Whamcloud - gitweb
LU-12130 test: pool inheritance for mdt component
[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-9054  312
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 #                                  5              12     8   12  15   (min)"
67 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
68
69 if [ "$mds1_FSTYPE" = "zfs" ]; then
70         #                                               13    (min)"
71         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
72 fi
73
74 if [ "$ost1_FSTYPE" = "zfs" ]; then
75         always_except LU-1941 130b 130c 130d 130e 130f 130g
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 test_24t() {
1151         test_mkdir $DIR/R16a
1152         test_mkdir $DIR/R16a/b
1153         test_mkdir $DIR/R16a/b/c
1154         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1155         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1156         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1157 }
1158 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1159
1160 test_24u() { # bug12192
1161         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1162         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1163 }
1164 run_test 24u "create stripe file"
1165
1166 simple_cleanup_common() {
1167         local createmany=$1
1168         local rc=0
1169
1170         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1171
1172         local start=$SECONDS
1173
1174         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1175         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1176         rc=$?
1177         wait_delete_completed
1178         echo "cleanup time $((SECONDS - start))"
1179         return $rc
1180 }
1181
1182 max_pages_per_rpc() {
1183         local mdtname="$(printf "MDT%04x" ${1:-0})"
1184         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1185 }
1186
1187 test_24v() {
1188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1189
1190         local nrfiles=${COUNT:-100000}
1191         local fname="$DIR/$tdir/$tfile"
1192
1193         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1194         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1195
1196         test_mkdir "$(dirname $fname)"
1197         # assume MDT0000 has the fewest inodes
1198         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1199         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1200         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1201
1202         stack_trap "simple_cleanup_common $nrfiles"
1203
1204         createmany -m "$fname" $nrfiles
1205
1206         cancel_lru_locks mdc
1207         lctl set_param mdc.*.stats clear
1208
1209         # was previously test_24D: LU-6101
1210         # readdir() returns correct number of entries after cursor reload
1211         local num_ls=$(ls $DIR/$tdir | wc -l)
1212         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1213         local num_all=$(ls -a $DIR/$tdir | wc -l)
1214         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1215                 [ $num_all -ne $((nrfiles + 2)) ]; then
1216                         error "Expected $nrfiles files, got $num_ls " \
1217                                 "($num_uniq unique $num_all .&..)"
1218         fi
1219         # LU-5 large readdir
1220         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1221         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1222         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1223         # take into account of overhead in lu_dirpage header and end mark in
1224         # each page, plus one in rpc_num calculation.
1225         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1226         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1227         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1228         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1229         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1230         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1231         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1232         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1233                 error "large readdir doesn't take effect: " \
1234                       "$mds_readpage should be about $rpc_max"
1235 }
1236 run_test 24v "list large directory (test hash collision, b=17560)"
1237
1238 test_24w() { # bug21506
1239         SZ1=234852
1240         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1241         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1242         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1243         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1244         [[ "$SZ1" -eq "$SZ2" ]] ||
1245                 error "Error reading at the end of the file $tfile"
1246 }
1247 run_test 24w "Reading a file larger than 4Gb"
1248
1249 test_24x() {
1250         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1252         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1253                 skip "Need MDS version at least 2.7.56"
1254
1255         local MDTIDX=1
1256         local remote_dir=$DIR/$tdir/remote_dir
1257
1258         test_mkdir $DIR/$tdir
1259         $LFS mkdir -i $MDTIDX $remote_dir ||
1260                 error "create remote directory failed"
1261
1262         test_mkdir $DIR/$tdir/src_dir
1263         touch $DIR/$tdir/src_file
1264         test_mkdir $remote_dir/tgt_dir
1265         touch $remote_dir/tgt_file
1266
1267         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1268                 error "rename dir cross MDT failed!"
1269
1270         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1271                 error "rename file cross MDT failed!"
1272
1273         touch $DIR/$tdir/ln_file
1274         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1275                 error "ln file cross MDT failed"
1276
1277         rm -rf $DIR/$tdir || error "Can not delete directories"
1278 }
1279 run_test 24x "cross MDT rename/link"
1280
1281 test_24y() {
1282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1284
1285         local remote_dir=$DIR/$tdir/remote_dir
1286         local mdtidx=1
1287
1288         test_mkdir $DIR/$tdir
1289         $LFS mkdir -i $mdtidx $remote_dir ||
1290                 error "create remote directory failed"
1291
1292         test_mkdir $remote_dir/src_dir
1293         touch $remote_dir/src_file
1294         test_mkdir $remote_dir/tgt_dir
1295         touch $remote_dir/tgt_file
1296
1297         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1298                 error "rename subdir in the same remote dir failed!"
1299
1300         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1301                 error "rename files in the same remote dir failed!"
1302
1303         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1304                 error "link files in the same remote dir failed!"
1305
1306         rm -rf $DIR/$tdir || error "Can not delete directories"
1307 }
1308 run_test 24y "rename/link on the same dir should succeed"
1309
1310 test_24z() {
1311         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1312         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1313                 skip "Need MDS version at least 2.12.51"
1314
1315         local index
1316
1317         for index in 0 1; do
1318                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1319                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1320         done
1321
1322         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1323
1324         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1325         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1326
1327         local mdts=$(comma_list $(mdts_nodes))
1328
1329         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1330         stack_trap "do_nodes $mdts $LCTL \
1331                 set_param mdt.*.enable_remote_rename=1" EXIT
1332
1333         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1334
1335         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1336         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1337 }
1338 run_test 24z "cross-MDT rename is done as cp"
1339
1340 test_24A() { # LU-3182
1341         local NFILES=5000
1342
1343         test_mkdir $DIR/$tdir
1344         stack_trap "simple_cleanup_common $NFILES"
1345         createmany -m $DIR/$tdir/$tfile $NFILES
1346         local t=$(ls $DIR/$tdir | wc -l)
1347         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1348         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1349
1350         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1351                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1352 }
1353 run_test 24A "readdir() returns correct number of entries."
1354
1355 test_24B() { # LU-4805
1356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1357
1358         local count
1359
1360         test_mkdir $DIR/$tdir
1361         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1362                 error "create striped dir failed"
1363
1364         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1365         [ $count -eq 2 ] || error "Expected 2, got $count"
1366
1367         touch $DIR/$tdir/striped_dir/a
1368
1369         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1370         [ $count -eq 3 ] || error "Expected 3, got $count"
1371
1372         touch $DIR/$tdir/striped_dir/.f
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 4 ] || error "Expected 4, got $count"
1376
1377         rm -rf $DIR/$tdir || error "Can not delete directories"
1378 }
1379 run_test 24B "readdir for striped dir return correct number of entries"
1380
1381 test_24C() {
1382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1383
1384         mkdir $DIR/$tdir
1385         mkdir $DIR/$tdir/d0
1386         mkdir $DIR/$tdir/d1
1387
1388         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1389                 error "create striped dir failed"
1390
1391         cd $DIR/$tdir/d0/striped_dir
1392
1393         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1394         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1395         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d0_ino" = "$parent_ino" ] ||
1398                 error ".. wrong, expect $d0_ino, get $parent_ino"
1399
1400         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1401                 error "mv striped dir failed"
1402
1403         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1404
1405         [ "$d1_ino" = "$parent_ino" ] ||
1406                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1407 }
1408 run_test 24C "check .. in striped dir"
1409
1410 test_24E() {
1411         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1413
1414         mkdir -p $DIR/$tdir
1415         mkdir $DIR/$tdir/src_dir
1416         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1417                 error "create remote source failed"
1418
1419         touch $DIR/$tdir/src_dir/src_child/a
1420
1421         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1422                 error "create remote target dir failed"
1423
1424         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1425                 error "create remote target child failed"
1426
1427         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1428                 error "rename dir cross MDT failed!"
1429
1430         find $DIR/$tdir
1431
1432         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1433                 error "src_child still exists after rename"
1434
1435         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1436                 error "missing file(a) after rename"
1437
1438         rm -rf $DIR/$tdir || error "Can not delete directories"
1439 }
1440 run_test 24E "cross MDT rename/link"
1441
1442 test_24F () {
1443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1444
1445         local repeats=1000
1446         [ "$SLOW" = "no" ] && repeats=100
1447
1448         mkdir -p $DIR/$tdir
1449
1450         echo "$repeats repeats"
1451         for ((i = 0; i < repeats; i++)); do
1452                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1453                 touch $DIR/$tdir/test/a || error "touch fails"
1454                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1455                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1456         done
1457
1458         true
1459 }
1460 run_test 24F "hash order vs readdir (LU-11330)"
1461
1462 test_24G () {
1463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1464
1465         local ino1
1466         local ino2
1467
1468         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1469         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1470         touch $DIR/$tdir-0/f1 || error "touch f1"
1471         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1472         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1473         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1474         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1475         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1476 }
1477 run_test 24G "migrate symlink in rename"
1478
1479 test_24H() {
1480         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1481         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1482                 skip "MDT1 should be on another node"
1483
1484         test_mkdir -i 1 -c 1 $DIR/$tdir
1485 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1486         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1487         touch $DIR/$tdir/$tfile || error "touch failed"
1488 }
1489 run_test 24H "repeat FLD_QUERY rpc"
1490
1491 test_25a() {
1492         echo '== symlink sanity ============================================='
1493
1494         test_mkdir $DIR/d25
1495         ln -s d25 $DIR/s25
1496         touch $DIR/s25/foo ||
1497                 error "File creation in symlinked directory failed"
1498 }
1499 run_test 25a "create file in symlinked directory ==============="
1500
1501 test_25b() {
1502         [ ! -d $DIR/d25 ] && test_25a
1503         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1504 }
1505 run_test 25b "lookup file in symlinked directory ==============="
1506
1507 test_26a() {
1508         test_mkdir $DIR/d26
1509         test_mkdir $DIR/d26/d26-2
1510         ln -s d26/d26-2 $DIR/s26
1511         touch $DIR/s26/foo || error "File creation failed"
1512 }
1513 run_test 26a "multiple component symlink ======================="
1514
1515 test_26b() {
1516         test_mkdir -p $DIR/$tdir/d26-2
1517         ln -s $tdir/d26-2/foo $DIR/s26-2
1518         touch $DIR/s26-2 || error "File creation failed"
1519 }
1520 run_test 26b "multiple component symlink at end of lookup ======"
1521
1522 test_26c() {
1523         test_mkdir $DIR/d26.2
1524         touch $DIR/d26.2/foo
1525         ln -s d26.2 $DIR/s26.2-1
1526         ln -s s26.2-1 $DIR/s26.2-2
1527         ln -s s26.2-2 $DIR/s26.2-3
1528         chmod 0666 $DIR/s26.2-3/foo
1529 }
1530 run_test 26c "chain of symlinks"
1531
1532 # recursive symlinks (bug 439)
1533 test_26d() {
1534         ln -s d26-3/foo $DIR/d26-3
1535 }
1536 run_test 26d "create multiple component recursive symlink"
1537
1538 test_26e() {
1539         [ ! -h $DIR/d26-3 ] && test_26d
1540         rm $DIR/d26-3
1541 }
1542 run_test 26e "unlink multiple component recursive symlink"
1543
1544 # recursive symlinks (bug 7022)
1545 test_26f() {
1546         test_mkdir $DIR/$tdir
1547         test_mkdir $DIR/$tdir/$tfile
1548         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1549         test_mkdir -p lndir/bar1
1550         test_mkdir $DIR/$tdir/$tfile/$tfile
1551         cd $tfile                || error "cd $tfile failed"
1552         ln -s .. dotdot          || error "ln dotdot failed"
1553         ln -s dotdot/lndir lndir || error "ln lndir failed"
1554         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1555         output=`ls $tfile/$tfile/lndir/bar1`
1556         [ "$output" = bar1 ] && error "unexpected output"
1557         rm -r $tfile             || error "rm $tfile failed"
1558         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1559 }
1560 run_test 26f "rm -r of a directory which has recursive symlink"
1561
1562 test_27a() {
1563         test_mkdir $DIR/$tdir
1564         $LFS getstripe $DIR/$tdir
1565         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1566         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1567         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1568 }
1569 run_test 27a "one stripe file"
1570
1571 test_27b() {
1572         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1573
1574         test_mkdir $DIR/$tdir
1575         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1576         $LFS getstripe -c $DIR/$tdir/$tfile
1577         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1578                 error "two-stripe file doesn't have two stripes"
1579
1580         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1581 }
1582 run_test 27b "create and write to two stripe file"
1583
1584 # 27c family tests specific striping, setstripe -o
1585 test_27ca() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1587         test_mkdir -p $DIR/$tdir
1588         local osts="1"
1589
1590         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1591         $LFS getstripe -i $DIR/$tdir/$tfile
1592         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1593                 error "stripe not on specified OST"
1594
1595         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1596 }
1597 run_test 27ca "one stripe on specified OST"
1598
1599 test_27cb() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         test_mkdir -p $DIR/$tdir
1602         local osts="1,0"
1603         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1604         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1605         echo "$getstripe"
1606
1607         # Strip getstripe output to a space separated list of OSTs
1608         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1609                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1610         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1611                 error "stripes not on specified OSTs"
1612
1613         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1614 }
1615 run_test 27cb "two stripes on specified OSTs"
1616
1617 test_27cc() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1620                 skip "server does not support overstriping"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cc "two stripes on the same OST"
1637
1638 test_27cd() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642         test_mkdir -p $DIR/$tdir
1643         local osts="0,1,1,0"
1644         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1645         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1646         echo "$getstripe"
1647
1648         # Strip getstripe output to a space separated list of OSTs
1649         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1650                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1651         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1652                 error "stripes not on specified OSTs"
1653
1654         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1655 }
1656 run_test 27cd "four stripes on two OSTs"
1657
1658 test_27ce() {
1659         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1660                 skip_env "too many osts, skipping"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         # We do one more stripe than we have OSTs
1664         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1665                 skip_env "ea_inode feature disabled"
1666
1667         test_mkdir -p $DIR/$tdir
1668         local osts=""
1669         for i in $(seq 0 $OSTCOUNT);
1670         do
1671                 osts=$osts"0"
1672                 if [ $i -ne $OSTCOUNT ]; then
1673                         osts=$osts","
1674                 fi
1675         done
1676         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1677         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1678         echo "$getstripe"
1679
1680         # Strip getstripe output to a space separated list of OSTs
1681         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1682                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1683         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1684                 error "stripes not on specified OSTs"
1685
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1687 }
1688 run_test 27ce "more stripes than OSTs with -o"
1689
1690 test_27cf() {
1691         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1692         local pid=0
1693
1694         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1695         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1696         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1697         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1698                 error "failed to set $osp_proc=0"
1699
1700         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1701         pid=$!
1702         sleep 1
1703         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1704         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1705                 error "failed to set $osp_proc=1"
1706         wait $pid
1707         [[ $pid -ne 0 ]] ||
1708                 error "should return error due to $osp_proc=0"
1709 }
1710 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1711
1712 test_27d() {
1713         test_mkdir $DIR/$tdir
1714         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1715                 error "setstripe failed"
1716         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1718 }
1719 run_test 27d "create file with default settings"
1720
1721 test_27e() {
1722         # LU-5839 adds check for existed layout before setting it
1723         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1724                 skip "Need MDS version at least 2.7.56"
1725
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1729         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1730 }
1731 run_test 27e "setstripe existing file (should return error)"
1732
1733 test_27f() {
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1736                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1737         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1738                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1739         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1740         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1741 }
1742 run_test 27f "setstripe with bad stripe size (should return error)"
1743
1744 test_27g() {
1745         test_mkdir $DIR/$tdir
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1748                 error "$DIR/$tdir/$tfile has object"
1749 }
1750 run_test 27g "$LFS getstripe with no objects"
1751
1752 test_27ga() {
1753         test_mkdir $DIR/$tdir
1754         touch $DIR/$tdir/$tfile || error "touch failed"
1755         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1756         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1757         local rc=$?
1758         (( rc == 2 )) || error "getstripe did not return ENOENT"
1759 }
1760 run_test 27ga "$LFS getstripe with missing file (should return error)"
1761
1762 test_27i() {
1763         test_mkdir $DIR/$tdir
1764         touch $DIR/$tdir/$tfile || error "touch failed"
1765         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1766                 error "missing objects"
1767 }
1768 run_test 27i "$LFS getstripe with some objects"
1769
1770 test_27j() {
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1773                 error "setstripe failed" || true
1774 }
1775 run_test 27j "setstripe with bad stripe offset (should return error)"
1776
1777 test_27k() { # bug 2844
1778         test_mkdir $DIR/$tdir
1779         local file=$DIR/$tdir/$tfile
1780         local ll_max_blksize=$((4 * 1024 * 1024))
1781         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1782         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1783         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1784         dd if=/dev/zero of=$file bs=4k count=1
1785         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1786         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1787 }
1788 run_test 27k "limit i_blksize for broken user apps"
1789
1790 test_27l() {
1791         mcreate $DIR/$tfile || error "creating file"
1792         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1793                 error "setstripe should have failed" || true
1794 }
1795 run_test 27l "check setstripe permissions (should return error)"
1796
1797 test_27m() {
1798         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1799
1800         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1801                 skip_env "multiple clients -- skipping"
1802
1803         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1804                    head -n1)
1805         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1806                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1807         fi
1808         stack_trap simple_cleanup_common
1809         test_mkdir $DIR/$tdir
1810         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1811         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1812                 error "dd should fill OST0"
1813         i=2
1814         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1815                 i=$((i + 1))
1816                 [ $i -gt 256 ] && break
1817         done
1818         i=$((i + 1))
1819         touch $DIR/$tdir/$tfile.$i
1820         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1821             awk '{print $1}'| grep -w "0") ] &&
1822                 error "OST0 was full but new created file still use it"
1823         i=$((i + 1))
1824         touch $DIR/$tdir/$tfile.$i
1825         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1826             awk '{print $1}'| grep -w "0") ] &&
1827                 error "OST0 was full but new created file still use it" || true
1828 }
1829 run_test 27m "create file while OST0 was full"
1830
1831 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1832 # if the OST isn't full anymore.
1833 reset_enospc() {
1834         local ostidx=${1:-""}
1835         local delay
1836         local ready
1837         local get_prealloc
1838
1839         local list=$(comma_list $(osts_nodes))
1840         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1841
1842         do_nodes $list lctl set_param fail_loc=0
1843         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1844         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1845                 awk '{print $1 * 2;exit;}')
1846         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1847                         grep -v \"^0$\""
1848         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1849 }
1850
1851 test_27n() {
1852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1854         remote_mds_nodsh && skip "remote MDS with nodsh"
1855         remote_ost_nodsh && skip "remote OST with nodsh"
1856
1857         reset_enospc
1858         rm -f $DIR/$tdir/$tfile
1859         exhaust_precreations 0 0x80000215
1860         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1861         touch $DIR/$tdir/$tfile || error "touch failed"
1862         $LFS getstripe $DIR/$tdir/$tfile
1863         reset_enospc
1864 }
1865 run_test 27n "create file with some full OSTs"
1866
1867 test_27o() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875         exhaust_all_precreations 0x215
1876
1877         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1878
1879         reset_enospc
1880         rm -rf $DIR/$tdir/*
1881 }
1882 run_test 27o "create file with all full OSTs (should error)"
1883
1884 function create_and_checktime() {
1885         local fname=$1
1886         local loops=$2
1887         local i
1888
1889         for ((i=0; i < $loops; i++)); do
1890                 local start=$SECONDS
1891                 multiop $fname-$i Oc
1892                 ((SECONDS-start < TIMEOUT)) ||
1893                         error "creation took " $((SECONDS-$start)) && return 1
1894         done
1895 }
1896
1897 test_27oo() {
1898         local mdts=$(comma_list $(mdts_nodes))
1899
1900         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1901                 skip "Need MDS version at least 2.13.57"
1902
1903         local f0=$DIR/${tfile}-0
1904         local f1=$DIR/${tfile}-1
1905
1906         wait_delete_completed
1907
1908         # refill precreated objects
1909         $LFS setstripe -i0 -c1 $f0
1910
1911         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1912         # force QoS allocation policy
1913         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1914         stack_trap "do_nodes $mdts $LCTL set_param \
1915                 lov.*.qos_threshold_rr=$saved" EXIT
1916         sleep_maxage
1917
1918         # one OST is unavailable, but still have few objects preallocated
1919         stop ost1
1920         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1921                 rm -rf $f1 $DIR/$tdir*" EXIT
1922
1923         for ((i=0; i < 7; i++)); do
1924                 mkdir $DIR/$tdir$i || error "can't create dir"
1925                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1926                         error "can't set striping"
1927         done
1928         for ((i=0; i < 7; i++)); do
1929                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1930         done
1931         wait
1932 }
1933 run_test 27oo "don't let few threads to reserve too many objects"
1934
1935 test_27p() {
1936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1938         remote_mds_nodsh && skip "remote MDS with nodsh"
1939         remote_ost_nodsh && skip "remote OST with nodsh"
1940
1941         reset_enospc
1942         rm -f $DIR/$tdir/$tfile
1943         test_mkdir $DIR/$tdir
1944
1945         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1946         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_precreations 0 0x80000215
1950         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1951         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1952         $LFS getstripe $DIR/$tdir/$tfile
1953
1954         reset_enospc
1955 }
1956 run_test 27p "append to a truncated file with some full OSTs"
1957
1958 test_27q() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966
1967         mkdir_on_mdt0 $DIR/$tdir
1968         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1969         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1970                 error "truncate $DIR/$tdir/$tfile failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_all_precreations 0x215
1974
1975         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1976         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1977
1978         reset_enospc
1979 }
1980 run_test 27q "append to truncated file with all OSTs full (should error)"
1981
1982 test_27r() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990         exhaust_precreations 0 0x80000215
1991
1992         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1993
1994         reset_enospc
1995 }
1996 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1997
1998 test_27s() { # bug 10725
1999         test_mkdir $DIR/$tdir
2000         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2001         local stripe_count=0
2002         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2003         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2004                 error "stripe width >= 2^32 succeeded" || true
2005
2006 }
2007 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2008
2009 test_27t() { # bug 10864
2010         WDIR=$(pwd)
2011         WLFS=$(which lfs)
2012         cd $DIR
2013         touch $tfile
2014         $WLFS getstripe $tfile
2015         cd $WDIR
2016 }
2017 run_test 27t "check that utils parse path correctly"
2018
2019 test_27u() { # bug 4900
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         remote_mds_nodsh && skip "remote MDS with nodsh"
2022
2023         local index
2024         local list=$(comma_list $(mdts_nodes))
2025
2026 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2027         do_nodes $list $LCTL set_param fail_loc=0x139
2028         test_mkdir -p $DIR/$tdir
2029         stack_trap "simple_cleanup_common 1000"
2030         createmany -o $DIR/$tdir/$tfile 1000
2031         do_nodes $list $LCTL set_param fail_loc=0
2032
2033         TLOG=$TMP/$tfile.getstripe
2034         $LFS getstripe $DIR/$tdir > $TLOG
2035         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2036         [[ $OBJS -gt 0 ]] &&
2037                 error "$OBJS objects created on OST-0. See $TLOG" ||
2038                 rm -f $TLOG
2039 }
2040 run_test 27u "skip object creation on OSC w/o objects"
2041
2042 test_27v() { # bug 4900
2043         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046         remote_ost_nodsh && skip "remote OST with nodsh"
2047
2048         exhaust_all_precreations 0x215
2049         reset_enospc
2050
2051         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2052
2053         touch $DIR/$tdir/$tfile
2054         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2055         # all except ost1
2056         for (( i=1; i < OSTCOUNT; i++ )); do
2057                 do_facet ost$i lctl set_param fail_loc=0x705
2058         done
2059         local START=`date +%s`
2060         createmany -o $DIR/$tdir/$tfile 32
2061
2062         local FINISH=`date +%s`
2063         local TIMEOUT=`lctl get_param -n timeout`
2064         local PROCESS=$((FINISH - START))
2065         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2066                error "$FINISH - $START >= $TIMEOUT / 2"
2067         sleep $((TIMEOUT / 2 - PROCESS))
2068         reset_enospc
2069 }
2070 run_test 27v "skip object creation on slow OST"
2071
2072 test_27w() { # bug 10997
2073         test_mkdir $DIR/$tdir
2074         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2075         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2076                 error "stripe size $size != 65536" || true
2077         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2078                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2079 }
2080 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2081
2082 test_27wa() {
2083         [[ $OSTCOUNT -lt 2 ]] &&
2084                 skip_env "skipping multiple stripe count/offset test"
2085
2086         test_mkdir $DIR/$tdir
2087         for i in $(seq 1 $OSTCOUNT); do
2088                 offset=$((i - 1))
2089                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2090                         error "setstripe -c $i -i $offset failed"
2091                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2092                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2093                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2094                 [ $index -ne $offset ] &&
2095                         error "stripe offset $index != $offset" || true
2096         done
2097 }
2098 run_test 27wa "check $LFS setstripe -c -i options"
2099
2100 test_27x() {
2101         remote_ost_nodsh && skip "remote OST with nodsh"
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104
2105         OFFSET=$(($OSTCOUNT - 1))
2106         OSTIDX=0
2107         local OST=$(ostname_from_index $OSTIDX)
2108
2109         test_mkdir $DIR/$tdir
2110         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2111         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2112         sleep_maxage
2113         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2114         for i in $(seq 0 $OFFSET); do
2115                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2116                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2117                 error "OST0 was degraded but new created file still use it"
2118         done
2119         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2120 }
2121 run_test 27x "create files while OST0 is degraded"
2122
2123 test_27y() {
2124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2125         remote_mds_nodsh && skip "remote MDS with nodsh"
2126         remote_ost_nodsh && skip "remote OST with nodsh"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2130         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2131                 osp.$mdtosc.prealloc_last_id)
2132         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2133                 osp.$mdtosc.prealloc_next_id)
2134         local fcount=$((last_id - next_id))
2135         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2136         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2137
2138         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2139                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2140         local OST_DEACTIVE_IDX=-1
2141         local OSC
2142         local OSTIDX
2143         local OST
2144
2145         for OSC in $MDS_OSCS; do
2146                 OST=$(osc_to_ost $OSC)
2147                 OSTIDX=$(index_from_ostuuid $OST)
2148                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2149                         OST_DEACTIVE_IDX=$OSTIDX
2150                 fi
2151                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2152                         echo $OSC "is Deactivated:"
2153                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2154                 fi
2155         done
2156
2157         OSTIDX=$(index_from_ostuuid $OST)
2158         test_mkdir $DIR/$tdir
2159         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2160
2161         for OSC in $MDS_OSCS; do
2162                 OST=$(osc_to_ost $OSC)
2163                 OSTIDX=$(index_from_ostuuid $OST)
2164                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2165                         echo $OST "is degraded:"
2166                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2167                                                 obdfilter.$OST.degraded=1
2168                 fi
2169         done
2170
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $fcount
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2178                         echo $OST "is recovered from degraded:"
2179                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2180                                                 obdfilter.$OST.degraded=0
2181                 else
2182                         do_facet $SINGLEMDS lctl --device %$OSC activate
2183                 fi
2184         done
2185
2186         # all osp devices get activated, hence -1 stripe count restored
2187         local stripe_count=0
2188
2189         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2190         # devices get activated.
2191         sleep_maxage
2192         $LFS setstripe -c -1 $DIR/$tfile
2193         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2194         rm -f $DIR/$tfile
2195         [ $stripe_count -ne $OSTCOUNT ] &&
2196                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2197         return 0
2198 }
2199 run_test 27y "create files while OST0 is degraded and the rest inactive"
2200
2201 check_seq_oid()
2202 {
2203         log "check file $1"
2204
2205         lmm_count=$($LFS getstripe -c $1)
2206         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2207         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2208
2209         local old_ifs="$IFS"
2210         IFS=$'[:]'
2211         fid=($($LFS path2fid $1))
2212         IFS="$old_ifs"
2213
2214         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2215         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2216
2217         # compare lmm_seq and lu_fid->f_seq
2218         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2219         # compare lmm_object_id and lu_fid->oid
2220         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2221
2222         # check the trusted.fid attribute of the OST objects of the file
2223         local have_obdidx=false
2224         local stripe_nr=0
2225         $LFS getstripe $1 | while read obdidx oid hex seq; do
2226                 # skip lines up to and including "obdidx"
2227                 [ -z "$obdidx" ] && break
2228                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2229                 $have_obdidx || continue
2230
2231                 local ost=$((obdidx + 1))
2232                 local dev=$(ostdevname $ost)
2233                 local oid_hex
2234
2235                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2236
2237                 seq=$(echo $seq | sed -e "s/^0x//g")
2238                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2239                         oid_hex=$(echo $oid)
2240                 else
2241                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2242                 fi
2243                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2244
2245                 local ff=""
2246                 #
2247                 # Don't unmount/remount the OSTs if we don't need to do that.
2248                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2249                 # update too, until that use mount/ll_decode_filter_fid/mount.
2250                 # Re-enable when debugfs will understand new filter_fid.
2251                 #
2252                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2253                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2254                                 $dev 2>/dev/null" | grep "parent=")
2255                 fi
2256                 if [ -z "$ff" ]; then
2257                         stop ost$ost
2258                         mount_fstype ost$ost
2259                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2260                                 $(facet_mntpt ost$ost)/$obj_file)
2261                         unmount_fstype ost$ost
2262                         start ost$ost $dev $OST_MOUNT_OPTS
2263                         clients_up
2264                 fi
2265
2266                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2267
2268                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2269
2270                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2271                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2272                 #
2273                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2274                 #       stripe_size=1048576 component_id=1 component_start=0 \
2275                 #       component_end=33554432
2276                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2277                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2278                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2279                 local ff_pstripe
2280                 if grep -q 'stripe=' <<<$ff; then
2281                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2282                 else
2283                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2284                         # into f_ver in this case.  See comment on ff_parent.
2285                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2286                 fi
2287
2288                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2289                 [ $ff_pseq = $lmm_seq ] ||
2290                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2291                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2292                 [ $ff_poid = $lmm_oid ] ||
2293                         error "FF parent OID $ff_poid != $lmm_oid"
2294                 (($ff_pstripe == $stripe_nr)) ||
2295                         error "FF stripe $ff_pstripe != $stripe_nr"
2296
2297                 stripe_nr=$((stripe_nr + 1))
2298                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2299                         continue
2300                 if grep -q 'stripe_count=' <<<$ff; then
2301                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2302                                             -e 's/ .*//' <<<$ff)
2303                         [ $lmm_count = $ff_scnt ] ||
2304                                 error "FF stripe count $lmm_count != $ff_scnt"
2305                 fi
2306         done
2307 }
2308
2309 test_27z() {
2310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2311         remote_ost_nodsh && skip "remote OST with nodsh"
2312
2313         test_mkdir $DIR/$tdir
2314         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2315                 { error "setstripe -c -1 failed"; return 1; }
2316         # We need to send a write to every object to get parent FID info set.
2317         # This _should_ also work for setattr, but does not currently.
2318         # touch $DIR/$tdir/$tfile-1 ||
2319         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2320                 { error "dd $tfile-1 failed"; return 2; }
2321         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2322                 { error "setstripe -c -1 failed"; return 3; }
2323         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2324                 { error "dd $tfile-2 failed"; return 4; }
2325
2326         # make sure write RPCs have been sent to OSTs
2327         sync; sleep 5; sync
2328
2329         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2330         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2331 }
2332 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2333
2334 test_27A() { # b=19102
2335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2336
2337         save_layout_restore_at_exit $MOUNT
2338         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2339         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2340                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2341         local default_size=$($LFS getstripe -S $MOUNT)
2342         local default_offset=$($LFS getstripe -i $MOUNT)
2343         local dsize=$(do_facet $SINGLEMDS \
2344                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2345         [ $default_size -eq $dsize ] ||
2346                 error "stripe size $default_size != $dsize"
2347         [ $default_offset -eq -1 ] ||
2348                 error "stripe offset $default_offset != -1"
2349 }
2350 run_test 27A "check filesystem-wide default LOV EA values"
2351
2352 test_27B() { # LU-2523
2353         test_mkdir $DIR/$tdir
2354         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2355         touch $DIR/$tdir/f0
2356         # open f1 with O_LOV_DELAY_CREATE
2357         # rename f0 onto f1
2358         # call setstripe ioctl on open file descriptor for f1
2359         # close
2360         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2361                 $DIR/$tdir/f0
2362
2363         rm -f $DIR/$tdir/f1
2364         # open f1 with O_LOV_DELAY_CREATE
2365         # unlink f1
2366         # call setstripe ioctl on open file descriptor for f1
2367         # close
2368         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2369
2370         # Allow multiop to fail in imitation of NFS's busted semantics.
2371         true
2372 }
2373 run_test 27B "call setstripe on open unlinked file/rename victim"
2374
2375 # 27C family tests full striping and overstriping
2376 test_27Ca() { #LU-2871
2377         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2378
2379         declare -a ost_idx
2380         local index
2381         local found
2382         local i
2383         local j
2384
2385         test_mkdir $DIR/$tdir
2386         cd $DIR/$tdir
2387         for i in $(seq 0 $((OSTCOUNT - 1))); do
2388                 # set stripe across all OSTs starting from OST$i
2389                 $LFS setstripe -i $i -c -1 $tfile$i
2390                 # get striping information
2391                 ost_idx=($($LFS getstripe $tfile$i |
2392                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2393                 echo "OST Index: ${ost_idx[*]}"
2394
2395                 # check the layout
2396                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2397                         error "${#ost_idx[@]} != $OSTCOUNT"
2398
2399                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2400                         found=0
2401                         for j in "${ost_idx[@]}"; do
2402                                 if [ $index -eq $j ]; then
2403                                         found=1
2404                                         break
2405                                 fi
2406                         done
2407                         [ $found = 1 ] ||
2408                                 error "Can not find $index in ${ost_idx[*]}"
2409                 done
2410         done
2411 }
2412 run_test 27Ca "check full striping across all OSTs"
2413
2414 test_27Cb() {
2415         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2416                 skip "server does not support overstriping"
2417         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2418                 skip_env "too many osts, skipping"
2419
2420         test_mkdir -p $DIR/$tdir
2421         local setcount=$(($OSTCOUNT * 2))
2422         [ $setcount -lt 160 ] || large_xattr_enabled ||
2423                 skip_env "ea_inode feature disabled"
2424
2425         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2426                 error "setstripe failed"
2427
2428         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2429         [ $count -eq $setcount ] ||
2430                 error "stripe count $count, should be $setcount"
2431
2432         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2433                 error "overstriped should be set in pattern"
2434
2435         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2436                 error "dd failed"
2437 }
2438 run_test 27Cb "more stripes than OSTs with -C"
2439
2440 test_27Cc() {
2441         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2442                 skip "server does not support overstriping"
2443         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2444
2445         test_mkdir -p $DIR/$tdir
2446         local setcount=$(($OSTCOUNT - 1))
2447
2448         [ $setcount -lt 160 ] || large_xattr_enabled ||
2449                 skip_env "ea_inode feature disabled"
2450
2451         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2452                 error "setstripe failed"
2453
2454         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2455         [ $count -eq $setcount ] ||
2456                 error "stripe count $count, should be $setcount"
2457
2458         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2459                 error "overstriped should not be set in pattern"
2460
2461         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2462                 error "dd failed"
2463 }
2464 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2465
2466 test_27Cd() {
2467         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2468                 skip "server does not support overstriping"
2469         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2470         large_xattr_enabled || skip_env "ea_inode feature disabled"
2471
2472         test_mkdir -p $DIR/$tdir
2473         local setcount=$LOV_MAX_STRIPE_COUNT
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2483                 error "overstriped should be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487
2488         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2489 }
2490 run_test 27Cd "test maximum stripe count"
2491
2492 test_27Ce() {
2493         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2494                 skip "server does not support overstriping"
2495         test_mkdir -p $DIR/$tdir
2496
2497         pool_add $TESTNAME || error "Pool creation failed"
2498         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2499
2500         local setcount=8
2501
2502         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2503                 error "setstripe failed"
2504
2505         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2506         [ $count -eq $setcount ] ||
2507                 error "stripe count $count, should be $setcount"
2508
2509         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2510                 error "overstriped should be set in pattern"
2511
2512         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2513                 error "dd failed"
2514
2515         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2516 }
2517 run_test 27Ce "test pool with overstriping"
2518
2519 test_27Cf() {
2520         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2521                 skip "server does not support overstriping"
2522         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2523                 skip_env "too many osts, skipping"
2524
2525         test_mkdir -p $DIR/$tdir
2526
2527         local setcount=$(($OSTCOUNT * 2))
2528         [ $setcount -lt 160 ] || large_xattr_enabled ||
2529                 skip_env "ea_inode feature disabled"
2530
2531         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2532                 error "setstripe failed"
2533
2534         echo 1 > $DIR/$tdir/$tfile
2535
2536         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2537         [ $count -eq $setcount ] ||
2538                 error "stripe count $count, should be $setcount"
2539
2540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2541                 error "overstriped should be set in pattern"
2542
2543         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2544                 error "dd failed"
2545
2546         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2547 }
2548 run_test 27Cf "test default inheritance with overstriping"
2549
2550 test_27D() {
2551         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2552         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2553         remote_mds_nodsh && skip "remote MDS with nodsh"
2554
2555         local POOL=${POOL:-testpool}
2556         local first_ost=0
2557         local last_ost=$(($OSTCOUNT - 1))
2558         local ost_step=1
2559         local ost_list=$(seq $first_ost $ost_step $last_ost)
2560         local ost_range="$first_ost $last_ost $ost_step"
2561
2562         test_mkdir $DIR/$tdir
2563         pool_add $POOL || error "pool_add failed"
2564         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2565
2566         local skip27D
2567         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2568                 skip27D+="-s 29"
2569         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2570                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2571                         skip27D+=" -s 30,31"
2572         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2573           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2574                 skip27D+=" -s 32,33"
2575         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2576                 skip27D+=" -s 34"
2577         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2578                 error "llapi_layout_test failed"
2579
2580         destroy_test_pools || error "destroy test pools failed"
2581 }
2582 run_test 27D "validate llapi_layout API"
2583
2584 # Verify that default_easize is increased from its initial value after
2585 # accessing a widely striped file.
2586 test_27E() {
2587         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2588         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2589                 skip "client does not have LU-3338 fix"
2590
2591         # 72 bytes is the minimum space required to store striping
2592         # information for a file striped across one OST:
2593         # (sizeof(struct lov_user_md_v3) +
2594         #  sizeof(struct lov_user_ost_data_v1))
2595         local min_easize=72
2596         $LCTL set_param -n llite.*.default_easize $min_easize ||
2597                 error "lctl set_param failed"
2598         local easize=$($LCTL get_param -n llite.*.default_easize)
2599
2600         [ $easize -eq $min_easize ] ||
2601                 error "failed to set default_easize"
2602
2603         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2604                 error "setstripe failed"
2605         # In order to ensure stat() call actually talks to MDS we need to
2606         # do something drastic to this file to shake off all lock, e.g.
2607         # rename it (kills lookup lock forcing cache cleaning)
2608         mv $DIR/$tfile $DIR/${tfile}-1
2609         ls -l $DIR/${tfile}-1
2610         rm $DIR/${tfile}-1
2611
2612         easize=$($LCTL get_param -n llite.*.default_easize)
2613
2614         [ $easize -gt $min_easize ] ||
2615                 error "default_easize not updated"
2616 }
2617 run_test 27E "check that default extended attribute size properly increases"
2618
2619 test_27F() { # LU-5346/LU-7975
2620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2621         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2622         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2623                 skip "Need MDS version at least 2.8.51"
2624         remote_ost_nodsh && skip "remote OST with nodsh"
2625
2626         test_mkdir $DIR/$tdir
2627         rm -f $DIR/$tdir/f0
2628         $LFS setstripe -c 2 $DIR/$tdir
2629
2630         # stop all OSTs to reproduce situation for LU-7975 ticket
2631         for num in $(seq $OSTCOUNT); do
2632                 stop ost$num
2633         done
2634
2635         # open/create f0 with O_LOV_DELAY_CREATE
2636         # truncate f0 to a non-0 size
2637         # close
2638         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2639
2640         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2641         # open/write it again to force delayed layout creation
2642         cat /etc/hosts > $DIR/$tdir/f0 &
2643         catpid=$!
2644
2645         # restart OSTs
2646         for num in $(seq $OSTCOUNT); do
2647                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2648                         error "ost$num failed to start"
2649         done
2650
2651         wait $catpid || error "cat failed"
2652
2653         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2654         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2655                 error "wrong stripecount"
2656
2657 }
2658 run_test 27F "Client resend delayed layout creation with non-zero size"
2659
2660 test_27G() { #LU-10629
2661         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2662                 skip "Need MDS version at least 2.11.51"
2663         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2664         remote_mds_nodsh && skip "remote MDS with nodsh"
2665         local POOL=${POOL:-testpool}
2666         local ostrange="0 0 1"
2667
2668         test_mkdir $DIR/$tdir
2669         touch $DIR/$tdir/$tfile.nopool
2670         pool_add $POOL || error "pool_add failed"
2671         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2672         $LFS setstripe -p $POOL $DIR/$tdir
2673
2674         local pool=$($LFS getstripe -p $DIR/$tdir)
2675
2676         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2677         touch $DIR/$tdir/$tfile.default
2678         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2679         $LFS find $DIR/$tdir -type f --pool $POOL
2680         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2681         [[ "$found" == "2" ]] ||
2682                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2683
2684         $LFS setstripe -d $DIR/$tdir
2685
2686         pool=$($LFS getstripe -p -d $DIR/$tdir)
2687
2688         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2689 }
2690 run_test 27G "Clear OST pool from stripe"
2691
2692 test_27H() {
2693         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2694                 skip "Need MDS version newer than 2.11.54"
2695         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2696         test_mkdir $DIR/$tdir
2697         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2698         touch $DIR/$tdir/$tfile
2699         $LFS getstripe -c $DIR/$tdir/$tfile
2700         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2701                 error "two-stripe file doesn't have two stripes"
2702
2703         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2704         $LFS getstripe -y $DIR/$tdir/$tfile
2705         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2706              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2707                 error "expected l_ost_idx: [02]$ not matched"
2708
2709         # make sure ost list has been cleared
2710         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2711         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2712                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2713         touch $DIR/$tdir/f3
2714         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2715 }
2716 run_test 27H "Set specific OSTs stripe"
2717
2718 test_27I() {
2719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2721         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2722                 skip "Need MDS version newer than 2.12.52"
2723         local pool=$TESTNAME
2724         local ostrange="1 1 1"
2725
2726         save_layout_restore_at_exit $MOUNT
2727         $LFS setstripe -c 2 -i 0 $MOUNT
2728         pool_add $pool || error "pool_add failed"
2729         pool_add_targets $pool $ostrange ||
2730                 error "pool_add_targets failed"
2731         test_mkdir $DIR/$tdir
2732         $LFS setstripe -p $pool $DIR/$tdir
2733         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2734         $LFS getstripe $DIR/$tdir/$tfile
2735 }
2736 run_test 27I "check that root dir striping does not break parent dir one"
2737
2738 test_27J() {
2739         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2740                 skip "Need MDS version newer than 2.12.51"
2741
2742         test_mkdir $DIR/$tdir
2743         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2744         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2745
2746         # create foreign file (raw way)
2747         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2748                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2749
2750         ! $LFS setstripe --foreign --flags foo \
2751                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2752                         error "creating $tfile with '--flags foo' should fail"
2753
2754         ! $LFS setstripe --foreign --flags 0xffffffff \
2755                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2756                         error "creating $tfile w/ 0xffffffff flags should fail"
2757
2758         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2759                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2760
2761         # verify foreign file (raw way)
2762         parse_foreign_file -f $DIR/$tdir/$tfile |
2763                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2764                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2765         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2766                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2767         parse_foreign_file -f $DIR/$tdir/$tfile |
2768                 grep "lov_foreign_size: 73" ||
2769                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2770         parse_foreign_file -f $DIR/$tdir/$tfile |
2771                 grep "lov_foreign_type: 1" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_flags: 0x0000DA08" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2776         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_value: 0x" |
2778                 sed -e 's/lov_foreign_value: 0x//')
2779         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2780         [[ $lov = ${lov2// /} ]] ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2782
2783         # create foreign file (lfs + API)
2784         $LFS setstripe --foreign=none --flags 0xda08 \
2785                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2786                 error "$DIR/$tdir/${tfile}2: create failed"
2787
2788         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2789                 grep "lfm_magic:.*0x0BD70BD0" ||
2790                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2791         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2792         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2793                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2795                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2796         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2797                 grep "lfm_flags:.*0x0000DA08" ||
2798                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2799         $LFS getstripe $DIR/$tdir/${tfile}2 |
2800                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2802
2803         # modify striping should fail
2804         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2805                 error "$DIR/$tdir/$tfile: setstripe should fail"
2806         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2807                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2808
2809         # R/W should fail
2810         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2811         cat $DIR/$tdir/${tfile}2 &&
2812                 error "$DIR/$tdir/${tfile}2: read should fail"
2813         cat /etc/passwd > $DIR/$tdir/$tfile &&
2814                 error "$DIR/$tdir/$tfile: write should fail"
2815         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2816                 error "$DIR/$tdir/${tfile}2: write should fail"
2817
2818         # chmod should work
2819         chmod 222 $DIR/$tdir/$tfile ||
2820                 error "$DIR/$tdir/$tfile: chmod failed"
2821         chmod 222 $DIR/$tdir/${tfile}2 ||
2822                 error "$DIR/$tdir/${tfile}2: chmod failed"
2823
2824         # chown should work
2825         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chown failed"
2827         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chown failed"
2829
2830         # rename should work
2831         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2832                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2833         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2834                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2835
2836         #remove foreign file
2837         rm $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2839         rm $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2841 }
2842 run_test 27J "basic ops on file with foreign LOV"
2843
2844 test_27K() {
2845         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2846                 skip "Need MDS version newer than 2.12.49"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign dir (raw way)
2853         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2854                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setdirstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2858                         error "creating $tdir with '--flags foo' should fail"
2859
2860         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2862                         error "creating $tdir w/ 0xffffffff flags should fail"
2863
2864         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2865                 error "create_foreign_dir FAILED"
2866
2867         # verify foreign dir (raw way)
2868         parse_foreign_dir -d $DIR/$tdir/$tdir |
2869                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2871         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2872                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2873         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2874                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2875         parse_foreign_dir -d $DIR/$tdir/$tdir |
2876                 grep "lmv_foreign_flags: 55813$" ||
2877                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2878         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2879                 grep "lmv_foreign_value: 0x" |
2880                 sed 's/lmv_foreign_value: 0x//')
2881         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2882                 sed 's/ //g')
2883         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2884
2885         # create foreign dir (lfs + API)
2886         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2887                 $DIR/$tdir/${tdir}2 ||
2888                 error "$DIR/$tdir/${tdir}2: create failed"
2889
2890         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2891
2892         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2893                 grep "lfm_magic:.*0x0CD50CD0" ||
2894                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2895         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2896         # - sizeof(lfm_type) - sizeof(lfm_flags)
2897         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2898                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2899         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2901         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2902                 grep "lfm_flags:.*0x0000DA05" ||
2903                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2904         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2905                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2907
2908         # file create in dir should fail
2909         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2910         touch $DIR/$tdir/${tdir}2/$tfile &&
2911                 error "$DIR/${tdir}2: file create should fail"
2912
2913         # chmod should work
2914         chmod 777 $DIR/$tdir/$tdir ||
2915                 error "$DIR/$tdir: chmod failed"
2916         chmod 777 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/${tdir}2: chmod failed"
2918
2919         # chown should work
2920         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chown failed"
2922         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chown failed"
2924
2925         # rename should work
2926         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2927                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2928         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2929                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2930
2931         #remove foreign dir
2932         rmdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2934         rmdir $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2936 }
2937 run_test 27K "basic ops on dir with foreign LMV"
2938
2939 test_27L() {
2940         remote_mds_nodsh && skip "remote MDS with nodsh"
2941
2942         local POOL=${POOL:-$TESTNAME}
2943
2944         pool_add $POOL || error "pool_add failed"
2945
2946         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2947                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2948                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2949 }
2950 run_test 27L "lfs pool_list gives correct pool name"
2951
2952 test_27M() {
2953         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2954                 skip "Need MDS version >= than 2.12.57"
2955         remote_mds_nodsh && skip "remote MDS with nodsh"
2956         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2957
2958         # Set default striping on directory
2959         local setcount=4
2960         local stripe_opt
2961         local mdts=$(comma_list $(mdts_nodes))
2962
2963         # if we run against a 2.12 server which lacks overstring support
2964         # then the connect_flag will not report overstriping, even if client
2965         # is 2.14+
2966         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2967                 stripe_opt="-C $setcount"
2968         elif (( $OSTCOUNT >= $setcount )); then
2969                 stripe_opt="-c $setcount"
2970         else
2971                 skip "server does not support overstriping"
2972         fi
2973
2974         test_mkdir $DIR/$tdir
2975
2976         # Validate existing append_* params and ensure restore
2977         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2978         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2980
2981         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2982         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2983         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2984
2985         $LFS setstripe $stripe_opt $DIR/$tdir
2986
2987         echo 1 > $DIR/$tdir/${tfile}.1
2988         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2989         [ $count -eq $setcount ] ||
2990                 error "(1) stripe count $count, should be $setcount"
2991
2992         local appendcount=$orig_count
2993         echo 1 >> $DIR/$tdir/${tfile}.2_append
2994         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2995         [ $count -eq $appendcount ] ||
2996                 error "(2)stripe count $count, should be $appendcount for append"
2997
2998         # Disable O_APPEND striping, verify it works
2999         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3000
3001         # Should now get the default striping, which is 4
3002         setcount=4
3003         echo 1 >> $DIR/$tdir/${tfile}.3_append
3004         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3005         [ $count -eq $setcount ] ||
3006                 error "(3) stripe count $count, should be $setcount"
3007
3008         # Try changing the stripe count for append files
3009         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3010
3011         # Append striping is now 2 (directory default is still 4)
3012         appendcount=2
3013         echo 1 >> $DIR/$tdir/${tfile}.4_append
3014         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3015         [ $count -eq $appendcount ] ||
3016                 error "(4) stripe count $count, should be $appendcount for append"
3017
3018         # Test append stripe count of -1
3019         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3020         appendcount=$OSTCOUNT
3021         echo 1 >> $DIR/$tdir/${tfile}.5
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3023         [ $count -eq $appendcount ] ||
3024                 error "(5) stripe count $count, should be $appendcount for append"
3025
3026         # Set append striping back to default of 1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3028
3029         # Try a new default striping, PFL + DOM
3030         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3031
3032         # Create normal DOM file, DOM returns stripe count == 0
3033         setcount=0
3034         touch $DIR/$tdir/${tfile}.6
3035         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3036         [ $count -eq $setcount ] ||
3037                 error "(6) stripe count $count, should be $setcount"
3038
3039         # Show
3040         appendcount=1
3041         echo 1 >> $DIR/$tdir/${tfile}.7_append
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3043         [ $count -eq $appendcount ] ||
3044                 error "(7) stripe count $count, should be $appendcount for append"
3045
3046         # Clean up DOM layout
3047         $LFS setstripe -d $DIR/$tdir
3048
3049         save_layout_restore_at_exit $MOUNT
3050         # Now test that append striping works when layout is from root
3051         $LFS setstripe -c 2 $MOUNT
3052         # Make a special directory for this
3053         mkdir $DIR/${tdir}/${tdir}.2
3054
3055         # Verify for normal file
3056         setcount=2
3057         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3058         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3059         [ $count -eq $setcount ] ||
3060                 error "(8) stripe count $count, should be $setcount"
3061
3062         appendcount=1
3063         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3064         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(9) stripe count $count, should be $appendcount for append"
3067
3068         # Now test O_APPEND striping with pools
3069         pool_add $TESTNAME || error "pool creation failed"
3070         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3071         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3072
3073         echo 1 >> $DIR/$tdir/${tfile}.10_append
3074
3075         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3076         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3077
3078         # Check that count is still correct
3079         appendcount=1
3080         echo 1 >> $DIR/$tdir/${tfile}.11_append
3081         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3082         [ $count -eq $appendcount ] ||
3083                 error "(11) stripe count $count, should be $appendcount for append"
3084
3085         # Disable O_APPEND stripe count, verify pool works separately
3086         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3087
3088         echo 1 >> $DIR/$tdir/${tfile}.12_append
3089
3090         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3091         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3092
3093         # Remove pool setting, verify it's not applied
3094         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3095
3096         echo 1 >> $DIR/$tdir/${tfile}.13_append
3097
3098         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3099         [ "$pool" = "" ] || error "(13) pool found: $pool"
3100 }
3101 run_test 27M "test O_APPEND striping"
3102
3103 test_27N() {
3104         combined_mgs_mds && skip "needs separate MGS/MDT"
3105
3106         pool_add $TESTNAME || error "pool_add failed"
3107         do_facet mgs "$LCTL pool_list $FSNAME" |
3108                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3109                 error "lctl pool_list on MGS failed"
3110 }
3111 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3112
3113 clean_foreign_symlink() {
3114         trap 0
3115         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3116         for i in $DIR/$tdir/* ; do
3117                 $LFS unlink_foreign $i || true
3118         done
3119 }
3120
3121 test_27O() {
3122         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3123                 skip "Need MDS version newer than 2.12.51"
3124
3125         test_mkdir $DIR/$tdir
3126         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3127         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3128
3129         trap clean_foreign_symlink EXIT
3130
3131         # enable foreign_symlink behaviour
3132         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3133
3134         # foreign symlink LOV format is a partial path by default
3135
3136         # create foreign file (lfs + API)
3137         $LFS setstripe --foreign=symlink --flags 0xda05 \
3138                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3139                 error "$DIR/$tdir/${tfile}: create failed"
3140
3141         $LFS getstripe -v $DIR/$tdir/${tfile} |
3142                 grep "lfm_magic:.*0x0BD70BD0" ||
3143                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3144         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3145                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3146         $LFS getstripe -v $DIR/$tdir/${tfile} |
3147                 grep "lfm_flags:.*0x0000DA05" ||
3148                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3149         $LFS getstripe $DIR/$tdir/${tfile} |
3150                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3152
3153         # modify striping should fail
3154         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3155                 error "$DIR/$tdir/$tfile: setstripe should fail"
3156
3157         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3158         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3159         cat /etc/passwd > $DIR/$tdir/$tfile &&
3160                 error "$DIR/$tdir/$tfile: write should fail"
3161
3162         # rename should succeed
3163         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3164                 error "$DIR/$tdir/$tfile: rename has failed"
3165
3166         #remove foreign_symlink file should fail
3167         rm $DIR/$tdir/${tfile}.new &&
3168                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3169
3170         #test fake symlink
3171         mkdir /tmp/${uuid1} ||
3172                 error "/tmp/${uuid1}: mkdir has failed"
3173         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3174                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3175         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3176         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3177                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3178         #read should succeed now
3179         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3180                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3181         #write should succeed now
3182         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3184         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3185                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3186         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3187                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3188
3189         #check that getstripe still works
3190         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3192
3193         # chmod should still succeed
3194         chmod 644 $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3196
3197         # chown should still succeed
3198         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3199                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3200
3201         # rename should still succeed
3202         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3203                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3204
3205         #remove foreign_symlink file should still fail
3206         rm $DIR/$tdir/${tfile} &&
3207                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3208
3209         #use special ioctl() to unlink foreign_symlink file
3210         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3211                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3212
3213 }
3214 run_test 27O "basic ops on foreign file of symlink type"
3215
3216 test_27P() {
3217         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3218                 skip "Need MDS version newer than 2.12.49"
3219
3220         test_mkdir $DIR/$tdir
3221         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3222         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3223
3224         trap clean_foreign_symlink EXIT
3225
3226         # enable foreign_symlink behaviour
3227         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3228
3229         # foreign symlink LMV format is a partial path by default
3230
3231         # create foreign dir (lfs + API)
3232         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3233                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3234                 error "$DIR/$tdir/${tdir}: create failed"
3235
3236         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3237
3238         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3239                 grep "lfm_magic:.*0x0CD50CD0" ||
3240                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3241         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3242                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3243         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3244                 grep "lfm_flags:.*0x0000DA05" ||
3245                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3246         $LFS getdirstripe $DIR/$tdir/${tdir} |
3247                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3249
3250         # file create in dir should fail
3251         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3252         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3253
3254         # rename should succeed
3255         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3256                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3257
3258         #remove foreign_symlink dir should fail
3259         rmdir $DIR/$tdir/${tdir}.new &&
3260                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3261
3262         #test fake symlink
3263         mkdir -p /tmp/${uuid1}/${uuid2} ||
3264                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3265         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3266                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3267         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3268         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3269                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3270         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3271                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3272
3273         #check that getstripe fails now that foreign_symlink enabled
3274         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3276
3277         # file create in dir should work now
3278         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3279                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3280         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3281                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3282         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3283                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3284
3285         # chmod should still succeed
3286         chmod 755 $DIR/$tdir/${tdir}.new ||
3287                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3288
3289         # chown should still succeed
3290         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3291                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3292
3293         # rename should still succeed
3294         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3295                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3296
3297         #remove foreign_symlink dir should still fail
3298         rmdir $DIR/$tdir/${tdir} &&
3299                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3300
3301         #use special ioctl() to unlink foreign_symlink file
3302         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3303                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3304
3305         #created file should still exist
3306         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3307                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3308         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3309                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3310 }
3311 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3312
3313 test_27Q() {
3314         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3315         stack_trap "rm -f $TMP/$tfile*"
3316
3317         test_mkdir $DIR/$tdir-1
3318         test_mkdir $DIR/$tdir-2
3319
3320         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3321         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3322
3323         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3324         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3325
3326         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3327         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3328
3329         # Create some bad symlinks and ensure that we don't loop
3330         # forever or something. These should return ELOOP (40) and
3331         # ENOENT (2) but I don't want to test for that because there's
3332         # always some weirdo architecture that needs to ruin
3333         # everything by defining these error numbers differently.
3334
3335         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3336         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3337
3338         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3339         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3340
3341         return 0
3342 }
3343 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3344
3345 test_27R() {
3346         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3347                 skip "need MDS 2.14.55 or later"
3348         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3349
3350         local testdir="$DIR/$tdir"
3351         test_mkdir -p $testdir
3352         stack_trap "rm -rf $testdir"
3353         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3354
3355         local f1="$testdir/f1"
3356         touch $f1 || error "failed to touch $f1"
3357         local count=$($LFS getstripe -c $f1)
3358         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3359
3360         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3361         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3362
3363         local maxcount=$(($OSTCOUNT - 1))
3364         local mdts=$(comma_list $(mdts_nodes))
3365         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3366         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3367
3368         local f2="$testdir/f2"
3369         touch $f2 || error "failed to touch $f2"
3370         local count=$($LFS getstripe -c $f2)
3371         (( $count == $maxcount )) || error "wrong stripe count"
3372 }
3373 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3374
3375 test_27T() {
3376         [ $(facet_host client) == $(facet_host ost1) ] &&
3377                 skip "need ost1 and client on different nodes"
3378
3379 #define OBD_FAIL_OSC_NO_GRANT            0x411
3380         $LCTL set_param fail_loc=0x20000411 fail_val=1
3381 #define OBD_FAIL_OST_ENOSPC              0x215
3382         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3383         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3384         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3385                 error "multiop failed"
3386 }
3387 run_test 27T "no eio on close on partial write due to enosp"
3388
3389 test_27U() {
3390         local dir=$DIR/$tdir
3391         local file=$dir/$tfile
3392         local append_pool=${TESTNAME}-append
3393         local normal_pool=${TESTNAME}-normal
3394         local pool
3395         local stripe_count
3396         local stripe_count2
3397         local mdts=$(comma_list $(mdts_nodes))
3398
3399         # FIMXE
3400         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3401         #       skip "Need MDS version at least 2.15.42"
3402
3403         # Validate existing append_* params and ensure restore
3404         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3405         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3406         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3407
3408         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3409         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3410         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3411
3412         pool_add $append_pool || error "pool creation failed"
3413         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3414
3415         pool_add $normal_pool || error "pool creation failed"
3416         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3417
3418         test_mkdir $dir
3419         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3420
3421         echo XXX >> $file.1
3422         $LFS getstripe $file.1
3423
3424         pool=$($LFS getstripe -p $file.1)
3425         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3426
3427         stripe_count2=$($LFS getstripe -c $file.1)
3428         ((stripe_count2 == stripe_count)) ||
3429                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3430
3431         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3432
3433         echo XXX >> $file.2
3434         $LFS getstripe $file.2
3435
3436         pool=$($LFS getstripe -p $file.2)
3437         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3438
3439         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3440
3441         echo XXX >> $file.3
3442         $LFS getstripe $file.3
3443
3444         stripe_count2=$($LFS getstripe -c $file.3)
3445         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3446 }
3447 run_test 27U "append pool and stripe count work with composite default layout"
3448
3449 # createtest also checks that device nodes are created and
3450 # then visible correctly (#2091)
3451 test_28() { # bug 2091
3452         test_mkdir $DIR/d28
3453         $CREATETEST $DIR/d28/ct || error "createtest failed"
3454 }
3455 run_test 28 "create/mknod/mkdir with bad file types ============"
3456
3457 test_29() {
3458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3459
3460         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3461                 disable_opencache
3462                 stack_trap "restore_opencache"
3463         }
3464
3465         sync; sleep 1; sync # flush out any dirty pages from previous tests
3466         cancel_lru_locks
3467         test_mkdir $DIR/d29
3468         touch $DIR/d29/foo
3469         log 'first d29'
3470         ls -l $DIR/d29
3471
3472         declare -i LOCKCOUNTORIG=0
3473         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3474                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3475         done
3476         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3477
3478         declare -i LOCKUNUSEDCOUNTORIG=0
3479         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3480                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3481         done
3482
3483         log 'second d29'
3484         ls -l $DIR/d29
3485         log 'done'
3486
3487         declare -i LOCKCOUNTCURRENT=0
3488         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3489                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3490         done
3491
3492         declare -i LOCKUNUSEDCOUNTCURRENT=0
3493         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3494                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3495         done
3496
3497         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3498                 $LCTL set_param -n ldlm.dump_namespaces ""
3499                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3500                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3501                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3502                 return 2
3503         fi
3504         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3505                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 3
3509         fi
3510 }
3511 run_test 29 "IT_GETATTR regression  ============================"
3512
3513 test_30a() { # was test_30
3514         cp $(which ls) $DIR || cp /bin/ls $DIR
3515         $DIR/ls / || error "Can't execute binary from lustre"
3516         rm $DIR/ls
3517 }
3518 run_test 30a "execute binary from Lustre (execve) =============="
3519
3520 test_30b() {
3521         cp `which ls` $DIR || cp /bin/ls $DIR
3522         chmod go+rx $DIR/ls
3523         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3524         rm $DIR/ls
3525 }
3526 run_test 30b "execute binary from Lustre as non-root ==========="
3527
3528 test_30c() { # b=22376
3529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3530
3531         cp $(which ls) $DIR || cp /bin/ls $DIR
3532         chmod a-rw $DIR/ls
3533         cancel_lru_locks mdc
3534         cancel_lru_locks osc
3535         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3536         rm -f $DIR/ls
3537 }
3538 run_test 30c "execute binary from Lustre without read perms ===="
3539
3540 test_30d() {
3541         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3542
3543         for i in {1..10}; do
3544                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3545                 local PID=$!
3546                 sleep 1
3547                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3548                 wait $PID || error "executing dd from Lustre failed"
3549                 rm -f $DIR/$tfile
3550         done
3551
3552         rm -f $DIR/dd
3553 }
3554 run_test 30d "execute binary from Lustre while clear locks"
3555
3556 test_31a() {
3557         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3558         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3559 }
3560 run_test 31a "open-unlink file =================================="
3561
3562 test_31b() {
3563         touch $DIR/f31 || error "touch $DIR/f31 failed"
3564         ln $DIR/f31 $DIR/f31b || error "ln failed"
3565         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3566         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3567 }
3568 run_test 31b "unlink file with multiple links while open ======="
3569
3570 test_31c() {
3571         touch $DIR/f31 || error "touch $DIR/f31 failed"
3572         ln $DIR/f31 $DIR/f31c || error "ln failed"
3573         multiop_bg_pause $DIR/f31 O_uc ||
3574                 error "multiop_bg_pause for $DIR/f31 failed"
3575         MULTIPID=$!
3576         $MULTIOP $DIR/f31c Ouc
3577         kill -USR1 $MULTIPID
3578         wait $MULTIPID
3579 }
3580 run_test 31c "open-unlink file with multiple links ============="
3581
3582 test_31d() {
3583         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3584         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3585 }
3586 run_test 31d "remove of open directory ========================="
3587
3588 test_31e() { # bug 2904
3589         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3590 }
3591 run_test 31e "remove of open non-empty directory ==============="
3592
3593 test_31f() { # bug 4554
3594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3595
3596         set -vx
3597         test_mkdir $DIR/d31f
3598         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3599         cp /etc/hosts $DIR/d31f
3600         ls -l $DIR/d31f
3601         $LFS getstripe $DIR/d31f/hosts
3602         multiop_bg_pause $DIR/d31f D_c || return 1
3603         MULTIPID=$!
3604
3605         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3606         test_mkdir $DIR/d31f
3607         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3608         cp /etc/hosts $DIR/d31f
3609         ls -l $DIR/d31f
3610         $LFS getstripe $DIR/d31f/hosts
3611         multiop_bg_pause $DIR/d31f D_c || return 1
3612         MULTIPID2=$!
3613
3614         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3615         wait $MULTIPID || error "first opendir $MULTIPID failed"
3616
3617         sleep 6
3618
3619         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3620         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3621         set +vx
3622 }
3623 run_test 31f "remove of open directory with open-unlink file ==="
3624
3625 test_31g() {
3626         echo "-- cross directory link --"
3627         test_mkdir -c1 $DIR/${tdir}ga
3628         test_mkdir -c1 $DIR/${tdir}gb
3629         touch $DIR/${tdir}ga/f
3630         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3631         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3632         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3633         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3634         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3635 }
3636 run_test 31g "cross directory link==============="
3637
3638 test_31h() {
3639         echo "-- cross directory link --"
3640         test_mkdir -c1 $DIR/${tdir}
3641         test_mkdir -c1 $DIR/${tdir}/dir
3642         touch $DIR/${tdir}/f
3643         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3644         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3645         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3646         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3647         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3648 }
3649 run_test 31h "cross directory link under child==============="
3650
3651 test_31i() {
3652         echo "-- cross directory link --"
3653         test_mkdir -c1 $DIR/$tdir
3654         test_mkdir -c1 $DIR/$tdir/dir
3655         touch $DIR/$tdir/dir/f
3656         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3657         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3658         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3659         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3660         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3661 }
3662 run_test 31i "cross directory link under parent==============="
3663
3664 test_31j() {
3665         test_mkdir -c1 -p $DIR/$tdir
3666         test_mkdir -c1 -p $DIR/$tdir/dir1
3667         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3668         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3669         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3671         return 0
3672 }
3673 run_test 31j "link for directory==============="
3674
3675 test_31k() {
3676         test_mkdir -c1 -p $DIR/$tdir
3677         touch $DIR/$tdir/s
3678         touch $DIR/$tdir/exist
3679         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3680         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3681         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3682         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3683         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3684         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3686         return 0
3687 }
3688 run_test 31k "link to file: the same, non-existing, dir==============="
3689
3690 test_31m() {
3691         mkdir $DIR/d31m
3692         touch $DIR/d31m/s
3693         mkdir $DIR/d31m2
3694         touch $DIR/d31m2/exist
3695         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3696         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3697         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3698         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3699         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3701         return 0
3702 }
3703 run_test 31m "link to file: the same, non-existing, dir==============="
3704
3705 test_31n() {
3706         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3707         nlink=$(stat --format=%h $DIR/$tfile)
3708         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3709         local fd=$(free_fd)
3710         local cmd="exec $fd<$DIR/$tfile"
3711         eval $cmd
3712         cmd="exec $fd<&-"
3713         trap "eval $cmd" EXIT
3714         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3715         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3716         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3717         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3718         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3719         eval $cmd
3720 }
3721 run_test 31n "check link count of unlinked file"
3722
3723 link_one() {
3724         local tempfile=$(mktemp $1_XXXXXX)
3725         mlink $tempfile $1 2> /dev/null &&
3726                 echo "$BASHPID: link $tempfile to $1 succeeded"
3727         munlink $tempfile
3728 }
3729
3730 test_31o() { # LU-2901
3731         test_mkdir $DIR/$tdir
3732         for LOOP in $(seq 100); do
3733                 rm -f $DIR/$tdir/$tfile*
3734                 for THREAD in $(seq 8); do
3735                         link_one $DIR/$tdir/$tfile.$LOOP &
3736                 done
3737                 wait
3738                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3739                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3740                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3741                         break || true
3742         done
3743 }
3744 run_test 31o "duplicate hard links with same filename"
3745
3746 test_31p() {
3747         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3748
3749         test_mkdir $DIR/$tdir
3750         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3751         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3752
3753         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3754                 error "open unlink test1 failed"
3755         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3756                 error "open unlink test2 failed"
3757
3758         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3759                 error "test1 still exists"
3760         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3761                 error "test2 still exists"
3762 }
3763 run_test 31p "remove of open striped directory"
3764
3765 test_31q() {
3766         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3767
3768         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3769         index=$($LFS getdirstripe -i $DIR/$tdir)
3770         [ $index -eq 3 ] || error "first stripe index $index != 3"
3771         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3772         [ $index -eq 1 ] || error "second stripe index $index != 1"
3773
3774         # when "-c <stripe_count>" is set, the number of MDTs specified after
3775         # "-i" should equal to the stripe count
3776         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3777 }
3778 run_test 31q "create striped directory on specific MDTs"
3779
3780 #LU-14949
3781 test_31r() {
3782         touch $DIR/$tfile.target
3783         touch $DIR/$tfile.source
3784
3785         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3786         $LCTL set_param fail_loc=0x1419 fail_val=3
3787         cat $DIR/$tfile.target &
3788         CATPID=$!
3789
3790         # Guarantee open is waiting before we get here
3791         sleep 1
3792         mv $DIR/$tfile.source $DIR/$tfile.target
3793
3794         wait $CATPID
3795         RC=$?
3796         if [[ $RC -ne 0 ]]; then
3797                 error "open with cat failed, rc=$RC"
3798         fi
3799 }
3800 run_test 31r "open-rename(replace) race"
3801
3802 cleanup_test32_mount() {
3803         local rc=0
3804         trap 0
3805         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3806         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3807         losetup -d $loopdev || true
3808         rm -rf $DIR/$tdir
3809         return $rc
3810 }
3811
3812 test_32a() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         echo "== more mountpoints and symlinks ================="
3816         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3817         trap cleanup_test32_mount EXIT
3818         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3819         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3820                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3821         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3822                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3823         cleanup_test32_mount
3824 }
3825 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3826
3827 test_32b() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3836                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3837         cleanup_test32_mount
3838 }
3839 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3840
3841 test_32c() {
3842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3843
3844         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3845         trap cleanup_test32_mount EXIT
3846         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3847         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3848                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3849         test_mkdir -p $DIR/$tdir/d2/test_dir
3850         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3851                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3852         cleanup_test32_mount
3853 }
3854 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3855
3856 test_32d() {
3857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3858
3859         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3860         trap cleanup_test32_mount EXIT
3861         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3862         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3863                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3864         test_mkdir -p $DIR/$tdir/d2/test_dir
3865         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3866                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3867         cleanup_test32_mount
3868 }
3869 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3870
3871 test_32e() {
3872         rm -fr $DIR/$tdir
3873         test_mkdir -p $DIR/$tdir/tmp
3874         local tmp_dir=$DIR/$tdir/tmp
3875         ln -s $DIR/$tdir $tmp_dir/symlink11
3876         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3877         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3878         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3879 }
3880 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3881
3882 test_32f() {
3883         rm -fr $DIR/$tdir
3884         test_mkdir -p $DIR/$tdir/tmp
3885         local tmp_dir=$DIR/$tdir/tmp
3886         ln -s $DIR/$tdir $tmp_dir/symlink11
3887         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3888         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3889         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3890 }
3891 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3892
3893 test_32g() {
3894         local tmp_dir=$DIR/$tdir/tmp
3895         test_mkdir -p $tmp_dir
3896         test_mkdir $DIR/${tdir}2
3897         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3898         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3899         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3900         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3901         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3902         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3903 }
3904 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3905
3906 test_32h() {
3907         rm -fr $DIR/$tdir $DIR/${tdir}2
3908         tmp_dir=$DIR/$tdir/tmp
3909         test_mkdir -p $tmp_dir
3910         test_mkdir $DIR/${tdir}2
3911         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3912         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3913         ls $tmp_dir/symlink12 || error "listing symlink12"
3914         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3915 }
3916 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3917
3918 test_32i() {
3919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3920
3921         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3922         trap cleanup_test32_mount EXIT
3923         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3924         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3925                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3926         touch $DIR/$tdir/test_file
3927         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3928                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3929         cleanup_test32_mount
3930 }
3931 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3932
3933 test_32j() {
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3937         trap cleanup_test32_mount EXIT
3938         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3941         touch $DIR/$tdir/test_file
3942         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3943                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3944         cleanup_test32_mount
3945 }
3946 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3947
3948 test_32k() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         rm -fr $DIR/$tdir
3952         trap cleanup_test32_mount EXIT
3953         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3954         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3955                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3956         test_mkdir -p $DIR/$tdir/d2
3957         touch $DIR/$tdir/d2/test_file || error "touch failed"
3958         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3959                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3960         cleanup_test32_mount
3961 }
3962 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3963
3964 test_32l() {
3965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3966
3967         rm -fr $DIR/$tdir
3968         trap cleanup_test32_mount EXIT
3969         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3970         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3971                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3972         test_mkdir -p $DIR/$tdir/d2
3973         touch $DIR/$tdir/d2/test_file || error "touch failed"
3974         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3975                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3976         cleanup_test32_mount
3977 }
3978 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3979
3980 test_32m() {
3981         rm -fr $DIR/d32m
3982         test_mkdir -p $DIR/d32m/tmp
3983         TMP_DIR=$DIR/d32m/tmp
3984         ln -s $DIR $TMP_DIR/symlink11
3985         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3986         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3987                 error "symlink11 not a link"
3988         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3989                 error "symlink01 not a link"
3990 }
3991 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3992
3993 test_32n() {
3994         rm -fr $DIR/d32n
3995         test_mkdir -p $DIR/d32n/tmp
3996         TMP_DIR=$DIR/d32n/tmp
3997         ln -s $DIR $TMP_DIR/symlink11
3998         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3999         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4000         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4001 }
4002 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4003
4004 test_32o() {
4005         touch $DIR/$tfile
4006         test_mkdir -p $DIR/d32o/tmp
4007         TMP_DIR=$DIR/d32o/tmp
4008         ln -s $DIR/$tfile $TMP_DIR/symlink12
4009         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4010         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4011                 error "symlink12 not a link"
4012         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4013         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4014                 error "$DIR/d32o/tmp/symlink12 not file type"
4015         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4016                 error "$DIR/d32o/symlink02 not file type"
4017 }
4018 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4019
4020 test_32p() {
4021         log 32p_1
4022         rm -fr $DIR/d32p
4023         log 32p_2
4024         rm -f $DIR/$tfile
4025         log 32p_3
4026         touch $DIR/$tfile
4027         log 32p_4
4028         test_mkdir -p $DIR/d32p/tmp
4029         log 32p_5
4030         TMP_DIR=$DIR/d32p/tmp
4031         log 32p_6
4032         ln -s $DIR/$tfile $TMP_DIR/symlink12
4033         log 32p_7
4034         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4035         log 32p_8
4036         cat $DIR/d32p/tmp/symlink12 ||
4037                 error "Can't open $DIR/d32p/tmp/symlink12"
4038         log 32p_9
4039         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4040         log 32p_10
4041 }
4042 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4043
4044 test_32q() {
4045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4046
4047         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4048         trap cleanup_test32_mount EXIT
4049         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4050         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4051         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4052                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4053         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4054         cleanup_test32_mount
4055 }
4056 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4057
4058 test_32r() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4062         trap cleanup_test32_mount EXIT
4063         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4064         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4065         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4066                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4067         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4068         cleanup_test32_mount
4069 }
4070 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4071
4072 test_33aa() {
4073         rm -f $DIR/$tfile
4074         touch $DIR/$tfile
4075         chmod 444 $DIR/$tfile
4076         chown $RUNAS_ID $DIR/$tfile
4077         log 33_1
4078         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4079         log 33_2
4080 }
4081 run_test 33aa "write file with mode 444 (should return error)"
4082
4083 test_33a() {
4084         rm -fr $DIR/$tdir
4085         test_mkdir $DIR/$tdir
4086         chown $RUNAS_ID $DIR/$tdir
4087         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4088                 error "$RUNAS create $tdir/$tfile failed"
4089         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4090                 error "open RDWR" || true
4091 }
4092 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4093
4094 test_33b() {
4095         rm -fr $DIR/$tdir
4096         test_mkdir $DIR/$tdir
4097         chown $RUNAS_ID $DIR/$tdir
4098         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4099 }
4100 run_test 33b "test open file with malformed flags (No panic)"
4101
4102 test_33c() {
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104         remote_ost_nodsh && skip "remote OST with nodsh"
4105
4106         local ostnum
4107         local ostname
4108         local write_bytes
4109         local all_zeros
4110
4111         all_zeros=true
4112         test_mkdir $DIR/$tdir
4113         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4114
4115         sync
4116         for ostnum in $(seq $OSTCOUNT); do
4117                 # test-framework's OST numbering is one-based, while Lustre's
4118                 # is zero-based
4119                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4120                 # check if at least some write_bytes stats are counted
4121                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4122                               obdfilter.$ostname.stats |
4123                               awk '/^write_bytes/ {print $7}' )
4124                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4125                 if (( ${write_bytes:-0} > 0 )); then
4126                         all_zeros=false
4127                         break
4128                 fi
4129         done
4130
4131         $all_zeros || return 0
4132
4133         # Write four bytes
4134         echo foo > $DIR/$tdir/bar
4135         # Really write them
4136         sync
4137
4138         # Total up write_bytes after writing.  We'd better find non-zeros.
4139         for ostnum in $(seq $OSTCOUNT); do
4140                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4141                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4142                               obdfilter/$ostname/stats |
4143                               awk '/^write_bytes/ {print $7}' )
4144                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4145                 if (( ${write_bytes:-0} > 0 )); then
4146                         all_zeros=false
4147                         break
4148                 fi
4149         done
4150
4151         if $all_zeros; then
4152                 for ostnum in $(seq $OSTCOUNT); do
4153                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4154                         echo "Check write_bytes is in obdfilter.*.stats:"
4155                         do_facet ost$ostnum lctl get_param -n \
4156                                 obdfilter.$ostname.stats
4157                 done
4158                 error "OST not keeping write_bytes stats (b=22312)"
4159         fi
4160 }
4161 run_test 33c "test write_bytes stats"
4162
4163 test_33d() {
4164         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4166
4167         local MDTIDX=1
4168         local remote_dir=$DIR/$tdir/remote_dir
4169
4170         test_mkdir $DIR/$tdir
4171         $LFS mkdir -i $MDTIDX $remote_dir ||
4172                 error "create remote directory failed"
4173
4174         touch $remote_dir/$tfile
4175         chmod 444 $remote_dir/$tfile
4176         chown $RUNAS_ID $remote_dir/$tfile
4177
4178         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4179
4180         chown $RUNAS_ID $remote_dir
4181         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4182                                         error "create" || true
4183         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4184                                     error "open RDWR" || true
4185         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4186 }
4187 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4188
4189 test_33e() {
4190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4191
4192         mkdir $DIR/$tdir
4193
4194         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4195         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4196         mkdir $DIR/$tdir/local_dir
4197
4198         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4199         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4200         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4201
4202         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4203                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4204
4205         rmdir $DIR/$tdir/* || error "rmdir failed"
4206
4207         umask 777
4208         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4209         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4210         mkdir $DIR/$tdir/local_dir
4211
4212         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4213         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4214         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4215
4216         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4217                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4218
4219         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4220
4221         umask 000
4222         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4223         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4224         mkdir $DIR/$tdir/local_dir
4225
4226         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4227         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4228         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4229
4230         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4231                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4232 }
4233 run_test 33e "mkdir and striped directory should have same mode"
4234
4235 cleanup_33f() {
4236         trap 0
4237         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4238 }
4239
4240 test_33f() {
4241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4242         remote_mds_nodsh && skip "remote MDS with nodsh"
4243
4244         mkdir $DIR/$tdir
4245         chmod go+rwx $DIR/$tdir
4246         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4247         trap cleanup_33f EXIT
4248
4249         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4250                 error "cannot create striped directory"
4251
4252         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4253                 error "cannot create files in striped directory"
4254
4255         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4256                 error "cannot remove files in striped directory"
4257
4258         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4259                 error "cannot remove striped directory"
4260
4261         cleanup_33f
4262 }
4263 run_test 33f "nonroot user can create, access, and remove a striped directory"
4264
4265 test_33g() {
4266         mkdir -p $DIR/$tdir/dir2
4267
4268         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4269         echo $err
4270         [[ $err =~ "exists" ]] || error "Not exists error"
4271 }
4272 run_test 33g "nonroot user create already existing root created file"
4273
4274 sub_33h() {
4275         local hash_type=$1
4276         local count=250
4277
4278         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4279                 error "lfs mkdir -H $hash_type $tdir failed"
4280         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4281
4282         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4283         local index2
4284         local fname
4285
4286         for fname in $DIR/$tdir/$tfile.bak \
4287                      $DIR/$tdir/$tfile.SAV \
4288                      $DIR/$tdir/$tfile.orig \
4289                      $DIR/$tdir/$tfile~; do
4290                 touch $fname || error "touch $fname failed"
4291                 index2=$($LFS getstripe -m $fname)
4292                 (( $index == $index2 )) ||
4293                         error "$fname MDT index mismatch $index != $index2"
4294         done
4295
4296         local failed=0
4297         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4298         local pattern
4299
4300         for pattern in ${patterns[*]}; do
4301                 echo "pattern $pattern"
4302                 fname=$DIR/$tdir/$pattern
4303                 for (( i = 0; i < $count; i++ )); do
4304                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4305                                 error "mktemp $DIR/$tdir/$pattern failed"
4306                         index2=$($LFS getstripe -m $fname)
4307                         (( $index == $index2 )) && continue
4308
4309                         failed=$((failed + 1))
4310                         echo "$fname MDT index mismatch $index != $index2"
4311                 done
4312         done
4313
4314         echo "$failed/$count MDT index mismatches, expect ~2-4"
4315         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4316
4317         local same=0
4318         local expect
4319
4320         # verify that "crush" is still broken with all files on same MDT,
4321         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4322         [[ "$hash_type" == "crush" ]] && expect=$count ||
4323                 expect=$((count / MDSCOUNT))
4324
4325         # crush2 doesn't put all-numeric suffixes on the same MDT,
4326         # filename like $tfile.12345678 should *not* be considered temp
4327         for pattern in ${patterns[*]}; do
4328                 local base=${pattern%%X*}
4329                 local suff=${pattern#$base}
4330
4331                 echo "pattern $pattern"
4332                 for (( i = 0; i < $count; i++ )); do
4333                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4334                         touch $fname || error "touch $fname failed"
4335                         index2=$($LFS getstripe -m $fname)
4336                         (( $index != $index2 )) && continue
4337
4338                         same=$((same + 1))
4339                 done
4340         done
4341
4342         # the number of "bad" hashes is random, as it depends on the random
4343         # filenames generated by "mktemp".  Allow some margin in the results.
4344         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4345         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4346            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4347                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4348         same=0
4349
4350         # crush2 doesn't put suffixes with special characters on the same MDT
4351         # filename like $tfile.txt.1234 should *not* be considered temp
4352         for pattern in ${patterns[*]}; do
4353                 local base=${pattern%%X*}
4354                 local suff=${pattern#$base}
4355
4356                 pattern=$base...${suff/XXX}
4357                 echo "pattern=$pattern"
4358                 for (( i = 0; i < $count; i++ )); do
4359                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4360                                 error "touch $fname failed"
4361                         index2=$($LFS getstripe -m $fname)
4362                         (( $index != $index2 )) && continue
4363
4364                         same=$((same + 1))
4365                 done
4366         done
4367
4368         # the number of "bad" hashes is random, as it depends on the random
4369         # filenames generated by "mktemp".  Allow some margin in the results.
4370         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4371         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4372            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4373                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4374 }
4375
4376 test_33h() {
4377         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4378         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4379                 skip "Need MDS version at least 2.13.50"
4380
4381         sub_33h crush
4382 }
4383 run_test 33h "temp file is located on the same MDT as target (crush)"
4384
4385 test_33hh() {
4386         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4387         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4388         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4389                 skip "Need MDS version at least 2.15.0 for crush2"
4390
4391         sub_33h crush2
4392 }
4393 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4394
4395 test_33i()
4396 {
4397         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4398
4399         local FNAME=$(str_repeat 'f' 250)
4400
4401         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4402         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4403
4404         local count
4405         local total
4406
4407         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4408
4409         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4410
4411         lctl --device %$MDC deactivate
4412         stack_trap "lctl --device %$MDC activate"
4413         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4414         total=$(\ls -l $DIR/$tdir | wc -l)
4415         # "ls -l" will list total in the first line
4416         total=$((total - 1))
4417         (( total + count == 1000 )) ||
4418                 error "ls list $total files, $count files on MDT1"
4419 }
4420 run_test 33i "striped directory can be accessed when one MDT is down"
4421
4422 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4423 test_34a() {
4424         rm -f $DIR/f34
4425         $MCREATE $DIR/f34 || error "mcreate failed"
4426         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4427                 error "getstripe failed"
4428         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4429         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4430                 error "getstripe failed"
4431         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4432                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4433 }
4434 run_test 34a "truncate file that has not been opened ==========="
4435
4436 test_34b() {
4437         [ ! -f $DIR/f34 ] && test_34a
4438         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4439                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4440         $OPENFILE -f O_RDONLY $DIR/f34
4441         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4442                 error "getstripe failed"
4443         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4444                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4445 }
4446 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4447
4448 test_34c() {
4449         [ ! -f $DIR/f34 ] && test_34a
4450         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4451                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4452         $OPENFILE -f O_RDWR $DIR/f34
4453         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4454                 error "$LFS getstripe failed"
4455         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4456                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4457 }
4458 run_test 34c "O_RDWR opening file-with-size works =============="
4459
4460 test_34d() {
4461         [ ! -f $DIR/f34 ] && test_34a
4462         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4463                 error "dd failed"
4464         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4465                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4466         rm $DIR/f34
4467 }
4468 run_test 34d "write to sparse file ============================="
4469
4470 test_34e() {
4471         rm -f $DIR/f34e
4472         $MCREATE $DIR/f34e || error "mcreate failed"
4473         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4474         $CHECKSTAT -s 1000 $DIR/f34e ||
4475                 error "Size of $DIR/f34e not equal to 1000 bytes"
4476         $OPENFILE -f O_RDWR $DIR/f34e
4477         $CHECKSTAT -s 1000 $DIR/f34e ||
4478                 error "Size of $DIR/f34e not equal to 1000 bytes"
4479 }
4480 run_test 34e "create objects, some with size and some without =="
4481
4482 test_34f() { # bug 6242, 6243
4483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4484
4485         SIZE34F=48000
4486         rm -f $DIR/f34f
4487         $MCREATE $DIR/f34f || error "mcreate failed"
4488         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4489         dd if=$DIR/f34f of=$TMP/f34f
4490         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4491         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4492         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4493         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4494         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4495 }
4496 run_test 34f "read from a file with no objects until EOF ======="
4497
4498 test_34g() {
4499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4500
4501         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4502                 error "dd failed"
4503         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4504         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4505                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4506         cancel_lru_locks osc
4507         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4508                 error "wrong size after lock cancel"
4509
4510         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4511         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4512                 error "expanding truncate failed"
4513         cancel_lru_locks osc
4514         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4515                 error "wrong expanded size after lock cancel"
4516 }
4517 run_test 34g "truncate long file ==============================="
4518
4519 test_34h() {
4520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4521
4522         local gid=10
4523         local sz=1000
4524
4525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4526         sync # Flush the cache so that multiop below does not block on cache
4527              # flush when getting the group lock
4528         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4529         MULTIPID=$!
4530
4531         # Since just timed wait is not good enough, let's do a sync write
4532         # that way we are sure enough time for a roundtrip + processing
4533         # passed + 2 seconds of extra margin.
4534         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4535         rm $DIR/${tfile}-1
4536         sleep 2
4537
4538         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4539                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4540                 kill -9 $MULTIPID
4541         fi
4542         wait $MULTIPID
4543         local nsz=`stat -c %s $DIR/$tfile`
4544         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4545 }
4546 run_test 34h "ftruncate file under grouplock should not block"
4547
4548 test_35a() {
4549         cp /bin/sh $DIR/f35a
4550         chmod 444 $DIR/f35a
4551         chown $RUNAS_ID $DIR/f35a
4552         $RUNAS $DIR/f35a && error || true
4553         rm $DIR/f35a
4554 }
4555 run_test 35a "exec file with mode 444 (should return and not leak)"
4556
4557 test_36a() {
4558         rm -f $DIR/f36
4559         utime $DIR/f36 || error "utime failed for MDS"
4560 }
4561 run_test 36a "MDS utime check (mknod, utime)"
4562
4563 test_36b() {
4564         echo "" > $DIR/f36
4565         utime $DIR/f36 || error "utime failed for OST"
4566 }
4567 run_test 36b "OST utime check (open, utime)"
4568
4569 test_36c() {
4570         rm -f $DIR/d36/f36
4571         test_mkdir $DIR/d36
4572         chown $RUNAS_ID $DIR/d36
4573         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4574 }
4575 run_test 36c "non-root MDS utime check (mknod, utime)"
4576
4577 test_36d() {
4578         [ ! -d $DIR/d36 ] && test_36c
4579         echo "" > $DIR/d36/f36
4580         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4581 }
4582 run_test 36d "non-root OST utime check (open, utime)"
4583
4584 test_36e() {
4585         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4586
4587         test_mkdir $DIR/$tdir
4588         touch $DIR/$tdir/$tfile
4589         $RUNAS utime $DIR/$tdir/$tfile &&
4590                 error "utime worked, expected failure" || true
4591 }
4592 run_test 36e "utime on non-owned file (should return error)"
4593
4594 subr_36fh() {
4595         local fl="$1"
4596         local LANG_SAVE=$LANG
4597         local LC_LANG_SAVE=$LC_LANG
4598         export LANG=C LC_LANG=C # for date language
4599
4600         DATESTR="Dec 20  2000"
4601         test_mkdir $DIR/$tdir
4602         lctl set_param fail_loc=$fl
4603         date; date +%s
4604         cp /etc/hosts $DIR/$tdir/$tfile
4605         sync & # write RPC generated with "current" inode timestamp, but delayed
4606         sleep 1
4607         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4608         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4609         cancel_lru_locks $OSC
4610         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4611         date; date +%s
4612         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4613                 echo "BEFORE: $LS_BEFORE" && \
4614                 echo "AFTER : $LS_AFTER" && \
4615                 echo "WANT  : $DATESTR" && \
4616                 error "$DIR/$tdir/$tfile timestamps changed" || true
4617
4618         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4619 }
4620
4621 test_36f() {
4622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4623
4624         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4625         subr_36fh "0x80000214"
4626 }
4627 run_test 36f "utime on file racing with OST BRW write =========="
4628
4629 test_36g() {
4630         remote_ost_nodsh && skip "remote OST with nodsh"
4631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4632         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4633                 skip "Need MDS version at least 2.12.51"
4634
4635         local fmd_max_age
4636         local fmd
4637         local facet="ost1"
4638         local tgt="obdfilter"
4639
4640         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4641
4642         test_mkdir $DIR/$tdir
4643         fmd_max_age=$(do_facet $facet \
4644                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4645                 head -n 1")
4646
4647         echo "FMD max age: ${fmd_max_age}s"
4648         touch $DIR/$tdir/$tfile
4649         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4650                 gawk '{cnt=cnt+$1}  END{print cnt}')
4651         echo "FMD before: $fmd"
4652         [[ $fmd == 0 ]] &&
4653                 error "FMD wasn't create by touch"
4654         sleep $((fmd_max_age + 12))
4655         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4656                 gawk '{cnt=cnt+$1}  END{print cnt}')
4657         echo "FMD after: $fmd"
4658         [[ $fmd == 0 ]] ||
4659                 error "FMD wasn't expired by ping"
4660 }
4661 run_test 36g "FMD cache expiry ====================="
4662
4663 test_36h() {
4664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4665
4666         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4667         subr_36fh "0x80000227"
4668 }
4669 run_test 36h "utime on file racing with OST BRW write =========="
4670
4671 test_36i() {
4672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4673
4674         test_mkdir $DIR/$tdir
4675         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4676
4677         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4678         local new_mtime=$((mtime + 200))
4679
4680         #change Modify time of striped dir
4681         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4682                         error "change mtime failed"
4683
4684         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4685
4686         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4687 }
4688 run_test 36i "change mtime on striped directory"
4689
4690 # test_37 - duplicate with tests 32q 32r
4691
4692 test_38() {
4693         local file=$DIR/$tfile
4694         touch $file
4695         openfile -f O_DIRECTORY $file
4696         local RC=$?
4697         local ENOTDIR=20
4698         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4699         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4700 }
4701 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4702
4703 test_39a() { # was test_39
4704         touch $DIR/$tfile
4705         touch $DIR/${tfile}2
4706 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4707 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4708 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4709         sleep 2
4710         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4711         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4712                 echo "mtime"
4713                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4714                 echo "atime"
4715                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4716                 echo "ctime"
4717                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4718                 error "O_TRUNC didn't change timestamps"
4719         fi
4720 }
4721 run_test 39a "mtime changed on create"
4722
4723 test_39b() {
4724         test_mkdir -c1 $DIR/$tdir
4725         cp -p /etc/passwd $DIR/$tdir/fopen
4726         cp -p /etc/passwd $DIR/$tdir/flink
4727         cp -p /etc/passwd $DIR/$tdir/funlink
4728         cp -p /etc/passwd $DIR/$tdir/frename
4729         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4730
4731         sleep 1
4732         echo "aaaaaa" >> $DIR/$tdir/fopen
4733         echo "aaaaaa" >> $DIR/$tdir/flink
4734         echo "aaaaaa" >> $DIR/$tdir/funlink
4735         echo "aaaaaa" >> $DIR/$tdir/frename
4736
4737         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4738         local link_new=`stat -c %Y $DIR/$tdir/flink`
4739         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4740         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4741
4742         cat $DIR/$tdir/fopen > /dev/null
4743         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4744         rm -f $DIR/$tdir/funlink2
4745         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4749                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4750                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4751                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4752
4753                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4754                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4755                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4756                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4757
4758                 cancel_lru_locks $OSC
4759                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4760         done
4761 }
4762 run_test 39b "mtime change on open, link, unlink, rename  ======"
4763
4764 # this should be set to past
4765 TEST_39_MTIME=`date -d "1 year ago" +%s`
4766
4767 # bug 11063
4768 test_39c() {
4769         touch $DIR1/$tfile
4770         sleep 2
4771         local mtime0=`stat -c %Y $DIR1/$tfile`
4772
4773         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4774         local mtime1=`stat -c %Y $DIR1/$tfile`
4775         [ "$mtime1" = $TEST_39_MTIME ] || \
4776                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4777
4778         local d1=`date +%s`
4779         echo hello >> $DIR1/$tfile
4780         local d2=`date +%s`
4781         local mtime2=`stat -c %Y $DIR1/$tfile`
4782         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4783                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4784
4785         mv $DIR1/$tfile $DIR1/$tfile-1
4786
4787         for (( i=0; i < 2; i++ )) ; do
4788                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4789                 [ "$mtime2" = "$mtime3" ] || \
4790                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4791
4792                 cancel_lru_locks $OSC
4793                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4794         done
4795 }
4796 run_test 39c "mtime change on rename ==========================="
4797
4798 # bug 21114
4799 test_39d() {
4800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4801
4802         touch $DIR1/$tfile
4803         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4804
4805         for (( i=0; i < 2; i++ )) ; do
4806                 local mtime=`stat -c %Y $DIR1/$tfile`
4807                 [ $mtime = $TEST_39_MTIME ] || \
4808                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4809
4810                 cancel_lru_locks $OSC
4811                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4812         done
4813 }
4814 run_test 39d "create, utime, stat =============================="
4815
4816 # bug 21114
4817 test_39e() {
4818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4819
4820         touch $DIR1/$tfile
4821         local mtime1=`stat -c %Y $DIR1/$tfile`
4822
4823         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4824
4825         for (( i=0; i < 2; i++ )) ; do
4826                 local mtime2=`stat -c %Y $DIR1/$tfile`
4827                 [ $mtime2 = $TEST_39_MTIME ] || \
4828                         error "mtime($mtime2) 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 39e "create, stat, utime, stat ========================"
4835
4836 # bug 21114
4837 test_39f() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         touch $DIR1/$tfile
4841         mtime1=`stat -c %Y $DIR1/$tfile`
4842
4843         sleep 2
4844         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4845
4846         for (( i=0; i < 2; i++ )) ; do
4847                 local mtime2=`stat -c %Y $DIR1/$tfile`
4848                 [ $mtime2 = $TEST_39_MTIME ] || \
4849                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4850
4851                 cancel_lru_locks $OSC
4852                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4853         done
4854 }
4855 run_test 39f "create, stat, sleep, utime, stat ================="
4856
4857 # bug 11063
4858 test_39g() {
4859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4860
4861         echo hello >> $DIR1/$tfile
4862         local mtime1=`stat -c %Y $DIR1/$tfile`
4863
4864         sleep 2
4865         chmod o+r $DIR1/$tfile
4866
4867         for (( i=0; i < 2; i++ )) ; do
4868                 local mtime2=`stat -c %Y $DIR1/$tfile`
4869                 [ "$mtime1" = "$mtime2" ] || \
4870                         error "lost mtime: $mtime2, should be $mtime1"
4871
4872                 cancel_lru_locks $OSC
4873                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4874         done
4875 }
4876 run_test 39g "write, chmod, stat ==============================="
4877
4878 # bug 11063
4879 test_39h() {
4880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4881
4882         touch $DIR1/$tfile
4883         sleep 1
4884
4885         local d1=`date`
4886         echo hello >> $DIR1/$tfile
4887         local mtime1=`stat -c %Y $DIR1/$tfile`
4888
4889         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4890         local d2=`date`
4891         if [ "$d1" != "$d2" ]; then
4892                 echo "write and touch not within one second"
4893         else
4894                 for (( i=0; i < 2; i++ )) ; do
4895                         local mtime2=`stat -c %Y $DIR1/$tfile`
4896                         [ "$mtime2" = $TEST_39_MTIME ] || \
4897                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4898
4899                         cancel_lru_locks $OSC
4900                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4901                 done
4902         fi
4903 }
4904 run_test 39h "write, utime within one second, stat ============="
4905
4906 test_39i() {
4907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4908
4909         touch $DIR1/$tfile
4910         sleep 1
4911
4912         echo hello >> $DIR1/$tfile
4913         local mtime1=`stat -c %Y $DIR1/$tfile`
4914
4915         mv $DIR1/$tfile $DIR1/$tfile-1
4916
4917         for (( i=0; i < 2; i++ )) ; do
4918                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4919
4920                 [ "$mtime1" = "$mtime2" ] || \
4921                         error "lost mtime: $mtime2, should be $mtime1"
4922
4923                 cancel_lru_locks $OSC
4924                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4925         done
4926 }
4927 run_test 39i "write, rename, stat =============================="
4928
4929 test_39j() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         start_full_debug_logging
4933         touch $DIR1/$tfile
4934         sleep 1
4935
4936         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4937         lctl set_param fail_loc=0x80000412
4938         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4939                 error "multiop failed"
4940         local multipid=$!
4941         local mtime1=`stat -c %Y $DIR1/$tfile`
4942
4943         mv $DIR1/$tfile $DIR1/$tfile-1
4944
4945         kill -USR1 $multipid
4946         wait $multipid || error "multiop close failed"
4947
4948         for (( i=0; i < 2; i++ )) ; do
4949                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4950                 [ "$mtime1" = "$mtime2" ] ||
4951                         error "mtime is lost on close: $mtime2, " \
4952                               "should be $mtime1"
4953
4954                 cancel_lru_locks
4955                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4956         done
4957         lctl set_param fail_loc=0
4958         stop_full_debug_logging
4959 }
4960 run_test 39j "write, rename, close, stat ======================="
4961
4962 test_39k() {
4963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4964
4965         touch $DIR1/$tfile
4966         sleep 1
4967
4968         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4969         local multipid=$!
4970         local mtime1=`stat -c %Y $DIR1/$tfile`
4971
4972         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4973
4974         kill -USR1 $multipid
4975         wait $multipid || error "multiop close failed"
4976
4977         for (( i=0; i < 2; i++ )) ; do
4978                 local mtime2=`stat -c %Y $DIR1/$tfile`
4979
4980                 [ "$mtime2" = $TEST_39_MTIME ] || \
4981                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4982
4983                 cancel_lru_locks
4984                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4985         done
4986 }
4987 run_test 39k "write, utime, close, stat ========================"
4988
4989 # this should be set to future
4990 TEST_39_ATIME=`date -d "1 year" +%s`
4991
4992 test_39l() {
4993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4994         remote_mds_nodsh && skip "remote MDS with nodsh"
4995
4996         local atime_diff=$(do_facet $SINGLEMDS \
4997                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4998         rm -rf $DIR/$tdir
4999         mkdir_on_mdt0 $DIR/$tdir
5000
5001         # test setting directory atime to future
5002         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5003         local atime=$(stat -c %X $DIR/$tdir)
5004         [ "$atime" = $TEST_39_ATIME ] ||
5005                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5006
5007         # test setting directory atime from future to now
5008         local now=$(date +%s)
5009         touch -a -d @$now $DIR/$tdir
5010
5011         atime=$(stat -c %X $DIR/$tdir)
5012         [ "$atime" -eq "$now"  ] ||
5013                 error "atime is not updated from future: $atime, $now"
5014
5015         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5016         sleep 3
5017
5018         # test setting directory atime when now > dir atime + atime_diff
5019         local d1=$(date +%s)
5020         ls $DIR/$tdir
5021         local d2=$(date +%s)
5022         cancel_lru_locks mdc
5023         atime=$(stat -c %X $DIR/$tdir)
5024         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5025                 error "atime is not updated  : $atime, should be $d2"
5026
5027         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5028         sleep 3
5029
5030         # test not setting directory atime when now < dir atime + atime_diff
5031         ls $DIR/$tdir
5032         cancel_lru_locks mdc
5033         atime=$(stat -c %X $DIR/$tdir)
5034         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5035                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5036
5037         do_facet $SINGLEMDS \
5038                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5039 }
5040 run_test 39l "directory atime update ==========================="
5041
5042 test_39m() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         touch $DIR1/$tfile
5046         sleep 2
5047         local far_past_mtime=$(date -d "May 29 1953" +%s)
5048         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5049
5050         touch -m -d @$far_past_mtime $DIR1/$tfile
5051         touch -a -d @$far_past_atime $DIR1/$tfile
5052
5053         for (( i=0; i < 2; i++ )) ; do
5054                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5055                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5056                         error "atime or mtime set incorrectly"
5057
5058                 cancel_lru_locks $OSC
5059                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5060         done
5061 }
5062 run_test 39m "test atime and mtime before 1970"
5063
5064 test_39n() { # LU-3832
5065         remote_mds_nodsh && skip "remote MDS with nodsh"
5066
5067         local atime_diff=$(do_facet $SINGLEMDS \
5068                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5069         local atime0
5070         local atime1
5071         local atime2
5072
5073         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5074
5075         rm -rf $DIR/$tfile
5076         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5077         atime0=$(stat -c %X $DIR/$tfile)
5078
5079         sleep 5
5080         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5081         atime1=$(stat -c %X $DIR/$tfile)
5082
5083         sleep 5
5084         cancel_lru_locks mdc
5085         cancel_lru_locks osc
5086         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5087         atime2=$(stat -c %X $DIR/$tfile)
5088
5089         do_facet $SINGLEMDS \
5090                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5091
5092         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5093         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5094 }
5095 run_test 39n "check that O_NOATIME is honored"
5096
5097 test_39o() {
5098         TESTDIR=$DIR/$tdir/$tfile
5099         [ -e $TESTDIR ] && rm -rf $TESTDIR
5100         mkdir -p $TESTDIR
5101         cd $TESTDIR
5102         links1=2
5103         ls
5104         mkdir a b
5105         ls
5106         links2=$(stat -c %h .)
5107         [ $(($links1 + 2)) != $links2 ] &&
5108                 error "wrong links count $(($links1 + 2)) != $links2"
5109         rmdir b
5110         links3=$(stat -c %h .)
5111         [ $(($links1 + 1)) != $links3 ] &&
5112                 error "wrong links count $links1 != $links3"
5113         return 0
5114 }
5115 run_test 39o "directory cached attributes updated after create"
5116
5117 test_39p() {
5118         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5119
5120         local MDTIDX=1
5121         TESTDIR=$DIR/$tdir/$tdir
5122         [ -e $TESTDIR ] && rm -rf $TESTDIR
5123         test_mkdir -p $TESTDIR
5124         cd $TESTDIR
5125         links1=2
5126         ls
5127         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5128         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5129         ls
5130         links2=$(stat -c %h .)
5131         [ $(($links1 + 2)) != $links2 ] &&
5132                 error "wrong links count $(($links1 + 2)) != $links2"
5133         rmdir remote_dir2
5134         links3=$(stat -c %h .)
5135         [ $(($links1 + 1)) != $links3 ] &&
5136                 error "wrong links count $links1 != $links3"
5137         return 0
5138 }
5139 run_test 39p "remote directory cached attributes updated after create ========"
5140
5141 test_39r() {
5142         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5143                 skip "no atime update on old OST"
5144         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5145                 skip_env "ldiskfs only test"
5146         fi
5147
5148         local saved_adiff
5149         saved_adiff=$(do_facet ost1 \
5150                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5151         stack_trap "do_facet ost1 \
5152                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5153
5154         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5155
5156         $LFS setstripe -i 0 $DIR/$tfile
5157         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5158                 error "can't write initial file"
5159         cancel_lru_locks osc
5160
5161         # exceed atime_diff and access file
5162         sleep 10
5163         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5164                 error "can't udpate atime"
5165
5166         local atime_cli=$(stat -c %X $DIR/$tfile)
5167         echo "client atime: $atime_cli"
5168         # allow atime update to be written to device
5169         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5170         sleep 5
5171
5172         local ostdev=$(ostdevname 1)
5173         local fid=($(lfs getstripe -y $DIR/$tfile |
5174                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5175         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5176         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5177
5178         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5179         local atime_ost=$(do_facet ost1 "$cmd" |&
5180                           awk -F'[: ]' '/atime:/ { print $4 }')
5181         (( atime_cli == atime_ost )) ||
5182                 error "atime on client $atime_cli != ost $atime_ost"
5183 }
5184 run_test 39r "lazy atime update on OST"
5185
5186 test_39q() { # LU-8041
5187         local testdir=$DIR/$tdir
5188         mkdir -p $testdir
5189         multiop_bg_pause $testdir D_c || error "multiop failed"
5190         local multipid=$!
5191         cancel_lru_locks mdc
5192         kill -USR1 $multipid
5193         local atime=$(stat -c %X $testdir)
5194         [ "$atime" -ne 0 ] || error "atime is zero"
5195 }
5196 run_test 39q "close won't zero out atime"
5197
5198 test_40() {
5199         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5200         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5201                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5202         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5203                 error "$tfile is not 4096 bytes in size"
5204 }
5205 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5206
5207 test_41() {
5208         # bug 1553
5209         small_write $DIR/f41 18
5210 }
5211 run_test 41 "test small file write + fstat ====================="
5212
5213 count_ost_writes() {
5214         lctl get_param -n ${OSC}.*.stats |
5215                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5216                         END { printf("%0.0f", writes) }'
5217 }
5218
5219 # decent default
5220 WRITEBACK_SAVE=500
5221 DIRTY_RATIO_SAVE=40
5222 MAX_DIRTY_RATIO=50
5223 BG_DIRTY_RATIO_SAVE=10
5224 MAX_BG_DIRTY_RATIO=25
5225
5226 start_writeback() {
5227         trap 0
5228         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5229         # dirty_ratio, dirty_background_ratio
5230         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5231                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5232                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5233                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5234         else
5235                 # if file not here, we are a 2.4 kernel
5236                 kill -CONT `pidof kupdated`
5237         fi
5238 }
5239
5240 stop_writeback() {
5241         # setup the trap first, so someone cannot exit the test at the
5242         # exact wrong time and mess up a machine
5243         trap start_writeback EXIT
5244         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5245         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5246                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5247                 sysctl -w vm.dirty_writeback_centisecs=0
5248                 sysctl -w vm.dirty_writeback_centisecs=0
5249                 # save and increase /proc/sys/vm/dirty_ratio
5250                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5251                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5252                 # save and increase /proc/sys/vm/dirty_background_ratio
5253                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5254                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5255         else
5256                 # if file not here, we are a 2.4 kernel
5257                 kill -STOP `pidof kupdated`
5258         fi
5259 }
5260
5261 # ensure that all stripes have some grant before we test client-side cache
5262 setup_test42() {
5263         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5264                 dd if=/dev/zero of=$i bs=4k count=1
5265                 rm $i
5266         done
5267 }
5268
5269 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5270 # file truncation, and file removal.
5271 test_42a() {
5272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5273
5274         setup_test42
5275         cancel_lru_locks $OSC
5276         stop_writeback
5277         sync; sleep 1; sync # just to be safe
5278         BEFOREWRITES=`count_ost_writes`
5279         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5280         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5281         AFTERWRITES=`count_ost_writes`
5282         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5283                 error "$BEFOREWRITES < $AFTERWRITES"
5284         start_writeback
5285 }
5286 run_test 42a "ensure that we don't flush on close"
5287
5288 test_42b() {
5289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5290
5291         setup_test42
5292         cancel_lru_locks $OSC
5293         stop_writeback
5294         sync
5295         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5296         BEFOREWRITES=$(count_ost_writes)
5297         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5298         AFTERWRITES=$(count_ost_writes)
5299         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5300                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5301         fi
5302         BEFOREWRITES=$(count_ost_writes)
5303         sync || error "sync: $?"
5304         AFTERWRITES=$(count_ost_writes)
5305         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5306                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5307         fi
5308         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5309         start_writeback
5310         return 0
5311 }
5312 run_test 42b "test destroy of file with cached dirty data ======"
5313
5314 # if these tests just want to test the effect of truncation,
5315 # they have to be very careful.  consider:
5316 # - the first open gets a {0,EOF}PR lock
5317 # - the first write conflicts and gets a {0, count-1}PW
5318 # - the rest of the writes are under {count,EOF}PW
5319 # - the open for truncate tries to match a {0,EOF}PR
5320 #   for the filesize and cancels the PWs.
5321 # any number of fixes (don't get {0,EOF} on open, match
5322 # composite locks, do smarter file size management) fix
5323 # this, but for now we want these tests to verify that
5324 # the cancellation with truncate intent works, so we
5325 # start the file with a full-file pw lock to match against
5326 # until the truncate.
5327 trunc_test() {
5328         test=$1
5329         file=$DIR/$test
5330         offset=$2
5331         cancel_lru_locks $OSC
5332         stop_writeback
5333         # prime the file with 0,EOF PW to match
5334         touch $file
5335         $TRUNCATE $file 0
5336         sync; sync
5337         # now the real test..
5338         dd if=/dev/zero of=$file bs=1024 count=100
5339         BEFOREWRITES=`count_ost_writes`
5340         $TRUNCATE $file $offset
5341         cancel_lru_locks $OSC
5342         AFTERWRITES=`count_ost_writes`
5343         start_writeback
5344 }
5345
5346 test_42c() {
5347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5348
5349         trunc_test 42c 1024
5350         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5351                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5352         rm $file
5353 }
5354 run_test 42c "test partial truncate of file with cached dirty data"
5355
5356 test_42d() {
5357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5358
5359         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5360         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5361         $LCTL set_param debug=+cache
5362
5363         trunc_test 42d 0
5364         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5365                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5366         rm $file
5367 }
5368 run_test 42d "test complete truncate of file with cached dirty data"
5369
5370 test_42e() { # bug22074
5371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5372
5373         local TDIR=$DIR/${tdir}e
5374         local pages=16 # hardcoded 16 pages, don't change it.
5375         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5376         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5377         local max_dirty_mb
5378         local warmup_files
5379
5380         test_mkdir $DIR/${tdir}e
5381         $LFS setstripe -c 1 $TDIR
5382         createmany -o $TDIR/f $files
5383
5384         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5385
5386         # we assume that with $OSTCOUNT files, at least one of them will
5387         # be allocated on OST0.
5388         warmup_files=$((OSTCOUNT * max_dirty_mb))
5389         createmany -o $TDIR/w $warmup_files
5390
5391         # write a large amount of data into one file and sync, to get good
5392         # avail_grant number from OST.
5393         for ((i=0; i<$warmup_files; i++)); do
5394                 idx=$($LFS getstripe -i $TDIR/w$i)
5395                 [ $idx -ne 0 ] && continue
5396                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5397                 break
5398         done
5399         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5400         sync
5401         $LCTL get_param $proc_osc0/cur_dirty_bytes
5402         $LCTL get_param $proc_osc0/cur_grant_bytes
5403
5404         # create as much dirty pages as we can while not to trigger the actual
5405         # RPCs directly. but depends on the env, VFS may trigger flush during this
5406         # period, hopefully we are good.
5407         for ((i=0; i<$warmup_files; i++)); do
5408                 idx=$($LFS getstripe -i $TDIR/w$i)
5409                 [ $idx -ne 0 ] && continue
5410                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5411         done
5412         $LCTL get_param $proc_osc0/cur_dirty_bytes
5413         $LCTL get_param $proc_osc0/cur_grant_bytes
5414
5415         # perform the real test
5416         $LCTL set_param $proc_osc0/rpc_stats 0
5417         for ((;i<$files; i++)); do
5418                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5419                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5420         done
5421         sync
5422         $LCTL get_param $proc_osc0/rpc_stats
5423
5424         local percent=0
5425         local have_ppr=false
5426         $LCTL get_param $proc_osc0/rpc_stats |
5427                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5428                         # skip lines until we are at the RPC histogram data
5429                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5430                         $have_ppr || continue
5431
5432                         # we only want the percent stat for < 16 pages
5433                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5434
5435                         percent=$((percent + WPCT))
5436                         if [[ $percent -gt 15 ]]; then
5437                                 error "less than 16-pages write RPCs" \
5438                                       "$percent% > 15%"
5439                                 break
5440                         fi
5441                 done
5442         rm -rf $TDIR
5443 }
5444 run_test 42e "verify sub-RPC writes are not done synchronously"
5445
5446 test_43A() { # was test_43
5447         test_mkdir $DIR/$tdir
5448         cp -p /bin/ls $DIR/$tdir/$tfile
5449         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5450         pid=$!
5451         # give multiop a chance to open
5452         sleep 1
5453
5454         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5455         kill -USR1 $pid
5456         # Wait for multiop to exit
5457         wait $pid
5458 }
5459 run_test 43A "execution of file opened for write should return -ETXTBSY"
5460
5461 test_43a() {
5462         test_mkdir $DIR/$tdir
5463         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5464         $DIR/$tdir/sleep 60 &
5465         SLEEP_PID=$!
5466         # Make sure exec of $tdir/sleep wins race with truncate
5467         sleep 1
5468         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5469         kill $SLEEP_PID
5470 }
5471 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5472
5473 test_43b() {
5474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5475
5476         test_mkdir $DIR/$tdir
5477         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5478         $DIR/$tdir/sleep 60 &
5479         SLEEP_PID=$!
5480         # Make sure exec of $tdir/sleep wins race with truncate
5481         sleep 1
5482         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5483         kill $SLEEP_PID
5484 }
5485 run_test 43b "truncate of file being executed should return -ETXTBSY"
5486
5487 test_43c() {
5488         local testdir="$DIR/$tdir"
5489         test_mkdir $testdir
5490         cp $SHELL $testdir/
5491         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5492                 ( cd $testdir && md5sum -c )
5493 }
5494 run_test 43c "md5sum of copy into lustre"
5495
5496 test_44A() { # was test_44
5497         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5498
5499         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5500         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5501 }
5502 run_test 44A "zero length read from a sparse stripe"
5503
5504 test_44a() {
5505         local nstripe=$($LFS getstripe -c -d $DIR)
5506         [ -z "$nstripe" ] && skip "can't get stripe info"
5507         [[ $nstripe -gt $OSTCOUNT ]] &&
5508                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5509
5510         local stride=$($LFS getstripe -S -d $DIR)
5511         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5512                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5513         fi
5514
5515         OFFSETS="0 $((stride/2)) $((stride-1))"
5516         for offset in $OFFSETS; do
5517                 for i in $(seq 0 $((nstripe-1))); do
5518                         local GLOBALOFFSETS=""
5519                         # size in Bytes
5520                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5521                         local myfn=$DIR/d44a-$size
5522                         echo "--------writing $myfn at $size"
5523                         ll_sparseness_write $myfn $size ||
5524                                 error "ll_sparseness_write"
5525                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5526                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5527                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5528
5529                         for j in $(seq 0 $((nstripe-1))); do
5530                                 # size in Bytes
5531                                 size=$((((j + $nstripe )*$stride + $offset)))
5532                                 ll_sparseness_write $myfn $size ||
5533                                         error "ll_sparseness_write"
5534                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5535                         done
5536                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5537                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5538                         rm -f $myfn
5539                 done
5540         done
5541 }
5542 run_test 44a "test sparse pwrite ==============================="
5543
5544 dirty_osc_total() {
5545         tot=0
5546         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5547                 tot=$(($tot + $d))
5548         done
5549         echo $tot
5550 }
5551 do_dirty_record() {
5552         before=`dirty_osc_total`
5553         echo executing "\"$*\""
5554         eval $*
5555         after=`dirty_osc_total`
5556         echo before $before, after $after
5557 }
5558 test_45() {
5559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5560
5561         f="$DIR/f45"
5562         # Obtain grants from OST if it supports it
5563         echo blah > ${f}_grant
5564         stop_writeback
5565         sync
5566         do_dirty_record "echo blah > $f"
5567         [[ $before -eq $after ]] && error "write wasn't cached"
5568         do_dirty_record "> $f"
5569         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5570         do_dirty_record "echo blah > $f"
5571         [[ $before -eq $after ]] && error "write wasn't cached"
5572         do_dirty_record "sync"
5573         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5574         do_dirty_record "echo blah > $f"
5575         [[ $before -eq $after ]] && error "write wasn't cached"
5576         do_dirty_record "cancel_lru_locks osc"
5577         [[ $before -gt $after ]] ||
5578                 error "lock cancellation didn't lower dirty count"
5579         start_writeback
5580 }
5581 run_test 45 "osc io page accounting ============================"
5582
5583 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5584 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5585 # objects offset and an assert hit when an rpc was built with 1023's mapped
5586 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5587 test_46() {
5588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5589
5590         f="$DIR/f46"
5591         stop_writeback
5592         sync
5593         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5594         sync
5595         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5596         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5597         sync
5598         start_writeback
5599 }
5600 run_test 46 "dirtying a previously written page ================"
5601
5602 # test_47 is removed "Device nodes check" is moved to test_28
5603
5604 test_48a() { # bug 2399
5605         [ "$mds1_FSTYPE" = "zfs" ] &&
5606         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5607                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5608
5609         test_mkdir $DIR/$tdir
5610         cd $DIR/$tdir
5611         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5612         test_mkdir $DIR/$tdir
5613         touch foo || error "'touch foo' failed after recreating cwd"
5614         test_mkdir bar
5615         touch .foo || error "'touch .foo' failed after recreating cwd"
5616         test_mkdir .bar
5617         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5618         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5619         cd . || error "'cd .' failed after recreating cwd"
5620         mkdir . && error "'mkdir .' worked after recreating cwd"
5621         rmdir . && error "'rmdir .' worked after recreating cwd"
5622         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5623         cd .. || error "'cd ..' failed after recreating cwd"
5624 }
5625 run_test 48a "Access renamed working dir (should return errors)="
5626
5627 test_48b() { # bug 2399
5628         rm -rf $DIR/$tdir
5629         test_mkdir $DIR/$tdir
5630         cd $DIR/$tdir
5631         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5632         touch foo && error "'touch foo' worked after removing cwd"
5633         mkdir foo && error "'mkdir foo' worked after removing cwd"
5634         touch .foo && error "'touch .foo' worked after removing cwd"
5635         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5636         ls . > /dev/null && error "'ls .' worked after removing cwd"
5637         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5638         mkdir . && error "'mkdir .' worked after removing cwd"
5639         rmdir . && error "'rmdir .' worked after removing cwd"
5640         ln -s . foo && error "'ln -s .' worked after removing cwd"
5641         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5642 }
5643 run_test 48b "Access removed working dir (should return errors)="
5644
5645 test_48c() { # bug 2350
5646         #lctl set_param debug=-1
5647         #set -vx
5648         rm -rf $DIR/$tdir
5649         test_mkdir -p $DIR/$tdir/dir
5650         cd $DIR/$tdir/dir
5651         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5652         $TRACE touch foo && error "touch foo worked after removing cwd"
5653         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5654         touch .foo && error "touch .foo worked after removing cwd"
5655         mkdir .foo && error "mkdir .foo worked after removing cwd"
5656         $TRACE ls . && error "'ls .' worked after removing cwd"
5657         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5658         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5659         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5660         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5661         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5662 }
5663 run_test 48c "Access removed working subdir (should return errors)"
5664
5665 test_48d() { # bug 2350
5666         #lctl set_param debug=-1
5667         #set -vx
5668         rm -rf $DIR/$tdir
5669         test_mkdir -p $DIR/$tdir/dir
5670         cd $DIR/$tdir/dir
5671         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5672         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5673         $TRACE touch foo && error "'touch foo' worked after removing parent"
5674         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5675         touch .foo && error "'touch .foo' worked after removing parent"
5676         mkdir .foo && error "mkdir .foo worked after removing parent"
5677         $TRACE ls . && error "'ls .' worked after removing parent"
5678         $TRACE ls .. && error "'ls ..' worked after removing parent"
5679         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5680         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5681         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5682         true
5683 }
5684 run_test 48d "Access removed parent subdir (should return errors)"
5685
5686 test_48e() { # bug 4134
5687         #lctl set_param debug=-1
5688         #set -vx
5689         rm -rf $DIR/$tdir
5690         test_mkdir -p $DIR/$tdir/dir
5691         cd $DIR/$tdir/dir
5692         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5693         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5694         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5695         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5696         # On a buggy kernel addition of "touch foo" after cd .. will
5697         # produce kernel oops in lookup_hash_it
5698         touch ../foo && error "'cd ..' worked after recreate parent"
5699         cd $DIR
5700         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5701 }
5702 run_test 48e "Access to recreated parent subdir (should return errors)"
5703
5704 test_48f() {
5705         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5706                 skip "need MDS >= 2.13.55"
5707         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5708         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5709                 skip "needs different host for mdt1 mdt2"
5710         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5711
5712         $LFS mkdir -i0 $DIR/$tdir
5713         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5714
5715         for d in sub1 sub2 sub3; do
5716                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5717                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5718                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5719         done
5720
5721         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5722 }
5723 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5724
5725 test_49() { # LU-1030
5726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5727         remote_ost_nodsh && skip "remote OST with nodsh"
5728
5729         # get ost1 size - $FSNAME-OST0000
5730         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5731                 awk '{ print $4 }')
5732         # write 800M at maximum
5733         [[ $ost1_size -lt 2 ]] && ost1_size=2
5734         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5735
5736         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5737         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5738         local dd_pid=$!
5739
5740         # change max_pages_per_rpc while writing the file
5741         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5742         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5743         # loop until dd process exits
5744         while ps ax -opid | grep -wq $dd_pid; do
5745                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5746                 sleep $((RANDOM % 5 + 1))
5747         done
5748         # restore original max_pages_per_rpc
5749         $LCTL set_param $osc1_mppc=$orig_mppc
5750         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5751 }
5752 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5753
5754 test_50() {
5755         # bug 1485
5756         test_mkdir $DIR/$tdir
5757         cd $DIR/$tdir
5758         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5759 }
5760 run_test 50 "special situations: /proc symlinks  ==============="
5761
5762 test_51a() {    # was test_51
5763         # bug 1516 - create an empty entry right after ".." then split dir
5764         test_mkdir -c1 $DIR/$tdir
5765         touch $DIR/$tdir/foo
5766         $MCREATE $DIR/$tdir/bar
5767         rm $DIR/$tdir/foo
5768         createmany -m $DIR/$tdir/longfile 201
5769         FNUM=202
5770         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5771                 $MCREATE $DIR/$tdir/longfile$FNUM
5772                 FNUM=$(($FNUM + 1))
5773                 echo -n "+"
5774         done
5775         echo
5776         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5777 }
5778 run_test 51a "special situations: split htree with empty entry =="
5779
5780 cleanup_print_lfs_df () {
5781         trap 0
5782         $LFS df
5783         $LFS df -i
5784 }
5785
5786 test_51b() {
5787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5788
5789         local dir=$DIR/$tdir
5790         local nrdirs=$((65536 + 100))
5791
5792         # cleanup the directory
5793         rm -fr $dir
5794
5795         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5796
5797         $LFS df
5798         $LFS df -i
5799         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5800         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5801         [[ $numfree -lt $nrdirs ]] &&
5802                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5803
5804         # need to check free space for the directories as well
5805         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5806         numfree=$(( blkfree / $(fs_inode_ksize) ))
5807         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5808
5809         trap cleanup_print_lfs_df EXIT
5810
5811         # create files
5812         createmany -d $dir/d $nrdirs || {
5813                 unlinkmany $dir/d $nrdirs
5814                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5815         }
5816
5817         # really created :
5818         nrdirs=$(ls -U $dir | wc -l)
5819
5820         # unlink all but 100 subdirectories, then check it still works
5821         local left=100
5822         local delete=$((nrdirs - left))
5823
5824         $LFS df
5825         $LFS df -i
5826
5827         # for ldiskfs the nlink count should be 1, but this is OSD specific
5828         # and so this is listed for informational purposes only
5829         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5830         unlinkmany -d $dir/d $delete ||
5831                 error "unlink of first $delete subdirs failed"
5832
5833         echo "nlink between: $(stat -c %h $dir)"
5834         local found=$(ls -U $dir | wc -l)
5835         [ $found -ne $left ] &&
5836                 error "can't find subdirs: found only $found, expected $left"
5837
5838         unlinkmany -d $dir/d $delete $left ||
5839                 error "unlink of second $left subdirs failed"
5840         # regardless of whether the backing filesystem tracks nlink accurately
5841         # or not, the nlink count shouldn't be more than "." and ".." here
5842         local after=$(stat -c %h $dir)
5843         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5844                 echo "nlink after: $after"
5845
5846         cleanup_print_lfs_df
5847 }
5848 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5849
5850 test_51d_sub() {
5851         local stripecount=$1
5852         local nfiles=$2
5853
5854         log "create files with stripecount=$stripecount"
5855         $LFS setstripe -C $stripecount $DIR/$tdir
5856         createmany -o $DIR/$tdir/t- $nfiles
5857         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5858         for ((n = 0; n < $OSTCOUNT; n++)); do
5859                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5860                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5861                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5862                             '($1 == '$n') { objs += 1 } \
5863                             END { printf("%0.0f", objs) }')
5864                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5865         done
5866         unlinkmany $DIR/$tdir/t- $nfiles
5867         rm  -f $TMP/$tfile
5868
5869         local nlast
5870         local min=4
5871         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5872
5873         # For some combinations of stripecount and OSTCOUNT current code
5874         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5875         # than others. Rather than skipping this test entirely, check that
5876         # and keep testing to ensure imbalance does not get worse. LU-15282
5877         (( (OSTCOUNT == 6 && stripecount == 4) ||
5878            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5879            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5880         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5881                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5882                         { $LFS df && $LFS df -i &&
5883                         error "stripecount=$stripecount: " \
5884                               "OST $n has fewer objects vs. OST $nlast " \
5885                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5886                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5887                         { $LFS df && $LFS df -i &&
5888                         error "stripecount=$stripecount: " \
5889                               "OST $n has more objects vs. OST $nlast " \
5890                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5891
5892                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5893                         { $LFS df && $LFS df -i &&
5894                         error "stripecount=$stripecount: " \
5895                               "OST $n has fewer #0 objects vs. OST $nlast " \
5896                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5897                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5898                         { $LFS df && $LFS df -i &&
5899                         error "stripecount=$stripecount: " \
5900                               "OST $n has more #0 objects vs. OST $nlast " \
5901                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5902         done
5903 }
5904
5905 test_51d() {
5906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5907         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5908
5909         local stripecount
5910         local per_ost=100
5911         local nfiles=$((per_ost * OSTCOUNT))
5912         local mdts=$(comma_list $(mdts_nodes))
5913         local param="osp.*.create_count"
5914         local qos_old=$(do_facet mds1 \
5915                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5916
5917         do_nodes $mdts \
5918                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5919         stack_trap "do_nodes $mdts \
5920                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5921
5922         test_mkdir $DIR/$tdir
5923         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5924         (( dirstripes > 0 )) || dirstripes=1
5925
5926         # Ensure enough OST objects precreated for tests to pass without
5927         # running out of objects.  This is an LOV r-r OST algorithm test,
5928         # not an OST object precreation test.
5929         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5930         (( old >= nfiles )) ||
5931         {
5932                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5933
5934                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5935                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5936
5937                 # trigger precreation from all MDTs for all OSTs
5938                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5939                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5940                 done
5941         }
5942
5943         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5944                 sleep 8  # allow object precreation to catch up
5945                 test_51d_sub $stripecount $nfiles
5946         done
5947 }
5948 run_test 51d "check LOV round-robin OST object distribution"
5949
5950 test_51e() {
5951         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5952                 skip_env "ldiskfs only test"
5953         fi
5954
5955         test_mkdir -c1 $DIR/$tdir
5956         test_mkdir -c1 $DIR/$tdir/d0
5957
5958         touch $DIR/$tdir/d0/foo
5959         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5960                 error "file exceed 65000 nlink limit!"
5961         unlinkmany $DIR/$tdir/d0/f- 65001
5962         return 0
5963 }
5964 run_test 51e "check file nlink limit"
5965
5966 test_51f() {
5967         test_mkdir $DIR/$tdir
5968
5969         local max=100000
5970         local ulimit_old=$(ulimit -n)
5971         local spare=20 # number of spare fd's for scripts/libraries, etc.
5972         local mdt=$($LFS getstripe -m $DIR/$tdir)
5973         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5974
5975         echo "MDT$mdt numfree=$numfree, max=$max"
5976         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5977         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5978                 while ! ulimit -n $((numfree + spare)); do
5979                         numfree=$((numfree * 3 / 4))
5980                 done
5981                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5982         else
5983                 echo "left ulimit at $ulimit_old"
5984         fi
5985
5986         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5987                 unlinkmany $DIR/$tdir/f $numfree
5988                 error "create+open $numfree files in $DIR/$tdir failed"
5989         }
5990         ulimit -n $ulimit_old
5991
5992         # if createmany exits at 120s there will be fewer than $numfree files
5993         unlinkmany $DIR/$tdir/f $numfree || true
5994 }
5995 run_test 51f "check many open files limit"
5996
5997 test_52a() {
5998         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5999         test_mkdir $DIR/$tdir
6000         touch $DIR/$tdir/foo
6001         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6002         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6003         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6004         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6005         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6006                                         error "link worked"
6007         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6008         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6009         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6010                                                      error "lsattr"
6011         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6012         cp -r $DIR/$tdir $TMP/
6013         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6014 }
6015 run_test 52a "append-only flag test (should return errors)"
6016
6017 test_52b() {
6018         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6019         test_mkdir $DIR/$tdir
6020         touch $DIR/$tdir/foo
6021         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6022         cat test > $DIR/$tdir/foo && error "cat test worked"
6023         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6024         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6025         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6026                                         error "link worked"
6027         echo foo >> $DIR/$tdir/foo && error "echo worked"
6028         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6029         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6030         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6031         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6032                                                         error "lsattr"
6033         chattr -i $DIR/$tdir/foo || error "chattr failed"
6034
6035         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6036 }
6037 run_test 52b "immutable flag test (should return errors) ======="
6038
6039 test_53() {
6040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6041         remote_mds_nodsh && skip "remote MDS with nodsh"
6042         remote_ost_nodsh && skip "remote OST with nodsh"
6043
6044         local param
6045         local param_seq
6046         local ostname
6047         local mds_last
6048         local mds_last_seq
6049         local ost_last
6050         local ost_last_seq
6051         local ost_last_id
6052         local ostnum
6053         local node
6054         local found=false
6055         local support_last_seq=true
6056
6057         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6058                 support_last_seq=false
6059
6060         # only test MDT0000
6061         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6062         local value
6063         for value in $(do_facet $SINGLEMDS \
6064                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6065                 param=$(echo ${value[0]} | cut -d "=" -f1)
6066                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6067
6068                 if $support_last_seq; then
6069                         param_seq=$(echo $param |
6070                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6071                         mds_last_seq=$(do_facet $SINGLEMDS \
6072                                        $LCTL get_param -n $param_seq)
6073                 fi
6074                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6075
6076                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6077                 node=$(facet_active_host ost$((ostnum+1)))
6078                 param="obdfilter.$ostname.last_id"
6079                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6080                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6081                         ost_last_id=$ost_last
6082
6083                         if $support_last_seq; then
6084                                 ost_last_id=$(echo $ost_last |
6085                                               awk -F':' '{print $2}' |
6086                                               sed -e "s/^0x//g")
6087                                 ost_last_seq=$(echo $ost_last |
6088                                                awk -F':' '{print $1}')
6089                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6090                         fi
6091
6092                         if [[ $ost_last_id != $mds_last ]]; then
6093                                 error "$ost_last_id != $mds_last"
6094                         else
6095                                 found=true
6096                                 break
6097                         fi
6098                 done
6099         done
6100         $found || error "can not match last_seq/last_id for $mdtosc"
6101         return 0
6102 }
6103 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6104
6105 test_54a() {
6106         perl -MSocket -e ';' || skip "no Socket perl module installed"
6107
6108         $SOCKETSERVER $DIR/socket ||
6109                 error "$SOCKETSERVER $DIR/socket failed: $?"
6110         $SOCKETCLIENT $DIR/socket ||
6111                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6112         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6113 }
6114 run_test 54a "unix domain socket test =========================="
6115
6116 test_54b() {
6117         f="$DIR/f54b"
6118         mknod $f c 1 3
6119         chmod 0666 $f
6120         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6121 }
6122 run_test 54b "char device works in lustre ======================"
6123
6124 find_loop_dev() {
6125         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6126         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6127         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6128
6129         for i in $(seq 3 7); do
6130                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6131                 LOOPDEV=$LOOPBASE$i
6132                 LOOPNUM=$i
6133                 break
6134         done
6135 }
6136
6137 cleanup_54c() {
6138         local rc=0
6139         loopdev="$DIR/loop54c"
6140
6141         trap 0
6142         $UMOUNT $DIR/$tdir || rc=$?
6143         losetup -d $loopdev || true
6144         losetup -d $LOOPDEV || true
6145         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6146         return $rc
6147 }
6148
6149 test_54c() {
6150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6151
6152         loopdev="$DIR/loop54c"
6153
6154         find_loop_dev
6155         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6156         trap cleanup_54c EXIT
6157         mknod $loopdev b 7 $LOOPNUM
6158         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6159         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6160         losetup $loopdev $DIR/$tfile ||
6161                 error "can't set up $loopdev for $DIR/$tfile"
6162         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6163         test_mkdir $DIR/$tdir
6164         mount -t ext2 $loopdev $DIR/$tdir ||
6165                 error "error mounting $loopdev on $DIR/$tdir"
6166         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6167                 error "dd write"
6168         df $DIR/$tdir
6169         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6170                 error "dd read"
6171         cleanup_54c
6172 }
6173 run_test 54c "block device works in lustre ====================="
6174
6175 test_54d() {
6176         local pipe="$DIR/$tfile.pipe"
6177         local string="aaaaaa"
6178
6179         mknod $pipe p
6180         echo -n "$string" > $pipe &
6181         local result=$(cat $pipe)
6182         [[ "$result" == "$string" ]] || error "$result != $string"
6183 }
6184 run_test 54d "fifo device works in lustre ======================"
6185
6186 test_54e() {
6187         f="$DIR/f54e"
6188         string="aaaaaa"
6189         cp -aL /dev/console $f
6190         echo $string > $f || error "echo $string to $f failed"
6191 }
6192 run_test 54e "console/tty device works in lustre ======================"
6193
6194 test_56a() {
6195         local numfiles=3
6196         local numdirs=2
6197         local dir=$DIR/$tdir
6198
6199         rm -rf $dir
6200         test_mkdir -p $dir/dir
6201         for i in $(seq $numfiles); do
6202                 touch $dir/file$i
6203                 touch $dir/dir/file$i
6204         done
6205
6206         local numcomp=$($LFS getstripe --component-count $dir)
6207
6208         [[ $numcomp == 0 ]] && numcomp=1
6209
6210         # test lfs getstripe with --recursive
6211         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6212
6213         [[ $filenum -eq $((numfiles * 2)) ]] ||
6214                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6215         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6216         [[ $filenum -eq $numfiles ]] ||
6217                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6218         echo "$LFS getstripe showed obdidx or l_ost_idx"
6219
6220         # test lfs getstripe with file instead of dir
6221         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6222         [[ $filenum -eq 1 ]] ||
6223                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6224         echo "$LFS getstripe file1 passed"
6225
6226         #test lfs getstripe with --verbose
6227         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6228         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6229                 error "$LFS getstripe --verbose $dir: "\
6230                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6231         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6232                 error "$LFS getstripe $dir: showed lmm_magic"
6233
6234         #test lfs getstripe with -v prints lmm_fid
6235         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6236         local countfids=$((numdirs + numfiles * numcomp))
6237         [[ $filenum -eq $countfids ]] ||
6238                 error "$LFS getstripe -v $dir: "\
6239                       "got $filenum want $countfids lmm_fid"
6240         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6241                 error "$LFS getstripe $dir: showed lmm_fid by default"
6242         echo "$LFS getstripe --verbose passed"
6243
6244         #check for FID information
6245         local fid1=$($LFS getstripe --fid $dir/file1)
6246         local fid2=$($LFS getstripe --verbose $dir/file1 |
6247                      awk '/lmm_fid: / { print $2; exit; }')
6248         local fid3=$($LFS path2fid $dir/file1)
6249
6250         [ "$fid1" != "$fid2" ] &&
6251                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6252         [ "$fid1" != "$fid3" ] &&
6253                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6254         echo "$LFS getstripe --fid passed"
6255
6256         #test lfs getstripe with --obd
6257         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6258                 error "$LFS getstripe --obd wrong_uuid: should return error"
6259
6260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6261
6262         local ostidx=1
6263         local obduuid=$(ostuuid_from_index $ostidx)
6264         local found=$($LFS getstripe -r --obd $obduuid $dir |
6265                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6266
6267         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6268         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6269                 ((filenum--))
6270         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6271                 ((filenum--))
6272
6273         [[ $found -eq $filenum ]] ||
6274                 error "$LFS getstripe --obd: found $found expect $filenum"
6275         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6276                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6277                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6278                 error "$LFS getstripe --obd: should not show file on other obd"
6279         echo "$LFS getstripe --obd passed"
6280 }
6281 run_test 56a "check $LFS getstripe"
6282
6283 test_56b() {
6284         local dir=$DIR/$tdir
6285         local numdirs=3
6286
6287         test_mkdir $dir
6288         for i in $(seq $numdirs); do
6289                 test_mkdir $dir/dir$i
6290         done
6291
6292         # test lfs getdirstripe default mode is non-recursion, which is
6293         # different from lfs getstripe
6294         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6295
6296         [[ $dircnt -eq 1 ]] ||
6297                 error "$LFS getdirstripe: found $dircnt, not 1"
6298         dircnt=$($LFS getdirstripe --recursive $dir |
6299                 grep -c lmv_stripe_count)
6300         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6301                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6302 }
6303 run_test 56b "check $LFS getdirstripe"
6304
6305 test_56c() {
6306         remote_ost_nodsh && skip "remote OST with nodsh"
6307
6308         local ost_idx=0
6309         local ost_name=$(ostname_from_index $ost_idx)
6310         local old_status=$(ost_dev_status $ost_idx)
6311         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6312
6313         [[ -z "$old_status" ]] ||
6314                 skip_env "OST $ost_name is in $old_status status"
6315
6316         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6317         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6318                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6319         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6320                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6321                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6322         fi
6323
6324         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6325                 error "$LFS df -v showing inactive devices"
6326         sleep_maxage
6327
6328         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6329
6330         [[ "$new_status" =~ "D" ]] ||
6331                 error "$ost_name status is '$new_status', missing 'D'"
6332         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6333                 [[ "$new_status" =~ "N" ]] ||
6334                         error "$ost_name status is '$new_status', missing 'N'"
6335         fi
6336         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6337                 [[ "$new_status" =~ "f" ]] ||
6338                         error "$ost_name status is '$new_status', missing 'f'"
6339         fi
6340
6341         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6342         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6343                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6344         [[ -z "$p" ]] && restore_lustre_params < $p || true
6345         sleep_maxage
6346
6347         new_status=$(ost_dev_status $ost_idx)
6348         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6349                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6350         # can't check 'f' as devices may actually be on flash
6351 }
6352 run_test 56c "check 'lfs df' showing device status"
6353
6354 test_56d() {
6355         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6356         local osts=$($LFS df -v $MOUNT | grep -c OST)
6357
6358         $LFS df $MOUNT
6359
6360         (( mdts == MDSCOUNT )) ||
6361                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6362         (( osts == OSTCOUNT )) ||
6363                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6364 }
6365 run_test 56d "'lfs df -v' prints only configured devices"
6366
6367 test_56e() {
6368         err_enoent=2 # No such file or directory
6369         err_eopnotsupp=95 # Operation not supported
6370
6371         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6372         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6373
6374         # Check for handling of path not exists
6375         output=$($LFS df $enoent_mnt 2>&1)
6376         ret=$?
6377
6378         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6379         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6380                 error "expect failure $err_enoent, not $ret"
6381
6382         # Check for handling of non-Lustre FS
6383         output=$($LFS df $notsup_mnt)
6384         ret=$?
6385
6386         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6387         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6388                 error "expect success $err_eopnotsupp, not $ret"
6389
6390         # Check for multiple LustreFS argument
6391         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6392         ret=$?
6393
6394         [[ $output -eq 3 && $ret -eq 0 ]] ||
6395                 error "expect success 3, not $output, rc = $ret"
6396
6397         # Check for correct non-Lustre FS handling among multiple
6398         # LustreFS argument
6399         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6400                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6401         ret=$?
6402
6403         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6404                 error "expect success 2, not $output, rc = $ret"
6405 }
6406 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6407
6408 NUMFILES=3
6409 NUMDIRS=3
6410 setup_56() {
6411         local local_tdir="$1"
6412         local local_numfiles="$2"
6413         local local_numdirs="$3"
6414         local dir_params="$4"
6415         local dir_stripe_params="$5"
6416
6417         if [ ! -d "$local_tdir" ] ; then
6418                 test_mkdir -p $dir_stripe_params $local_tdir
6419                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6420                 for i in $(seq $local_numfiles) ; do
6421                         touch $local_tdir/file$i
6422                 done
6423                 for i in $(seq $local_numdirs) ; do
6424                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6425                         for j in $(seq $local_numfiles) ; do
6426                                 touch $local_tdir/dir$i/file$j
6427                         done
6428                 done
6429         fi
6430 }
6431
6432 setup_56_special() {
6433         local local_tdir=$1
6434         local local_numfiles=$2
6435         local local_numdirs=$3
6436
6437         setup_56 $local_tdir $local_numfiles $local_numdirs
6438
6439         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6440                 for i in $(seq $local_numfiles) ; do
6441                         mknod $local_tdir/loop${i}b b 7 $i
6442                         mknod $local_tdir/null${i}c c 1 3
6443                         ln -s $local_tdir/file1 $local_tdir/link${i}
6444                 done
6445                 for i in $(seq $local_numdirs) ; do
6446                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6447                         mknod $local_tdir/dir$i/null${i}c c 1 3
6448                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6449                 done
6450         fi
6451 }
6452
6453 test_56g() {
6454         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6455         local expected=$(($NUMDIRS + 2))
6456
6457         setup_56 $dir $NUMFILES $NUMDIRS
6458
6459         # test lfs find with -name
6460         for i in $(seq $NUMFILES) ; do
6461                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6462
6463                 [ $nums -eq $expected ] ||
6464                         error "lfs find -name '*$i' $dir wrong: "\
6465                               "found $nums, expected $expected"
6466         done
6467 }
6468 run_test 56g "check lfs find -name"
6469
6470 test_56h() {
6471         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6472         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6473
6474         setup_56 $dir $NUMFILES $NUMDIRS
6475
6476         # test lfs find with ! -name
6477         for i in $(seq $NUMFILES) ; do
6478                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6479
6480                 [ $nums -eq $expected ] ||
6481                         error "lfs find ! -name '*$i' $dir wrong: "\
6482                               "found $nums, expected $expected"
6483         done
6484 }
6485 run_test 56h "check lfs find ! -name"
6486
6487 test_56i() {
6488         local dir=$DIR/$tdir
6489
6490         test_mkdir $dir
6491
6492         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6493         local out=$($cmd)
6494
6495         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6496 }
6497 run_test 56i "check 'lfs find -ost UUID' skips directories"
6498
6499 test_56j() {
6500         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6501
6502         setup_56_special $dir $NUMFILES $NUMDIRS
6503
6504         local expected=$((NUMDIRS + 1))
6505         local cmd="$LFS find -type d $dir"
6506         local nums=$($cmd | wc -l)
6507
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510 }
6511 run_test 56j "check lfs find -type d"
6512
6513 test_56k() {
6514         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6515
6516         setup_56_special $dir $NUMFILES $NUMDIRS
6517
6518         local expected=$(((NUMDIRS + 1) * NUMFILES))
6519         local cmd="$LFS find -type f $dir"
6520         local nums=$($cmd | wc -l)
6521
6522         [ $nums -eq $expected ] ||
6523                 error "'$cmd' wrong: found $nums, expected $expected"
6524 }
6525 run_test 56k "check lfs find -type f"
6526
6527 test_56l() {
6528         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6529
6530         setup_56_special $dir $NUMFILES $NUMDIRS
6531
6532         local expected=$((NUMDIRS + NUMFILES))
6533         local cmd="$LFS find -type b $dir"
6534         local nums=$($cmd | wc -l)
6535
6536         [ $nums -eq $expected ] ||
6537                 error "'$cmd' wrong: found $nums, expected $expected"
6538 }
6539 run_test 56l "check lfs find -type b"
6540
6541 test_56m() {
6542         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6543
6544         setup_56_special $dir $NUMFILES $NUMDIRS
6545
6546         local expected=$((NUMDIRS + NUMFILES))
6547         local cmd="$LFS find -type c $dir"
6548         local nums=$($cmd | wc -l)
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551 }
6552 run_test 56m "check lfs find -type c"
6553
6554 test_56n() {
6555         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6556         setup_56_special $dir $NUMFILES $NUMDIRS
6557
6558         local expected=$((NUMDIRS + NUMFILES))
6559         local cmd="$LFS find -type l $dir"
6560         local nums=$($cmd | wc -l)
6561
6562         [ $nums -eq $expected ] ||
6563                 error "'$cmd' wrong: found $nums, expected $expected"
6564 }
6565 run_test 56n "check lfs find -type l"
6566
6567 test_56o() {
6568         local dir=$DIR/$tdir
6569
6570         setup_56 $dir $NUMFILES $NUMDIRS
6571         utime $dir/file1 > /dev/null || error "utime (1)"
6572         utime $dir/file2 > /dev/null || error "utime (2)"
6573         utime $dir/dir1 > /dev/null || error "utime (3)"
6574         utime $dir/dir2 > /dev/null || error "utime (4)"
6575         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6576         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6577
6578         local expected=4
6579         local nums=$($LFS find -mtime +0 $dir | wc -l)
6580
6581         [ $nums -eq $expected ] ||
6582                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6583
6584         expected=12
6585         cmd="$LFS find -mtime 0 $dir"
6586         nums=$($cmd | wc -l)
6587         [ $nums -eq $expected ] ||
6588                 error "'$cmd' wrong: found $nums, expected $expected"
6589 }
6590 run_test 56o "check lfs find -mtime for old files"
6591
6592 test_56ob() {
6593         local dir=$DIR/$tdir
6594         local expected=1
6595         local count=0
6596
6597         # just to make sure there is something that won't be found
6598         test_mkdir $dir
6599         touch $dir/$tfile.now
6600
6601         for age in year week day hour min; do
6602                 count=$((count + 1))
6603
6604                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6605                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6606                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6607
6608                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6609                 local nums=$($cmd | wc -l)
6610                 [ $nums -eq $expected ] ||
6611                         error "'$cmd' wrong: found $nums, expected $expected"
6612
6613                 cmd="$LFS find $dir -atime $count${age:0:1}"
6614                 nums=$($cmd | wc -l)
6615                 [ $nums -eq $expected ] ||
6616                         error "'$cmd' wrong: found $nums, expected $expected"
6617         done
6618
6619         sleep 2
6620         cmd="$LFS find $dir -ctime +1s -type f"
6621         nums=$($cmd | wc -l)
6622         (( $nums == $count * 2 + 1)) ||
6623                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6624 }
6625 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6626
6627 test_newerXY_base() {
6628         local x=$1
6629         local y=$2
6630         local dir=$DIR/$tdir
6631         local ref
6632         local negref
6633
6634         if [ $y == "t" ]; then
6635                 if [ $x == "b" ]; then
6636                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6637                 else
6638                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6639                 fi
6640         else
6641                 ref=$DIR/$tfile.newer.$x$y
6642                 touch $ref || error "touch $ref failed"
6643         fi
6644
6645         echo "before = $ref"
6646         sleep 2
6647         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6648         sleep 2
6649         if [ $y == "t" ]; then
6650                 if [ $x == "b" ]; then
6651                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6652                 else
6653                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6654                 fi
6655         else
6656                 negref=$DIR/$tfile.negnewer.$x$y
6657                 touch $negref || error "touch $negref failed"
6658         fi
6659
6660         echo "after = $negref"
6661         local cmd="$LFS find $dir -newer$x$y $ref"
6662         local nums=$(eval $cmd | wc -l)
6663         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6664
6665         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6666                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6667
6668         cmd="$LFS find $dir ! -newer$x$y $negref"
6669         nums=$(eval $cmd | wc -l)
6670         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6671                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6672
6673         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6674         nums=$(eval $cmd | wc -l)
6675         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6676                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6677
6678         rm -rf $DIR/*
6679 }
6680
6681 test_56oc() {
6682         test_newerXY_base "a" "a"
6683         test_newerXY_base "a" "m"
6684         test_newerXY_base "a" "c"
6685         test_newerXY_base "m" "a"
6686         test_newerXY_base "m" "m"
6687         test_newerXY_base "m" "c"
6688         test_newerXY_base "c" "a"
6689         test_newerXY_base "c" "m"
6690         test_newerXY_base "c" "c"
6691
6692         [[ -n "$sles_version" ]] &&
6693                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6694
6695         test_newerXY_base "a" "t"
6696         test_newerXY_base "m" "t"
6697         test_newerXY_base "c" "t"
6698
6699         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6700            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6701                 ! btime_supported && echo "btime unsupported" && return 0
6702
6703         test_newerXY_base "b" "b"
6704         test_newerXY_base "b" "t"
6705 }
6706 run_test 56oc "check lfs find -newerXY work"
6707
6708 btime_supported() {
6709         local dir=$DIR/$tdir
6710         local rc
6711
6712         mkdir -p $dir
6713         touch $dir/$tfile
6714         $LFS find $dir -btime -1d -type f
6715         rc=$?
6716         rm -rf $dir
6717         return $rc
6718 }
6719
6720 test_56od() {
6721         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6722                 ! btime_supported && skip "btime unsupported on MDS"
6723
6724         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6725                 ! btime_supported && skip "btime unsupported on clients"
6726
6727         local dir=$DIR/$tdir
6728         local ref=$DIR/$tfile.ref
6729         local negref=$DIR/$tfile.negref
6730
6731         mkdir $dir || error "mkdir $dir failed"
6732         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6733         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6734         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6735         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6736         touch $ref || error "touch $ref failed"
6737         # sleep 3 seconds at least
6738         sleep 3
6739
6740         local before=$(do_facet mds1 date +%s)
6741         local skew=$(($(date +%s) - before + 1))
6742
6743         if (( skew < 0 && skew > -5 )); then
6744                 sleep $((0 - skew + 1))
6745                 skew=0
6746         fi
6747
6748         # Set the dir stripe params to limit files all on MDT0,
6749         # otherwise we need to calc the max clock skew between
6750         # the client and MDTs.
6751         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6752         sleep 2
6753         touch $negref || error "touch $negref failed"
6754
6755         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6756         local nums=$($cmd | wc -l)
6757         local expected=$(((NUMFILES + 1) * NUMDIRS))
6758
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6763         nums=$($cmd | wc -l)
6764         expected=$((NUMFILES + 1))
6765         [ $nums -eq $expected ] ||
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767
6768         [ $skew -lt 0 ] && return
6769
6770         local after=$(do_facet mds1 date +%s)
6771         local age=$((after - before + 1 + skew))
6772
6773         cmd="$LFS find $dir -btime -${age}s -type f"
6774         nums=$($cmd | wc -l)
6775         expected=$(((NUMFILES + 1) * NUMDIRS))
6776
6777         echo "Clock skew between client and server: $skew, age:$age"
6778         [ $nums -eq $expected ] ||
6779                 error "'$cmd' wrong: found $nums, expected $expected"
6780
6781         expected=$(($NUMDIRS + 1))
6782         cmd="$LFS find $dir -btime -${age}s -type d"
6783         nums=$($cmd | wc -l)
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786         rm -f $ref $negref || error "Failed to remove $ref $negref"
6787 }
6788 run_test 56od "check lfs find -btime with units"
6789
6790 test_56p() {
6791         [ $RUNAS_ID -eq $UID ] &&
6792                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6793
6794         local dir=$DIR/$tdir
6795
6796         setup_56 $dir $NUMFILES $NUMDIRS
6797         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6798
6799         local expected=$NUMFILES
6800         local cmd="$LFS find -uid $RUNAS_ID $dir"
6801         local nums=$($cmd | wc -l)
6802
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805
6806         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6807         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6808         nums=$($cmd | wc -l)
6809         [ $nums -eq $expected ] ||
6810                 error "'$cmd' wrong: found $nums, expected $expected"
6811 }
6812 run_test 56p "check lfs find -uid and ! -uid"
6813
6814 test_56q() {
6815         [ $RUNAS_ID -eq $UID ] &&
6816                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6817
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS
6821         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6822
6823         local expected=$NUMFILES
6824         local cmd="$LFS find -gid $RUNAS_GID $dir"
6825         local nums=$($cmd | wc -l)
6826
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829
6830         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6831         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6832         nums=$($cmd | wc -l)
6833         [ $nums -eq $expected ] ||
6834                 error "'$cmd' wrong: found $nums, expected $expected"
6835 }
6836 run_test 56q "check lfs find -gid and ! -gid"
6837
6838 test_56r() {
6839         local dir=$DIR/$tdir
6840
6841         setup_56 $dir $NUMFILES $NUMDIRS
6842
6843         local expected=12
6844         local cmd="$LFS find -size 0 -type f -lazy $dir"
6845         local nums=$($cmd | wc -l)
6846
6847         [ $nums -eq $expected ] ||
6848                 error "'$cmd' wrong: found $nums, expected $expected"
6849         cmd="$LFS find -size 0 -type f $dir"
6850         nums=$($cmd | wc -l)
6851         [ $nums -eq $expected ] ||
6852                 error "'$cmd' wrong: found $nums, expected $expected"
6853
6854         expected=0
6855         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6856         nums=$($cmd | wc -l)
6857         [ $nums -eq $expected ] ||
6858                 error "'$cmd' wrong: found $nums, expected $expected"
6859         cmd="$LFS find ! -size 0 -type f $dir"
6860         nums=$($cmd | wc -l)
6861         [ $nums -eq $expected ] ||
6862                 error "'$cmd' wrong: found $nums, expected $expected"
6863
6864         echo "test" > $dir/$tfile
6865         echo "test2" > $dir/$tfile.2 && sync
6866         expected=1
6867         cmd="$LFS find -size 5 -type f -lazy $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871         cmd="$LFS find -size 5 -type f $dir"
6872         nums=$($cmd | wc -l)
6873         [ $nums -eq $expected ] ||
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875
6876         expected=1
6877         cmd="$LFS find -size +5 -type f -lazy $dir"
6878         nums=$($cmd | wc -l)
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881         cmd="$LFS find -size +5 -type f $dir"
6882         nums=$($cmd | wc -l)
6883         [ $nums -eq $expected ] ||
6884                 error "'$cmd' wrong: found $nums, expected $expected"
6885
6886         expected=2
6887         cmd="$LFS find -size +0 -type f -lazy $dir"
6888         nums=$($cmd | wc -l)
6889         [ $nums -eq $expected ] ||
6890                 error "'$cmd' wrong: found $nums, expected $expected"
6891         cmd="$LFS find -size +0 -type f $dir"
6892         nums=$($cmd | wc -l)
6893         [ $nums -eq $expected ] ||
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895
6896         expected=2
6897         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] ||
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901         cmd="$LFS find ! -size -5 -type f $dir"
6902         nums=$($cmd | wc -l)
6903         [ $nums -eq $expected ] ||
6904                 error "'$cmd' wrong: found $nums, expected $expected"
6905
6906         expected=12
6907         cmd="$LFS find -size -5 -type f -lazy $dir"
6908         nums=$($cmd | wc -l)
6909         [ $nums -eq $expected ] ||
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911         cmd="$LFS find -size -5 -type f $dir"
6912         nums=$($cmd | wc -l)
6913         [ $nums -eq $expected ] ||
6914                 error "'$cmd' wrong: found $nums, expected $expected"
6915 }
6916 run_test 56r "check lfs find -size works"
6917
6918 test_56ra_sub() {
6919         local expected=$1
6920         local glimpses=$2
6921         local cmd="$3"
6922
6923         cancel_lru_locks $OSC
6924
6925         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6926         local nums=$($cmd | wc -l)
6927
6928         [ $nums -eq $expected ] ||
6929                 error "'$cmd' wrong: found $nums, expected $expected"
6930
6931         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6932
6933         if (( rpcs_before + glimpses != rpcs_after )); then
6934                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6935                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6936
6937                 if [[ $glimpses == 0 ]]; then
6938                         error "'$cmd' should not send glimpse RPCs to OST"
6939                 else
6940                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6941                 fi
6942         fi
6943 }
6944
6945 test_56ra() {
6946         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6947                 skip "MDS < 2.12.58 doesn't return LSOM data"
6948         local dir=$DIR/$tdir
6949         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6950
6951         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6952
6953         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6954         $LCTL set_param -n llite.*.statahead_agl=0
6955         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6956
6957         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6958         # open and close all files to ensure LSOM is updated
6959         cancel_lru_locks $OSC
6960         find $dir -type f | xargs cat > /dev/null
6961
6962         #   expect_found  glimpse_rpcs  command_to_run
6963         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6964         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6965         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6966         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6967
6968         echo "test" > $dir/$tfile
6969         echo "test2" > $dir/$tfile.2 && sync
6970         cancel_lru_locks $OSC
6971         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6972
6973         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6974         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6975         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6976         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6977
6978         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6979         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6980         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6981         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6982         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6983         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6984 }
6985 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6986
6987 test_56rb() {
6988         local dir=$DIR/$tdir
6989         local tmp=$TMP/$tfile.log
6990         local mdt_idx;
6991
6992         test_mkdir -p $dir || error "failed to mkdir $dir"
6993         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6994                 error "failed to setstripe $dir/$tfile"
6995         mdt_idx=$($LFS getdirstripe -i $dir)
6996         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6997
6998         stack_trap "rm -f $tmp" EXIT
6999         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7000         ! grep -q obd_uuid $tmp ||
7001                 error "failed to find --size +100K --ost 0 $dir"
7002         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7003         ! grep -q obd_uuid $tmp ||
7004                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7005 }
7006 run_test 56rb "check lfs find --size --ost/--mdt works"
7007
7008 test_56rc() {
7009         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7010         local dir=$DIR/$tdir
7011         local found
7012
7013         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7014         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7015         (( $MDSCOUNT > 2 )) &&
7016                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7017         mkdir $dir/$tdir-{1..10}
7018         touch $dir/$tfile-{1..10}
7019
7020         found=$($LFS find $dir --mdt-count 2 | wc -l)
7021         expect=11
7022         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7023
7024         found=$($LFS find $dir -T +1 | wc -l)
7025         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7026         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7027
7028         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7029         expect=11
7030         (( $found == $expect )) || error "found $found all_char, expect $expect"
7031
7032         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7033         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7034         (( $found == $expect )) || error "found $found all_char, expect $expect"
7035 }
7036 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7037
7038 test_56s() { # LU-611 #LU-9369
7039         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7040
7041         local dir=$DIR/$tdir
7042         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7043
7044         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7045         for i in $(seq $NUMDIRS); do
7046                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7047         done
7048
7049         local expected=$NUMDIRS
7050         local cmd="$LFS find -c $OSTCOUNT $dir"
7051         local nums=$($cmd | wc -l)
7052
7053         [ $nums -eq $expected ] || {
7054                 $LFS getstripe -R $dir
7055                 error "'$cmd' wrong: found $nums, expected $expected"
7056         }
7057
7058         expected=$((NUMDIRS + onestripe))
7059         cmd="$LFS find -stripe-count +0 -type f $dir"
7060         nums=$($cmd | wc -l)
7061         [ $nums -eq $expected ] || {
7062                 $LFS getstripe -R $dir
7063                 error "'$cmd' wrong: found $nums, expected $expected"
7064         }
7065
7066         expected=$onestripe
7067         cmd="$LFS find -stripe-count 1 -type f $dir"
7068         nums=$($cmd | wc -l)
7069         [ $nums -eq $expected ] || {
7070                 $LFS getstripe -R $dir
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072         }
7073
7074         cmd="$LFS find -stripe-count -2 -type f $dir"
7075         nums=$($cmd | wc -l)
7076         [ $nums -eq $expected ] || {
7077                 $LFS getstripe -R $dir
7078                 error "'$cmd' wrong: found $nums, expected $expected"
7079         }
7080
7081         expected=0
7082         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7083         nums=$($cmd | wc -l)
7084         [ $nums -eq $expected ] || {
7085                 $LFS getstripe -R $dir
7086                 error "'$cmd' wrong: found $nums, expected $expected"
7087         }
7088 }
7089 run_test 56s "check lfs find -stripe-count works"
7090
7091 test_56t() { # LU-611 #LU-9369
7092         local dir=$DIR/$tdir
7093
7094         setup_56 $dir 0 $NUMDIRS
7095         for i in $(seq $NUMDIRS); do
7096                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7097         done
7098
7099         local expected=$NUMDIRS
7100         local cmd="$LFS find -S 8M $dir"
7101         local nums=$($cmd | wc -l)
7102
7103         [ $nums -eq $expected ] || {
7104                 $LFS getstripe -R $dir
7105                 error "'$cmd' wrong: found $nums, expected $expected"
7106         }
7107         rm -rf $dir
7108
7109         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7110
7111         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7112
7113         expected=$(((NUMDIRS + 1) * NUMFILES))
7114         cmd="$LFS find -stripe-size 512k -type f $dir"
7115         nums=$($cmd | wc -l)
7116         [ $nums -eq $expected ] ||
7117                 error "'$cmd' wrong: found $nums, expected $expected"
7118
7119         cmd="$LFS find -stripe-size +320k -type f $dir"
7120         nums=$($cmd | wc -l)
7121         [ $nums -eq $expected ] ||
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123
7124         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7125         cmd="$LFS find -stripe-size +200k -type f $dir"
7126         nums=$($cmd | wc -l)
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129
7130         cmd="$LFS find -stripe-size -640k -type f $dir"
7131         nums=$($cmd | wc -l)
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134
7135         expected=4
7136         cmd="$LFS find -stripe-size 256k -type f $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140
7141         cmd="$LFS find -stripe-size -320k -type f $dir"
7142         nums=$($cmd | wc -l)
7143         [ $nums -eq $expected ] ||
7144                 error "'$cmd' wrong: found $nums, expected $expected"
7145
7146         expected=0
7147         cmd="$LFS find -stripe-size 1024k -type f $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151 }
7152 run_test 56t "check lfs find -stripe-size works"
7153
7154 test_56u() { # LU-611
7155         local dir=$DIR/$tdir
7156
7157         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7158
7159         if [[ $OSTCOUNT -gt 1 ]]; then
7160                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7161                 onestripe=4
7162         else
7163                 onestripe=0
7164         fi
7165
7166         local expected=$(((NUMDIRS + 1) * NUMFILES))
7167         local cmd="$LFS find -stripe-index 0 -type f $dir"
7168         local nums=$($cmd | wc -l)
7169
7170         [ $nums -eq $expected ] ||
7171                 error "'$cmd' wrong: found $nums, expected $expected"
7172
7173         expected=$onestripe
7174         cmd="$LFS find -stripe-index 1 -type f $dir"
7175         nums=$($cmd | wc -l)
7176         [ $nums -eq $expected ] ||
7177                 error "'$cmd' wrong: found $nums, expected $expected"
7178
7179         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7180         nums=$($cmd | wc -l)
7181         [ $nums -eq $expected ] ||
7182                 error "'$cmd' wrong: found $nums, expected $expected"
7183
7184         expected=0
7185         # This should produce an error and not return any files
7186         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7187         nums=$($cmd 2>/dev/null | wc -l)
7188         [ $nums -eq $expected ] ||
7189                 error "'$cmd' wrong: found $nums, expected $expected"
7190
7191         if [[ $OSTCOUNT -gt 1 ]]; then
7192                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7193                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7194                 nums=$($cmd | wc -l)
7195                 [ $nums -eq $expected ] ||
7196                         error "'$cmd' wrong: found $nums, expected $expected"
7197         fi
7198 }
7199 run_test 56u "check lfs find -stripe-index works"
7200
7201 test_56v() {
7202         local mdt_idx=0
7203         local dir=$DIR/$tdir
7204
7205         setup_56 $dir $NUMFILES $NUMDIRS
7206
7207         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7208         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7209
7210         for file in $($LFS find -m $UUID $dir); do
7211                 file_midx=$($LFS getstripe -m $file)
7212                 [ $file_midx -eq $mdt_idx ] ||
7213                         error "lfs find -m $UUID != getstripe -m $file_midx"
7214         done
7215 }
7216 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7217
7218 test_56w() {
7219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7221
7222         local dir=$DIR/$tdir
7223
7224         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7225
7226         local stripe_size=$($LFS getstripe -S -d $dir) ||
7227                 error "$LFS getstripe -S -d $dir failed"
7228         stripe_size=${stripe_size%% *}
7229
7230         local file_size=$((stripe_size * OSTCOUNT))
7231         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7232         local required_space=$((file_num * file_size))
7233         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7234                            head -n1)
7235         [[ $free_space -le $((required_space / 1024)) ]] &&
7236                 skip_env "need $required_space, have $free_space kbytes"
7237
7238         local dd_bs=65536
7239         local dd_count=$((file_size / dd_bs))
7240
7241         # write data into the files
7242         local i
7243         local j
7244         local file
7245
7246         for i in $(seq $NUMFILES); do
7247                 file=$dir/file$i
7248                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7249                         error "write data into $file failed"
7250         done
7251         for i in $(seq $NUMDIRS); do
7252                 for j in $(seq $NUMFILES); do
7253                         file=$dir/dir$i/file$j
7254                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7255                                 error "write data into $file failed"
7256                 done
7257         done
7258
7259         # $LFS_MIGRATE will fail if hard link migration is unsupported
7260         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7261                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7262                         error "creating links to $dir/dir1/file1 failed"
7263         fi
7264
7265         local expected=-1
7266
7267         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7268
7269         # lfs_migrate file
7270         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7271
7272         echo "$cmd"
7273         eval $cmd || error "$cmd failed"
7274
7275         check_stripe_count $dir/file1 $expected
7276
7277         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7278         then
7279                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7280                 # OST 1 if it is on OST 0. This file is small enough to
7281                 # be on only one stripe.
7282                 file=$dir/migr_1_ost
7283                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7284                         error "write data into $file failed"
7285                 local obdidx=$($LFS getstripe -i $file)
7286                 local oldmd5=$(md5sum $file)
7287                 local newobdidx=0
7288
7289                 [[ $obdidx -eq 0 ]] && newobdidx=1
7290                 cmd="$LFS migrate -i $newobdidx $file"
7291                 echo $cmd
7292                 eval $cmd || error "$cmd failed"
7293
7294                 local realobdix=$($LFS getstripe -i $file)
7295                 local newmd5=$(md5sum $file)
7296
7297                 [[ $newobdidx -ne $realobdix ]] &&
7298                         error "new OST is different (was=$obdidx, "\
7299                               "wanted=$newobdidx, got=$realobdix)"
7300                 [[ "$oldmd5" != "$newmd5" ]] &&
7301                         error "md5sum differ: $oldmd5, $newmd5"
7302         fi
7303
7304         # lfs_migrate dir
7305         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7306         echo "$cmd"
7307         eval $cmd || error "$cmd failed"
7308
7309         for j in $(seq $NUMFILES); do
7310                 check_stripe_count $dir/dir1/file$j $expected
7311         done
7312
7313         # lfs_migrate works with lfs find
7314         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7315              $LFS_MIGRATE -y -c $expected"
7316         echo "$cmd"
7317         eval $cmd || error "$cmd failed"
7318
7319         for i in $(seq 2 $NUMFILES); do
7320                 check_stripe_count $dir/file$i $expected
7321         done
7322         for i in $(seq 2 $NUMDIRS); do
7323                 for j in $(seq $NUMFILES); do
7324                 check_stripe_count $dir/dir$i/file$j $expected
7325                 done
7326         done
7327 }
7328 run_test 56w "check lfs_migrate -c stripe_count works"
7329
7330 test_56wb() {
7331         local file1=$DIR/$tdir/file1
7332         local create_pool=false
7333         local initial_pool=$($LFS getstripe -p $DIR)
7334         local pool_list=()
7335         local pool=""
7336
7337         echo -n "Creating test dir..."
7338         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7339         echo "done."
7340
7341         echo -n "Creating test file..."
7342         touch $file1 || error "cannot create file"
7343         echo "done."
7344
7345         echo -n "Detecting existing pools..."
7346         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7347
7348         if [ ${#pool_list[@]} -gt 0 ]; then
7349                 echo "${pool_list[@]}"
7350                 for thispool in "${pool_list[@]}"; do
7351                         if [[ -z "$initial_pool" ||
7352                               "$initial_pool" != "$thispool" ]]; then
7353                                 pool="$thispool"
7354                                 echo "Using existing pool '$pool'"
7355                                 break
7356                         fi
7357                 done
7358         else
7359                 echo "none detected."
7360         fi
7361         if [ -z "$pool" ]; then
7362                 pool=${POOL:-testpool}
7363                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7364                 echo -n "Creating pool '$pool'..."
7365                 create_pool=true
7366                 pool_add $pool &> /dev/null ||
7367                         error "pool_add failed"
7368                 echo "done."
7369
7370                 echo -n "Adding target to pool..."
7371                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7372                         error "pool_add_targets failed"
7373                 echo "done."
7374         fi
7375
7376         echo -n "Setting pool using -p option..."
7377         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7378                 error "migrate failed rc = $?"
7379         echo "done."
7380
7381         echo -n "Verifying test file is in pool after migrating..."
7382         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7383                 error "file was not migrated to pool $pool"
7384         echo "done."
7385
7386         echo -n "Removing test file from pool '$pool'..."
7387         # "lfs migrate $file" won't remove the file from the pool
7388         # until some striping information is changed.
7389         $LFS migrate -c 1 $file1 &> /dev/null ||
7390                 error "cannot remove from pool"
7391         [ "$($LFS getstripe -p $file1)" ] &&
7392                 error "pool still set"
7393         echo "done."
7394
7395         echo -n "Setting pool using --pool option..."
7396         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7397                 error "migrate failed rc = $?"
7398         echo "done."
7399
7400         # Clean up
7401         rm -f $file1
7402         if $create_pool; then
7403                 destroy_test_pools 2> /dev/null ||
7404                         error "destroy test pools failed"
7405         fi
7406 }
7407 run_test 56wb "check lfs_migrate pool support"
7408
7409 test_56wc() {
7410         local file1="$DIR/$tdir/file1"
7411         local parent_ssize
7412         local parent_scount
7413         local cur_ssize
7414         local cur_scount
7415         local orig_ssize
7416
7417         echo -n "Creating test dir..."
7418         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7419         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7420                 error "cannot set stripe by '-S 1M -c 1'"
7421         echo "done"
7422
7423         echo -n "Setting initial stripe for test file..."
7424         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7425                 error "cannot set stripe"
7426         cur_ssize=$($LFS getstripe -S "$file1")
7427         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7428         echo "done."
7429
7430         # File currently set to -S 512K -c 1
7431
7432         # Ensure -c and -S options are rejected when -R is set
7433         echo -n "Verifying incompatible options are detected..."
7434         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7435                 error "incompatible -c and -R options not detected"
7436         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7437                 error "incompatible -S and -R options not detected"
7438         echo "done."
7439
7440         # Ensure unrecognized options are passed through to 'lfs migrate'
7441         echo -n "Verifying -S option is passed through to lfs migrate..."
7442         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7443                 error "migration failed"
7444         cur_ssize=$($LFS getstripe -S "$file1")
7445         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7446         echo "done."
7447
7448         # File currently set to -S 1M -c 1
7449
7450         # Ensure long options are supported
7451         echo -n "Verifying long options supported..."
7452         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7453                 error "long option without argument not supported"
7454         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7455                 error "long option with argument not supported"
7456         cur_ssize=$($LFS getstripe -S "$file1")
7457         [ $cur_ssize -eq 524288 ] ||
7458                 error "migrate --stripe-size $cur_ssize != 524288"
7459         echo "done."
7460
7461         # File currently set to -S 512K -c 1
7462
7463         if [ "$OSTCOUNT" -gt 1 ]; then
7464                 echo -n "Verifying explicit stripe count can be set..."
7465                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7466                         error "migrate failed"
7467                 cur_scount=$($LFS getstripe -c "$file1")
7468                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7469                 echo "done."
7470         fi
7471
7472         # File currently set to -S 512K -c 1 or -S 512K -c 2
7473
7474         # Ensure parent striping is used if -R is set, and no stripe
7475         # count or size is specified
7476         echo -n "Setting stripe for parent directory..."
7477         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7478                 error "cannot set stripe '-S 2M -c 1'"
7479         echo "done."
7480
7481         echo -n "Verifying restripe option uses parent stripe settings..."
7482         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7483         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7484         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7485                 error "migrate failed"
7486         cur_ssize=$($LFS getstripe -S "$file1")
7487         [ $cur_ssize -eq $parent_ssize ] ||
7488                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7489         cur_scount=$($LFS getstripe -c "$file1")
7490         [ $cur_scount -eq $parent_scount ] ||
7491                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7492         echo "done."
7493
7494         # File currently set to -S 1M -c 1
7495
7496         # Ensure striping is preserved if -R is not set, and no stripe
7497         # count or size is specified
7498         echo -n "Verifying striping size preserved when not specified..."
7499         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7500         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7501                 error "cannot set stripe on parent directory"
7502         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7503                 error "migrate failed"
7504         cur_ssize=$($LFS getstripe -S "$file1")
7505         [ $cur_ssize -eq $orig_ssize ] ||
7506                 error "migrate by default $cur_ssize != $orig_ssize"
7507         echo "done."
7508
7509         # Ensure file name properly detected when final option has no argument
7510         echo -n "Verifying file name properly detected..."
7511         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7512                 error "file name interpreted as option argument"
7513         echo "done."
7514
7515         # Clean up
7516         rm -f "$file1"
7517 }
7518 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7519
7520 test_56wd() {
7521         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7522
7523         local file1=$DIR/$tdir/file1
7524
7525         echo -n "Creating test dir..."
7526         test_mkdir $DIR/$tdir || error "cannot create dir"
7527         echo "done."
7528
7529         echo -n "Creating test file..."
7530         touch $file1
7531         echo "done."
7532
7533         # Ensure 'lfs migrate' will fail by using a non-existent option,
7534         # and make sure rsync is not called to recover
7535         echo -n "Make sure --no-rsync option works..."
7536         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7537                 grep -q 'refusing to fall back to rsync' ||
7538                 error "rsync was called with --no-rsync set"
7539         echo "done."
7540
7541         # Ensure rsync is called without trying 'lfs migrate' first
7542         echo -n "Make sure --rsync option works..."
7543         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7544                 grep -q 'falling back to rsync' &&
7545                 error "lfs migrate was called with --rsync set"
7546         echo "done."
7547
7548         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7549         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7550                 grep -q 'at the same time' ||
7551                 error "--rsync and --no-rsync accepted concurrently"
7552         echo "done."
7553
7554         # Clean up
7555         rm -f $file1
7556 }
7557 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7558
7559 test_56we() {
7560         local td=$DIR/$tdir
7561         local tf=$td/$tfile
7562
7563         test_mkdir $td || error "cannot create $td"
7564         touch $tf || error "cannot touch $tf"
7565
7566         echo -n "Make sure --non-direct|-D works..."
7567         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7568                 grep -q "lfs migrate --non-direct" ||
7569                 error "--non-direct option cannot work correctly"
7570         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7571                 grep -q "lfs migrate -D" ||
7572                 error "-D option cannot work correctly"
7573         echo "done."
7574 }
7575 run_test 56we "check lfs_migrate --non-direct|-D support"
7576
7577 test_56x() {
7578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7579         check_swap_layouts_support
7580
7581         local dir=$DIR/$tdir
7582         local ref1=/etc/passwd
7583         local file1=$dir/file1
7584
7585         test_mkdir $dir || error "creating dir $dir"
7586         $LFS setstripe -c 2 $file1
7587         cp $ref1 $file1
7588         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7589         stripe=$($LFS getstripe -c $file1)
7590         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7591         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7592
7593         # clean up
7594         rm -f $file1
7595 }
7596 run_test 56x "lfs migration support"
7597
7598 test_56xa() {
7599         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7600         check_swap_layouts_support
7601
7602         local dir=$DIR/$tdir/$testnum
7603
7604         test_mkdir -p $dir
7605
7606         local ref1=/etc/passwd
7607         local file1=$dir/file1
7608
7609         $LFS setstripe -c 2 $file1
7610         cp $ref1 $file1
7611         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7612
7613         local stripe=$($LFS getstripe -c $file1)
7614
7615         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7616         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7617
7618         # clean up
7619         rm -f $file1
7620 }
7621 run_test 56xa "lfs migration --block support"
7622
7623 check_migrate_links() {
7624         local dir="$1"
7625         local file1="$dir/file1"
7626         local begin="$2"
7627         local count="$3"
7628         local runas="$4"
7629         local total_count=$(($begin + $count - 1))
7630         local symlink_count=10
7631         local uniq_count=10
7632
7633         if [ ! -f "$file1" ]; then
7634                 echo -n "creating initial file..."
7635                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7636                         error "cannot setstripe initial file"
7637                 echo "done"
7638
7639                 echo -n "creating symlinks..."
7640                 for s in $(seq 1 $symlink_count); do
7641                         ln -s "$file1" "$dir/slink$s" ||
7642                                 error "cannot create symlinks"
7643                 done
7644                 echo "done"
7645
7646                 echo -n "creating nonlinked files..."
7647                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7648                         error "cannot create nonlinked files"
7649                 echo "done"
7650         fi
7651
7652         # create hard links
7653         if [ ! -f "$dir/file$total_count" ]; then
7654                 echo -n "creating hard links $begin:$total_count..."
7655                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7656                         /dev/null || error "cannot create hard links"
7657                 echo "done"
7658         fi
7659
7660         echo -n "checking number of hard links listed in xattrs..."
7661         local fid=$($LFS getstripe -F "$file1")
7662         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7663
7664         echo "${#paths[*]}"
7665         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7666                         skip "hard link list has unexpected size, skipping test"
7667         fi
7668         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7669                         error "link names should exceed xattrs size"
7670         fi
7671
7672         echo -n "migrating files..."
7673         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7674         local rc=$?
7675         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7676         echo "done"
7677
7678         # make sure all links have been properly migrated
7679         echo -n "verifying files..."
7680         fid=$($LFS getstripe -F "$file1") ||
7681                 error "cannot get fid for file $file1"
7682         for i in $(seq 2 $total_count); do
7683                 local fid2=$($LFS getstripe -F $dir/file$i)
7684
7685                 [ "$fid2" == "$fid" ] ||
7686                         error "migrated hard link has mismatched FID"
7687         done
7688
7689         # make sure hard links were properly detected, and migration was
7690         # performed only once for the entire link set; nonlinked files should
7691         # also be migrated
7692         local actual=$(grep -c 'done' <<< "$migrate_out")
7693         local expected=$(($uniq_count + 1))
7694
7695         [ "$actual" -eq  "$expected" ] ||
7696                 error "hard links individually migrated ($actual != $expected)"
7697
7698         # make sure the correct number of hard links are present
7699         local hardlinks=$(stat -c '%h' "$file1")
7700
7701         [ $hardlinks -eq $total_count ] ||
7702                 error "num hard links $hardlinks != $total_count"
7703         echo "done"
7704
7705         return 0
7706 }
7707
7708 test_56xb() {
7709         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7710                 skip "Need MDS version at least 2.10.55"
7711
7712         local dir="$DIR/$tdir"
7713
7714         test_mkdir "$dir" || error "cannot create dir $dir"
7715
7716         echo "testing lfs migrate mode when all links fit within xattrs"
7717         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7718
7719         echo "testing rsync mode when all links fit within xattrs"
7720         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7721
7722         echo "testing lfs migrate mode when all links do not fit within xattrs"
7723         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7724
7725         echo "testing rsync mode when all links do not fit within xattrs"
7726         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7727
7728         chown -R $RUNAS_ID $dir
7729         echo "testing non-root lfs migrate mode when not all links are in xattr"
7730         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7731
7732         # clean up
7733         rm -rf $dir
7734 }
7735 run_test 56xb "lfs migration hard link support"
7736
7737 test_56xc() {
7738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7739
7740         local dir="$DIR/$tdir"
7741
7742         test_mkdir "$dir" || error "cannot create dir $dir"
7743
7744         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7745         echo -n "Setting initial stripe for 20MB test file..."
7746         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7747                 error "cannot setstripe 20MB file"
7748         echo "done"
7749         echo -n "Sizing 20MB test file..."
7750         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7751         echo "done"
7752         echo -n "Verifying small file autostripe count is 1..."
7753         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7754                 error "cannot migrate 20MB file"
7755         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7756                 error "cannot get stripe for $dir/20mb"
7757         [ $stripe_count -eq 1 ] ||
7758                 error "unexpected stripe count $stripe_count for 20MB file"
7759         rm -f "$dir/20mb"
7760         echo "done"
7761
7762         # Test 2: File is small enough to fit within the available space on
7763         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7764         # have at least an additional 1KB for each desired stripe for test 3
7765         echo -n "Setting stripe for 1GB test file..."
7766         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7767         echo "done"
7768         echo -n "Sizing 1GB test file..."
7769         # File size is 1GB + 3KB
7770         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7771         echo "done"
7772
7773         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7774         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7775         if (( avail > 524288 * OSTCOUNT )); then
7776                 echo -n "Migrating 1GB file..."
7777                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7778                         error "cannot migrate 1GB file"
7779                 echo "done"
7780                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7781                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7782                         error "cannot getstripe for 1GB file"
7783                 [ $stripe_count -eq 2 ] ||
7784                         error "unexpected stripe count $stripe_count != 2"
7785                 echo "done"
7786         fi
7787
7788         # Test 3: File is too large to fit within the available space on
7789         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7790         if [ $OSTCOUNT -ge 3 ]; then
7791                 # The required available space is calculated as
7792                 # file size (1GB + 3KB) / OST count (3).
7793                 local kb_per_ost=349526
7794
7795                 echo -n "Migrating 1GB file with limit..."
7796                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7797                         error "cannot migrate 1GB file with limit"
7798                 echo "done"
7799
7800                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7801                 echo -n "Verifying 1GB autostripe count with limited space..."
7802                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7803                         error "unexpected stripe count $stripe_count (min 3)"
7804                 echo "done"
7805         fi
7806
7807         # clean up
7808         rm -rf $dir
7809 }
7810 run_test 56xc "lfs migration autostripe"
7811
7812 test_56xd() {
7813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7814
7815         local dir=$DIR/$tdir
7816         local f_mgrt=$dir/$tfile.mgrt
7817         local f_yaml=$dir/$tfile.yaml
7818         local f_copy=$dir/$tfile.copy
7819         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7820         local layout_copy="-c 2 -S 2M -i 1"
7821         local yamlfile=$dir/yamlfile
7822         local layout_before;
7823         local layout_after;
7824
7825         test_mkdir "$dir" || error "cannot create dir $dir"
7826         $LFS setstripe $layout_yaml $f_yaml ||
7827                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7828         $LFS getstripe --yaml $f_yaml > $yamlfile
7829         $LFS setstripe $layout_copy $f_copy ||
7830                 error "cannot setstripe $f_copy with layout $layout_copy"
7831         touch $f_mgrt
7832         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7833
7834         # 1. test option --yaml
7835         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7836                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7837         layout_before=$(get_layout_param $f_yaml)
7838         layout_after=$(get_layout_param $f_mgrt)
7839         [ "$layout_after" == "$layout_before" ] ||
7840                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7841
7842         # 2. test option --copy
7843         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7844                 error "cannot migrate $f_mgrt with --copy $f_copy"
7845         layout_before=$(get_layout_param $f_copy)
7846         layout_after=$(get_layout_param $f_mgrt)
7847         [ "$layout_after" == "$layout_before" ] ||
7848                 error "lfs_migrate --copy: $layout_after != $layout_before"
7849 }
7850 run_test 56xd "check lfs_migrate --yaml and --copy support"
7851
7852 test_56xe() {
7853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7854
7855         local dir=$DIR/$tdir
7856         local f_comp=$dir/$tfile
7857         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7858         local layout_before=""
7859         local layout_after=""
7860
7861         test_mkdir "$dir" || error "cannot create dir $dir"
7862         $LFS setstripe $layout $f_comp ||
7863                 error "cannot setstripe $f_comp with layout $layout"
7864         layout_before=$(get_layout_param $f_comp)
7865         dd if=/dev/zero of=$f_comp bs=1M count=4
7866
7867         # 1. migrate a comp layout file by lfs_migrate
7868         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7869         layout_after=$(get_layout_param $f_comp)
7870         [ "$layout_before" == "$layout_after" ] ||
7871                 error "lfs_migrate: $layout_before != $layout_after"
7872
7873         # 2. migrate a comp layout file by lfs migrate
7874         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7875         layout_after=$(get_layout_param $f_comp)
7876         [ "$layout_before" == "$layout_after" ] ||
7877                 error "lfs migrate: $layout_before != $layout_after"
7878 }
7879 run_test 56xe "migrate a composite layout file"
7880
7881 test_56xf() {
7882         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7883
7884         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7885                 skip "Need server version at least 2.13.53"
7886
7887         local dir=$DIR/$tdir
7888         local f_comp=$dir/$tfile
7889         local layout="-E 1M -c1 -E -1 -c2"
7890         local fid_before=""
7891         local fid_after=""
7892
7893         test_mkdir "$dir" || error "cannot create dir $dir"
7894         $LFS setstripe $layout $f_comp ||
7895                 error "cannot setstripe $f_comp with layout $layout"
7896         fid_before=$($LFS getstripe --fid $f_comp)
7897         dd if=/dev/zero of=$f_comp bs=1M count=4
7898
7899         # 1. migrate a comp layout file to a comp layout
7900         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7901         fid_after=$($LFS getstripe --fid $f_comp)
7902         [ "$fid_before" == "$fid_after" ] ||
7903                 error "comp-to-comp migrate: $fid_before != $fid_after"
7904
7905         # 2. migrate a comp layout file to a plain layout
7906         $LFS migrate -c2 $f_comp ||
7907                 error "cannot migrate $f_comp by lfs migrate"
7908         fid_after=$($LFS getstripe --fid $f_comp)
7909         [ "$fid_before" == "$fid_after" ] ||
7910                 error "comp-to-plain migrate: $fid_before != $fid_after"
7911
7912         # 3. migrate a plain layout file to a comp layout
7913         $LFS migrate $layout $f_comp ||
7914                 error "cannot migrate $f_comp by lfs migrate"
7915         fid_after=$($LFS getstripe --fid $f_comp)
7916         [ "$fid_before" == "$fid_after" ] ||
7917                 error "plain-to-comp migrate: $fid_before != $fid_after"
7918 }
7919 run_test 56xf "FID is not lost during migration of a composite layout file"
7920
7921 check_file_ost_range() {
7922         local file="$1"
7923         shift
7924         local range="$*"
7925         local -a file_range
7926         local idx
7927
7928         file_range=($($LFS getstripe -y "$file" |
7929                 awk '/l_ost_idx:/ { print $NF }'))
7930
7931         if [[ "${#file_range[@]}" = 0 ]]; then
7932                 echo "No osts found for $file"
7933                 return 1
7934         fi
7935
7936         for idx in "${file_range[@]}"; do
7937                 [[ " $range " =~ " $idx " ]] ||
7938                         return 1
7939         done
7940
7941         return 0
7942 }
7943
7944 sub_test_56xg() {
7945         local stripe_opt="$1"
7946         local pool="$2"
7947         shift 2
7948         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7949
7950         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7951                 error "Fail to migrate $tfile on $pool"
7952         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7953                 error "$tfile is not in pool $pool"
7954         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7955                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7956 }
7957
7958 test_56xg() {
7959         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7960         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7961         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7962                 skip "Need MDS version newer than 2.14.52"
7963
7964         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7965         local -a pool_ranges=("0 0" "1 1" "0 1")
7966
7967         # init pools
7968         for i in "${!pool_names[@]}"; do
7969                 pool_add ${pool_names[$i]} ||
7970                         error "pool_add failed (pool: ${pool_names[$i]})"
7971                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7972                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7973         done
7974
7975         # init the file to migrate
7976         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7977                 error "Unable to create $tfile on OST1"
7978         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7979                 error "Unable to write on $tfile"
7980
7981         echo "1. migrate $tfile on pool ${pool_names[0]}"
7982         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7983
7984         echo "2. migrate $tfile on pool ${pool_names[2]}"
7985         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7986
7987         echo "3. migrate $tfile on pool ${pool_names[1]}"
7988         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7989
7990         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7991         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7992         echo
7993
7994         # Clean pools
7995         destroy_test_pools ||
7996                 error "pool_destroy failed"
7997 }
7998 run_test 56xg "lfs migrate pool support"
7999
8000 test_56y() {
8001         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8002                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8003
8004         local res=""
8005         local dir=$DIR/$tdir
8006         local f1=$dir/file1
8007         local f2=$dir/file2
8008
8009         test_mkdir -p $dir || error "creating dir $dir"
8010         touch $f1 || error "creating std file $f1"
8011         $MULTIOP $f2 H2c || error "creating released file $f2"
8012
8013         # a directory can be raid0, so ask only for files
8014         res=$($LFS find $dir -L raid0 -type f | wc -l)
8015         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8016
8017         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8018         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8019
8020         # only files can be released, so no need to force file search
8021         res=$($LFS find $dir -L released)
8022         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8023
8024         res=$($LFS find $dir -type f \! -L released)
8025         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8026 }
8027 run_test 56y "lfs find -L raid0|released"
8028
8029 test_56z() { # LU-4824
8030         # This checks to make sure 'lfs find' continues after errors
8031         # There are two classes of errors that should be caught:
8032         # - If multiple paths are provided, all should be searched even if one
8033         #   errors out
8034         # - If errors are encountered during the search, it should not terminate
8035         #   early
8036         local dir=$DIR/$tdir
8037         local i
8038
8039         test_mkdir $dir
8040         for i in d{0..9}; do
8041                 test_mkdir $dir/$i
8042                 touch $dir/$i/$tfile
8043         done
8044         $LFS find $DIR/non_existent_dir $dir &&
8045                 error "$LFS find did not return an error"
8046         # Make a directory unsearchable. This should NOT be the last entry in
8047         # directory order.  Arbitrarily pick the 6th entry
8048         chmod 700 $($LFS find $dir -type d | sed '6!d')
8049
8050         $RUNAS $LFS find $DIR/non_existent $dir
8051         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8052
8053         # The user should be able to see 10 directories and 9 files
8054         (( count == 19 )) ||
8055                 error "$LFS find found $count != 19 entries after error"
8056 }
8057 run_test 56z "lfs find should continue after an error"
8058
8059 test_56aa() { # LU-5937
8060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8061
8062         local dir=$DIR/$tdir
8063
8064         mkdir $dir
8065         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8066
8067         createmany -o $dir/striped_dir/${tfile}- 1024
8068         local dirs=$($LFS find --size +8k $dir/)
8069
8070         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8071 }
8072 run_test 56aa "lfs find --size under striped dir"
8073
8074 test_56ab() { # LU-10705
8075         test_mkdir $DIR/$tdir
8076         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8077         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8078         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8079         # Flush writes to ensure valid blocks.  Need to be more thorough for
8080         # ZFS, since blocks are not allocated/returned to client immediately.
8081         sync_all_data
8082         wait_zfs_commit ost1 2
8083         cancel_lru_locks osc
8084         ls -ls $DIR/$tdir
8085
8086         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8087
8088         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8089
8090         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8091         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8092
8093         rm -f $DIR/$tdir/$tfile.[123]
8094 }
8095 run_test 56ab "lfs find --blocks"
8096
8097 # LU-11188
8098 test_56aca() {
8099         local dir="$DIR/$tdir"
8100         local perms=(001 002 003 004 005 006 007
8101                      010 020 030 040 050 060 070
8102                      100 200 300 400 500 600 700
8103                      111 222 333 444 555 666 777)
8104         local perm_minus=(8 8 4 8 4 4 2
8105                           8 8 4 8 4 4 2
8106                           8 8 4 8 4 4 2
8107                           4 4 2 4 2 2 1)
8108         local perm_slash=(8  8 12  8 12 12 14
8109                           8  8 12  8 12 12 14
8110                           8  8 12  8 12 12 14
8111                          16 16 24 16 24 24 28)
8112
8113         test_mkdir "$dir"
8114         for perm in ${perms[*]}; do
8115                 touch "$dir/$tfile.$perm"
8116                 chmod $perm "$dir/$tfile.$perm"
8117         done
8118
8119         for ((i = 0; i < ${#perms[*]}; i++)); do
8120                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8121                 (( $num == 1 )) ||
8122                         error "lfs find -perm ${perms[i]}:"\
8123                               "$num != 1"
8124
8125                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8126                 (( $num == ${perm_minus[i]} )) ||
8127                         error "lfs find -perm -${perms[i]}:"\
8128                               "$num != ${perm_minus[i]}"
8129
8130                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8131                 (( $num == ${perm_slash[i]} )) ||
8132                         error "lfs find -perm /${perms[i]}:"\
8133                               "$num != ${perm_slash[i]}"
8134         done
8135 }
8136 run_test 56aca "check lfs find -perm with octal representation"
8137
8138 test_56acb() {
8139         local dir=$DIR/$tdir
8140         # p is the permission of write and execute for user, group and other
8141         # without the umask. It is used to test +wx.
8142         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8143         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8144         local symbolic=(+t  a+t u+t g+t o+t
8145                         g+s u+s o+s +s o+sr
8146                         o=r,ug+o,u+w
8147                         u+ g+ o+ a+ ugo+
8148                         u- g- o- a- ugo-
8149                         u= g= o= a= ugo=
8150                         o=r,ug+o,u+w u=r,a+u,u+w
8151                         g=r,ugo=g,u+w u+x,+X +X
8152                         u+x,u+X u+X u+x,g+X o+r,+X
8153                         u+x,go+X +wx +rwx)
8154
8155         test_mkdir $dir
8156         for perm in ${perms[*]}; do
8157                 touch "$dir/$tfile.$perm"
8158                 chmod $perm "$dir/$tfile.$perm"
8159         done
8160
8161         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8162                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8163
8164                 (( $num == 1 )) ||
8165                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8166         done
8167 }
8168 run_test 56acb "check lfs find -perm with symbolic representation"
8169
8170 test_56acc() {
8171         local dir=$DIR/$tdir
8172         local tests="17777 787 789 abcd
8173                 ug=uu ug=a ug=gu uo=ou urw
8174                 u+xg+x a=r,u+x,"
8175
8176         test_mkdir $dir
8177         for err in $tests; do
8178                 if $LFS find $dir -perm $err 2>/dev/null; then
8179                         error "lfs find -perm $err: parsing should have failed"
8180                 fi
8181         done
8182 }
8183 run_test 56acc "check parsing error for lfs find -perm"
8184
8185 test_56ba() {
8186         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8187                 skip "Need MDS version at least 2.10.50"
8188
8189         # Create composite files with one component
8190         local dir=$DIR/$tdir
8191
8192         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8193         # Create composite files with three components
8194         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8195         # Create non-composite files
8196         createmany -o $dir/${tfile}- 10
8197
8198         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8199
8200         [[ $nfiles == 10 ]] ||
8201                 error "lfs find -E 1M found $nfiles != 10 files"
8202
8203         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8204         [[ $nfiles == 25 ]] ||
8205                 error "lfs find ! -E 1M found $nfiles != 25 files"
8206
8207         # All files have a component that starts at 0
8208         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8209         [[ $nfiles == 35 ]] ||
8210                 error "lfs find --component-start 0 - $nfiles != 35 files"
8211
8212         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8213         [[ $nfiles == 15 ]] ||
8214                 error "lfs find --component-start 2M - $nfiles != 15 files"
8215
8216         # All files created here have a componenet that does not starts at 2M
8217         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8218         [[ $nfiles == 35 ]] ||
8219                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8220
8221         # Find files with a specified number of components
8222         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8223         [[ $nfiles == 15 ]] ||
8224                 error "lfs find --component-count 3 - $nfiles != 15 files"
8225
8226         # Remember non-composite files have a component count of zero
8227         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8228         [[ $nfiles == 10 ]] ||
8229                 error "lfs find --component-count 0 - $nfiles != 10 files"
8230
8231         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8232         [[ $nfiles == 20 ]] ||
8233                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8234
8235         # All files have a flag called "init"
8236         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8237         [[ $nfiles == 35 ]] ||
8238                 error "lfs find --component-flags init - $nfiles != 35 files"
8239
8240         # Multi-component files will have a component not initialized
8241         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8242         [[ $nfiles == 15 ]] ||
8243                 error "lfs find !--component-flags init - $nfiles != 15 files"
8244
8245         rm -rf $dir
8246
8247 }
8248 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8249
8250 test_56ca() {
8251         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8252                 skip "Need MDS version at least 2.10.57"
8253
8254         local td=$DIR/$tdir
8255         local tf=$td/$tfile
8256         local dir
8257         local nfiles
8258         local cmd
8259         local i
8260         local j
8261
8262         # create mirrored directories and mirrored files
8263         mkdir $td || error "mkdir $td failed"
8264         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8265         createmany -o $tf- 10 || error "create $tf- failed"
8266
8267         for i in $(seq 2); do
8268                 dir=$td/dir$i
8269                 mkdir $dir || error "mkdir $dir failed"
8270                 $LFS mirror create -N$((3 + i)) $dir ||
8271                         error "create mirrored dir $dir failed"
8272                 createmany -o $dir/$tfile- 10 ||
8273                         error "create $dir/$tfile- failed"
8274         done
8275
8276         # change the states of some mirrored files
8277         echo foo > $tf-6
8278         for i in $(seq 2); do
8279                 dir=$td/dir$i
8280                 for j in $(seq 4 9); do
8281                         echo foo > $dir/$tfile-$j
8282                 done
8283         done
8284
8285         # find mirrored files with specific mirror count
8286         cmd="$LFS find --mirror-count 3 --type f $td"
8287         nfiles=$($cmd | wc -l)
8288         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8289
8290         cmd="$LFS find ! --mirror-count 3 --type f $td"
8291         nfiles=$($cmd | wc -l)
8292         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8293
8294         cmd="$LFS find --mirror-count +2 --type f $td"
8295         nfiles=$($cmd | wc -l)
8296         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8297
8298         cmd="$LFS find --mirror-count -6 --type f $td"
8299         nfiles=$($cmd | wc -l)
8300         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8301
8302         # find mirrored files with specific file state
8303         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8304         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8305
8306         cmd="$LFS find --mirror-state=ro --type f $td"
8307         nfiles=$($cmd | wc -l)
8308         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8309
8310         cmd="$LFS find ! --mirror-state=ro --type f $td"
8311         nfiles=$($cmd | wc -l)
8312         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8313
8314         cmd="$LFS find --mirror-state=wp --type f $td"
8315         nfiles=$($cmd | wc -l)
8316         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8317
8318         cmd="$LFS find ! --mirror-state=sp --type f $td"
8319         nfiles=$($cmd | wc -l)
8320         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8321 }
8322 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8323
8324 test_56da() { # LU-14179
8325         local path=$DIR/$tdir
8326
8327         test_mkdir $path
8328         cd $path
8329
8330         local longdir=$(str_repeat 'a' 255)
8331
8332         for i in {1..15}; do
8333                 path=$path/$longdir
8334                 test_mkdir $longdir
8335                 cd $longdir
8336         done
8337
8338         local len=${#path}
8339         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8340
8341         test_mkdir $lastdir
8342         cd $lastdir
8343         # PATH_MAX-1
8344         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8345
8346         # NAME_MAX
8347         touch $(str_repeat 'f' 255)
8348
8349         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8350                 error "lfs find reported an error"
8351
8352         rm -rf $DIR/$tdir
8353 }
8354 run_test 56da "test lfs find with long paths"
8355
8356 test_56ea() { #LU-10378
8357         local path=$DIR/$tdir
8358         local pool=$TESTNAME
8359
8360         # Create ost pool
8361         pool_add $pool || error "pool_add $pool failed"
8362         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8363                 error "adding targets to $pool failed"
8364
8365         # Set default pool on directory before creating file
8366         mkdir $path || error "mkdir $path failed"
8367         $LFS setstripe -p $pool $path ||
8368                 error "set OST pool on $pool failed"
8369         touch $path/$tfile || error "touch $path/$tfile failed"
8370
8371         # Compare basic file attributes from -printf and stat
8372         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8373         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8374
8375         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8376                 error "Attrs from lfs find and stat don't match"
8377
8378         # Compare Lustre attributes from lfs find and lfs getstripe
8379         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8380         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8381         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8382         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8383         local fpool=$($LFS getstripe --pool $path/$tfile)
8384         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8385
8386         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8387                 error "Attrs from lfs find and lfs getstripe don't match"
8388
8389         # Verify behavior for unknown escape/format sequences
8390         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8391
8392         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8393                 error "Escape/format codes don't match"
8394 }
8395 run_test 56ea "test lfs find -printf option"
8396
8397 test_57a() {
8398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8399         # note test will not do anything if MDS is not local
8400         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8401                 skip_env "ldiskfs only test"
8402         fi
8403         remote_mds_nodsh && skip "remote MDS with nodsh"
8404
8405         local MNTDEV="osd*.*MDT*.mntdev"
8406         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8407         [ -z "$DEV" ] && error "can't access $MNTDEV"
8408         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8409                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8410                         error "can't access $DEV"
8411                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8412                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8413                 rm $TMP/t57a.dump
8414         done
8415 }
8416 run_test 57a "verify MDS filesystem created with large inodes =="
8417
8418 test_57b() {
8419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8420         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8421                 skip_env "ldiskfs only test"
8422         fi
8423         remote_mds_nodsh && skip "remote MDS with nodsh"
8424
8425         local dir=$DIR/$tdir
8426         local filecount=100
8427         local file1=$dir/f1
8428         local fileN=$dir/f$filecount
8429
8430         rm -rf $dir || error "removing $dir"
8431         test_mkdir -c1 $dir
8432         local mdtidx=$($LFS getstripe -m $dir)
8433         local mdtname=MDT$(printf %04x $mdtidx)
8434         local facet=mds$((mdtidx + 1))
8435
8436         echo "mcreating $filecount files"
8437         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8438
8439         # verify that files do not have EAs yet
8440         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8441                 error "$file1 has an EA"
8442         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8443                 error "$fileN has an EA"
8444
8445         sync
8446         sleep 1
8447         df $dir  #make sure we get new statfs data
8448         local mdsfree=$(do_facet $facet \
8449                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8450         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8451         local file
8452
8453         echo "opening files to create objects/EAs"
8454         for file in $(seq -f $dir/f%g 1 $filecount); do
8455                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8456                         error "opening $file"
8457         done
8458
8459         # verify that files have EAs now
8460         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8461         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8462
8463         sleep 1  #make sure we get new statfs data
8464         df $dir
8465         local mdsfree2=$(do_facet $facet \
8466                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8467         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8468
8469         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8470                 if [ "$mdsfree" != "$mdsfree2" ]; then
8471                         error "MDC before $mdcfree != after $mdcfree2"
8472                 else
8473                         echo "MDC before $mdcfree != after $mdcfree2"
8474                         echo "unable to confirm if MDS has large inodes"
8475                 fi
8476         fi
8477         rm -rf $dir
8478 }
8479 run_test 57b "default LOV EAs are stored inside large inodes ==="
8480
8481 test_58() {
8482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8483         [ -z "$(which wiretest 2>/dev/null)" ] &&
8484                         skip_env "could not find wiretest"
8485
8486         wiretest
8487 }
8488 run_test 58 "verify cross-platform wire constants =============="
8489
8490 test_59() {
8491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8492
8493         echo "touch 130 files"
8494         createmany -o $DIR/f59- 130
8495         echo "rm 130 files"
8496         unlinkmany $DIR/f59- 130
8497         sync
8498         # wait for commitment of removal
8499         wait_delete_completed
8500 }
8501 run_test 59 "verify cancellation of llog records async ========="
8502
8503 TEST60_HEAD="test_60 run $RANDOM"
8504 test_60a() {
8505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8506         remote_mgs_nodsh && skip "remote MGS with nodsh"
8507         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8508                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8509                         skip_env "missing subtest run-llog.sh"
8510
8511         log "$TEST60_HEAD - from kernel mode"
8512         do_facet mgs "$LCTL dk > /dev/null"
8513         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8514         do_facet mgs $LCTL dk > $TMP/$tfile
8515
8516         # LU-6388: test llog_reader
8517         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8518         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8519         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8520                         skip_env "missing llog_reader"
8521         local fstype=$(facet_fstype mgs)
8522         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8523                 skip_env "Only for ldiskfs or zfs type mgs"
8524
8525         local mntpt=$(facet_mntpt mgs)
8526         local mgsdev=$(mgsdevname 1)
8527         local fid_list
8528         local fid
8529         local rec_list
8530         local rec
8531         local rec_type
8532         local obj_file
8533         local path
8534         local seq
8535         local oid
8536         local pass=true
8537
8538         #get fid and record list
8539         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8540                 tail -n 4))
8541         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8542                 tail -n 4))
8543         #remount mgs as ldiskfs or zfs type
8544         stop mgs || error "stop mgs failed"
8545         mount_fstype mgs || error "remount mgs failed"
8546         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8547                 fid=${fid_list[i]}
8548                 rec=${rec_list[i]}
8549                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8550                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8551                 oid=$((16#$oid))
8552
8553                 case $fstype in
8554                         ldiskfs )
8555                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8556                         zfs )
8557                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8558                 esac
8559                 echo "obj_file is $obj_file"
8560                 do_facet mgs $llog_reader $obj_file
8561
8562                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8563                         awk '{ print $3 }' | sed -e "s/^type=//g")
8564                 if [ $rec_type != $rec ]; then
8565                         echo "FAILED test_60a wrong record type $rec_type," \
8566                               "should be $rec"
8567                         pass=false
8568                         break
8569                 fi
8570
8571                 #check obj path if record type is LLOG_LOGID_MAGIC
8572                 if [ "$rec" == "1064553b" ]; then
8573                         path=$(do_facet mgs $llog_reader $obj_file |
8574                                 grep "path=" | awk '{ print $NF }' |
8575                                 sed -e "s/^path=//g")
8576                         if [ $obj_file != $mntpt/$path ]; then
8577                                 echo "FAILED test_60a wrong obj path" \
8578                                       "$montpt/$path, should be $obj_file"
8579                                 pass=false
8580                                 break
8581                         fi
8582                 fi
8583         done
8584         rm -f $TMP/$tfile
8585         #restart mgs before "error", otherwise it will block the next test
8586         stop mgs || error "stop mgs failed"
8587         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8588         $pass || error "test failed, see FAILED test_60a messages for specifics"
8589 }
8590 run_test 60a "llog_test run from kernel module and test llog_reader"
8591
8592 test_60b() { # bug 6411
8593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8594
8595         dmesg > $DIR/$tfile
8596         LLOG_COUNT=$(do_facet mgs dmesg |
8597                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8598                           /llog_[a-z]*.c:[0-9]/ {
8599                                 if (marker)
8600                                         from_marker++
8601                                 from_begin++
8602                           }
8603                           END {
8604                                 if (marker)
8605                                         print from_marker
8606                                 else
8607                                         print from_begin
8608                           }")
8609
8610         [[ $LLOG_COUNT -gt 120 ]] &&
8611                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8612 }
8613 run_test 60b "limit repeated messages from CERROR/CWARN"
8614
8615 test_60c() {
8616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8617
8618         echo "create 5000 files"
8619         createmany -o $DIR/f60c- 5000
8620 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8621         lctl set_param fail_loc=0x80000137
8622         unlinkmany $DIR/f60c- 5000
8623         lctl set_param fail_loc=0
8624 }
8625 run_test 60c "unlink file when mds full"
8626
8627 test_60d() {
8628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8629
8630         SAVEPRINTK=$(lctl get_param -n printk)
8631         # verify "lctl mark" is even working"
8632         MESSAGE="test message ID $RANDOM $$"
8633         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8634         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8635
8636         lctl set_param printk=0 || error "set lnet.printk failed"
8637         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8638         MESSAGE="new test message ID $RANDOM $$"
8639         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8640         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8641         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8642
8643         lctl set_param -n printk="$SAVEPRINTK"
8644 }
8645 run_test 60d "test printk console message masking"
8646
8647 test_60e() {
8648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8649         remote_mds_nodsh && skip "remote MDS with nodsh"
8650
8651         touch $DIR/$tfile
8652 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8653         do_facet mds1 lctl set_param fail_loc=0x15b
8654         rm $DIR/$tfile
8655 }
8656 run_test 60e "no space while new llog is being created"
8657
8658 test_60f() {
8659         local old_path=$($LCTL get_param -n debug_path)
8660
8661         stack_trap "$LCTL set_param debug_path=$old_path"
8662         stack_trap "rm -f $TMP/$tfile*"
8663         rm -f $TMP/$tfile* 2> /dev/null
8664         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8665         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8666         test_mkdir $DIR/$tdir
8667         # retry in case the open is cached and not released
8668         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8669                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8670                 sleep 0.1
8671         done
8672         ls $TMP/$tfile*
8673         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8674 }
8675 run_test 60f "change debug_path works"
8676
8677 test_60g() {
8678         local pid
8679         local i
8680
8681         test_mkdir -c $MDSCOUNT $DIR/$tdir
8682
8683         (
8684                 local index=0
8685                 while true; do
8686                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8687                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8688                                 2>/dev/null
8689                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8690                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8691                         index=$((index + 1))
8692                 done
8693         ) &
8694
8695         pid=$!
8696
8697         for i in {0..100}; do
8698                 # define OBD_FAIL_OSD_TXN_START    0x19a
8699                 local index=$((i % MDSCOUNT + 1))
8700
8701                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8702                         > /dev/null
8703                 sleep 0.01
8704         done
8705
8706         kill -9 $pid
8707
8708         for i in $(seq $MDSCOUNT); do
8709                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8710         done
8711
8712         mkdir $DIR/$tdir/new || error "mkdir failed"
8713         rmdir $DIR/$tdir/new || error "rmdir failed"
8714
8715         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8716                 -t namespace
8717         for i in $(seq $MDSCOUNT); do
8718                 wait_update_facet mds$i "$LCTL get_param -n \
8719                         mdd.$(facet_svc mds$i).lfsck_namespace |
8720                         awk '/^status/ { print \\\$2 }'" "completed"
8721         done
8722
8723         ls -R $DIR/$tdir
8724         rm -rf $DIR/$tdir || error "rmdir failed"
8725 }
8726 run_test 60g "transaction abort won't cause MDT hung"
8727
8728 test_60h() {
8729         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8730                 skip "Need MDS version at least 2.12.52"
8731         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8732
8733         local f
8734
8735         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8736         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8737         for fail_loc in 0x80000188 0x80000189; do
8738                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8739                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8740                         error "mkdir $dir-$fail_loc failed"
8741                 for i in {0..10}; do
8742                         # create may fail on missing stripe
8743                         echo $i > $DIR/$tdir-$fail_loc/$i
8744                 done
8745                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8746                         error "getdirstripe $tdir-$fail_loc failed"
8747                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8748                         error "migrate $tdir-$fail_loc failed"
8749                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8750                         error "getdirstripe $tdir-$fail_loc failed"
8751                 pushd $DIR/$tdir-$fail_loc
8752                 for f in *; do
8753                         echo $f | cmp $f - || error "$f data mismatch"
8754                 done
8755                 popd
8756                 rm -rf $DIR/$tdir-$fail_loc
8757         done
8758 }
8759 run_test 60h "striped directory with missing stripes can be accessed"
8760
8761 function t60i_load() {
8762         mkdir $DIR/$tdir
8763         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8764         $LCTL set_param fail_loc=0x131c fail_val=1
8765         for ((i=0; i<5000; i++)); do
8766                 touch $DIR/$tdir/f$i
8767         done
8768 }
8769
8770 test_60i() {
8771         changelog_register || error "changelog_register failed"
8772         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8773         changelog_users $SINGLEMDS | grep -q $cl_user ||
8774                 error "User $cl_user not found in changelog_users"
8775         changelog_chmask "ALL"
8776         t60i_load &
8777         local PID=$!
8778         for((i=0; i<100; i++)); do
8779                 changelog_dump >/dev/null ||
8780                         error "can't read changelog"
8781         done
8782         kill $PID
8783         wait $PID
8784         changelog_deregister || error "changelog_deregister failed"
8785         $LCTL set_param fail_loc=0
8786 }
8787 run_test 60i "llog: new record vs reader race"
8788
8789 test_61a() {
8790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8791
8792         f="$DIR/f61"
8793         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8794         cancel_lru_locks osc
8795         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8796         sync
8797 }
8798 run_test 61a "mmap() writes don't make sync hang ================"
8799
8800 test_61b() {
8801         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8802 }
8803 run_test 61b "mmap() of unstriped file is successful"
8804
8805 # bug 2330 - insufficient obd_match error checking causes LBUG
8806 test_62() {
8807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8808
8809         f="$DIR/f62"
8810         echo foo > $f
8811         cancel_lru_locks osc
8812         lctl set_param fail_loc=0x405
8813         cat $f && error "cat succeeded, expect -EIO"
8814         lctl set_param fail_loc=0
8815 }
8816 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8817 # match every page all of the time.
8818 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8819
8820 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8821 # Though this test is irrelevant anymore, it helped to reveal some
8822 # other grant bugs (LU-4482), let's keep it.
8823 test_63a() {   # was test_63
8824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8825
8826         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8827
8828         for i in `seq 10` ; do
8829                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8830                 sleep 5
8831                 kill $!
8832                 sleep 1
8833         done
8834
8835         rm -f $DIR/f63 || true
8836 }
8837 run_test 63a "Verify oig_wait interruption does not crash ======="
8838
8839 # bug 2248 - async write errors didn't return to application on sync
8840 # bug 3677 - async write errors left page locked
8841 test_63b() {
8842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8843
8844         debugsave
8845         lctl set_param debug=-1
8846
8847         # ensure we have a grant to do async writes
8848         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8849         rm $DIR/$tfile
8850
8851         sync    # sync lest earlier test intercept the fail_loc
8852
8853         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8854         lctl set_param fail_loc=0x80000406
8855         $MULTIOP $DIR/$tfile Owy && \
8856                 error "sync didn't return ENOMEM"
8857         sync; sleep 2; sync     # do a real sync this time to flush page
8858         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8859                 error "locked page left in cache after async error" || true
8860         debugrestore
8861 }
8862 run_test 63b "async write errors should be returned to fsync ==="
8863
8864 test_64a () {
8865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8866
8867         lfs df $DIR
8868         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8869 }
8870 run_test 64a "verify filter grant calculations (in kernel) ====="
8871
8872 test_64b () {
8873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8874
8875         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8876 }
8877 run_test 64b "check out-of-space detection on client"
8878
8879 test_64c() {
8880         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8881 }
8882 run_test 64c "verify grant shrink"
8883
8884 import_param() {
8885         local tgt=$1
8886         local param=$2
8887
8888         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8889 }
8890
8891 # this does exactly what osc_request.c:osc_announce_cached() does in
8892 # order to calculate max amount of grants to ask from server
8893 want_grant() {
8894         local tgt=$1
8895
8896         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8897         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8898
8899         ((rpc_in_flight++));
8900         nrpages=$((nrpages * rpc_in_flight))
8901
8902         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8903
8904         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8905
8906         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8907         local undirty=$((nrpages * PAGE_SIZE))
8908
8909         local max_extent_pages
8910         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8911         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8912         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8913         local grant_extent_tax
8914         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8915
8916         undirty=$((undirty + nrextents * grant_extent_tax))
8917
8918         echo $undirty
8919 }
8920
8921 # this is size of unit for grant allocation. It should be equal to
8922 # what tgt_grant.c:tgt_grant_chunk() calculates
8923 grant_chunk() {
8924         local tgt=$1
8925         local max_brw_size
8926         local grant_extent_tax
8927
8928         max_brw_size=$(import_param $tgt max_brw_size)
8929
8930         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8931
8932         echo $(((max_brw_size + grant_extent_tax) * 2))
8933 }
8934
8935 test_64d() {
8936         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8937                 skip "OST < 2.10.55 doesn't limit grants enough"
8938
8939         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8940
8941         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8942                 skip "no grant_param connect flag"
8943
8944         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8945
8946         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8947         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8948
8949
8950         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8951         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8952
8953         $LFS setstripe $DIR/$tfile -i 0 -c 1
8954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8955         ddpid=$!
8956
8957         while kill -0 $ddpid; do
8958                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8959
8960                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8961                         kill $ddpid
8962                         error "cur_grant $cur_grant > $max_cur_granted"
8963                 fi
8964
8965                 sleep 1
8966         done
8967 }
8968 run_test 64d "check grant limit exceed"
8969
8970 check_grants() {
8971         local tgt=$1
8972         local expected=$2
8973         local msg=$3
8974         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8975
8976         ((cur_grants == expected)) ||
8977                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8978 }
8979
8980 round_up_p2() {
8981         echo $((($1 + $2 - 1) & ~($2 - 1)))
8982 }
8983
8984 test_64e() {
8985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8986         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8987                 skip "Need OSS version at least 2.11.56"
8988
8989         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8990         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8991         $LCTL set_param debug=+cache
8992
8993         # Remount client to reset grant
8994         remount_client $MOUNT || error "failed to remount client"
8995         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8996
8997         local init_grants=$(import_param $osc_tgt initial_grant)
8998
8999         check_grants $osc_tgt $init_grants "init grants"
9000
9001         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9002         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9003         local gbs=$(import_param $osc_tgt grant_block_size)
9004
9005         # write random number of bytes from max_brw_size / 4 to max_brw_size
9006         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9007         # align for direct io
9008         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9009         # round to grant consumption unit
9010         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9011
9012         local grants=$((wb_round_up + extent_tax))
9013
9014         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9015
9016         # define OBD_FAIL_TGT_NO_GRANT 0x725
9017         # make the server not grant more back
9018         do_facet ost1 $LCTL set_param fail_loc=0x725
9019         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9020
9021         do_facet ost1 $LCTL set_param fail_loc=0
9022
9023         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9024
9025         rm -f $DIR/$tfile || error "rm failed"
9026
9027         # Remount client to reset grant
9028         remount_client $MOUNT || error "failed to remount client"
9029         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9030
9031         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9032
9033         # define OBD_FAIL_TGT_NO_GRANT 0x725
9034         # make the server not grant more back
9035         do_facet ost1 $LCTL set_param fail_loc=0x725
9036         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9037         do_facet ost1 $LCTL set_param fail_loc=0
9038
9039         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9040 }
9041 run_test 64e "check grant consumption (no grant allocation)"
9042
9043 test_64f() {
9044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9045
9046         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9047         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9048         $LCTL set_param debug=+cache
9049
9050         # Remount client to reset grant
9051         remount_client $MOUNT || error "failed to remount client"
9052         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9053
9054         local init_grants=$(import_param $osc_tgt initial_grant)
9055         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9056         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9057         local gbs=$(import_param $osc_tgt grant_block_size)
9058         local chunk=$(grant_chunk $osc_tgt)
9059
9060         # write random number of bytes from max_brw_size / 4 to max_brw_size
9061         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9062         # align for direct io
9063         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9064         # round to grant consumption unit
9065         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9066
9067         local grants=$((wb_round_up + extent_tax))
9068
9069         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9070         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9071                 error "error writing to $DIR/$tfile"
9072
9073         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9074                 "direct io with grant allocation"
9075
9076         rm -f $DIR/$tfile || error "rm failed"
9077
9078         # Remount client to reset grant
9079         remount_client $MOUNT || error "failed to remount client"
9080         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9081
9082         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9083
9084         local cmd="oO_WRONLY:w${write_bytes}_yc"
9085
9086         $MULTIOP $DIR/$tfile $cmd &
9087         MULTIPID=$!
9088         sleep 1
9089
9090         check_grants $osc_tgt $((init_grants - grants)) \
9091                 "buffered io, not write rpc"
9092
9093         kill -USR1 $MULTIPID
9094         wait
9095
9096         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9097                 "buffered io, one RPC"
9098 }
9099 run_test 64f "check grant consumption (with grant allocation)"
9100
9101 test_64g() {
9102         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9103                 skip "Need MDS version at least 2.14.56"
9104
9105         local mdts=$(comma_list $(mdts_nodes))
9106
9107         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9108                         tr '\n' ' ')
9109         stack_trap "$LCTL set_param $old"
9110
9111         # generate dirty pages and increase dirty granted on MDT
9112         stack_trap "rm -f $DIR/$tfile-*"
9113         for (( i = 0; i < 10; i++)); do
9114                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9115                         error "can't set stripe"
9116                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9117                         error "can't dd"
9118                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9119                         $LFS getstripe $DIR/$tfile-$i
9120                         error "not DoM file"
9121                 }
9122         done
9123
9124         # flush dirty pages
9125         sync
9126
9127         # wait until grant shrink reset grant dirty on MDTs
9128         for ((i = 0; i < 120; i++)); do
9129                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9130                         awk '{sum=sum+$1} END {print sum}')
9131                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9132                 echo "$grant_dirty grants, $vm_dirty pages"
9133                 (( grant_dirty + vm_dirty == 0 )) && break
9134                 (( i == 3 )) && sync &&
9135                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9136                 sleep 1
9137         done
9138
9139         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9140                 awk '{sum=sum+$1} END {print sum}')
9141         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9142 }
9143 run_test 64g "grant shrink on MDT"
9144
9145 test_64h() {
9146         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9147                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9148
9149         local instance=$($LFS getname -i $DIR)
9150         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9151         local num_exps=$(do_facet ost1 \
9152             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9153         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9154         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9155         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9156
9157         # 10MiB is for file to be written, max_brw_size * 16 *
9158         # num_exps is space reserve so that tgt_grant_shrink() decided
9159         # to not shrink
9160         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9161         (( avail * 1024 < expect )) &&
9162                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9163
9164         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9165         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9166         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9167         $LCTL set_param osc.*OST0000*.grant_shrink=1
9168         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9169
9170         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9171         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9172
9173         # drop cache so that coming read would do rpc
9174         cancel_lru_locks osc
9175
9176         # shrink interval is set to 10, pause for 7 seconds so that
9177         # grant thread did not wake up yet but coming read entered
9178         # shrink mode for rpc (osc_should_shrink_grant())
9179         sleep 7
9180
9181         declare -a cur_grant_bytes
9182         declare -a tot_granted
9183         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9184         tot_granted[0]=$(do_facet ost1 \
9185             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9186
9187         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9188
9189         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9190         tot_granted[1]=$(do_facet ost1 \
9191             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9192
9193         # grant change should be equal on both sides
9194         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9195                 tot_granted[0] - tot_granted[1])) ||
9196                 error "grant change mismatch, "                                \
9197                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9198                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9199 }
9200 run_test 64h "grant shrink on read"
9201
9202 test_64i() {
9203         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9204                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9205
9206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9207         remote_ost_nodsh && skip "remote OSTs with nodsh"
9208
9209         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9210
9211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9212
9213         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9214         local instance=$($LFS getname -i $DIR)
9215
9216         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9217         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9218
9219         # shrink grants and simulate rpc loss
9220         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9221         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9222         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9223
9224         fail ost1
9225
9226         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9227
9228         local testid=$(echo $TESTNAME | tr '_' ' ')
9229
9230         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9231                 grep "GRANT, real grant" &&
9232                 error "client has more grants then it owns" || true
9233 }
9234 run_test 64i "shrink on reconnect"
9235
9236 # bug 1414 - set/get directories' stripe info
9237 test_65a() {
9238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9239
9240         test_mkdir $DIR/$tdir
9241         touch $DIR/$tdir/f1
9242         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9243 }
9244 run_test 65a "directory with no stripe info"
9245
9246 test_65b() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248
9249         test_mkdir $DIR/$tdir
9250         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9251
9252         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9253                                                 error "setstripe"
9254         touch $DIR/$tdir/f2
9255         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9256 }
9257 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9258
9259 test_65c() {
9260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9261         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9262
9263         test_mkdir $DIR/$tdir
9264         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9265
9266         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9267                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9268         touch $DIR/$tdir/f3
9269         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9270 }
9271 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9272
9273 test_65d() {
9274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9275
9276         test_mkdir $DIR/$tdir
9277         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9278         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9279
9280         if [[ $STRIPECOUNT -le 0 ]]; then
9281                 sc=1
9282         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9283                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9284                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9285         else
9286                 sc=$(($STRIPECOUNT - 1))
9287         fi
9288         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9289         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9290         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9291                 error "lverify failed"
9292 }
9293 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9294
9295 test_65e() {
9296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9297
9298         test_mkdir $DIR/$tdir
9299
9300         $LFS setstripe $DIR/$tdir || error "setstripe"
9301         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9302                                         error "no stripe info failed"
9303         touch $DIR/$tdir/f6
9304         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9305 }
9306 run_test 65e "directory setstripe defaults"
9307
9308 test_65f() {
9309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9310
9311         test_mkdir $DIR/${tdir}f
9312         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9313                 error "setstripe succeeded" || true
9314 }
9315 run_test 65f "dir setstripe permission (should return error) ==="
9316
9317 test_65g() {
9318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9319
9320         test_mkdir $DIR/$tdir
9321         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9322
9323         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9324                 error "setstripe -S failed"
9325         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9326         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9327                 error "delete default stripe failed"
9328 }
9329 run_test 65g "directory setstripe -d"
9330
9331 test_65h() {
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333
9334         test_mkdir $DIR/$tdir
9335         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9336
9337         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9338                 error "setstripe -S failed"
9339         test_mkdir $DIR/$tdir/dd1
9340         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9341                 error "stripe info inherit failed"
9342 }
9343 run_test 65h "directory stripe info inherit ===================="
9344
9345 test_65i() {
9346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9347
9348         save_layout_restore_at_exit $MOUNT
9349
9350         # bug6367: set non-default striping on root directory
9351         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9352
9353         # bug12836: getstripe on -1 default directory striping
9354         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9355
9356         # bug12836: getstripe -v on -1 default directory striping
9357         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9358
9359         # bug12836: new find on -1 default directory striping
9360         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9361 }
9362 run_test 65i "various tests to set root directory striping"
9363
9364 test_65j() { # bug6367
9365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9366
9367         sync; sleep 1
9368
9369         # if we aren't already remounting for each test, do so for this test
9370         if [ "$I_MOUNTED" = "yes" ]; then
9371                 cleanup || error "failed to unmount"
9372                 setup
9373         fi
9374
9375         save_layout_restore_at_exit $MOUNT
9376
9377         $LFS setstripe -d $MOUNT || error "setstripe failed"
9378 }
9379 run_test 65j "set default striping on root directory (bug 6367)="
9380
9381 cleanup_65k() {
9382         rm -rf $DIR/$tdir
9383         wait_delete_completed
9384         do_facet $SINGLEMDS "lctl set_param -n \
9385                 osp.$ost*MDT0000.max_create_count=$max_count"
9386         do_facet $SINGLEMDS "lctl set_param -n \
9387                 osp.$ost*MDT0000.create_count=$count"
9388         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9389         echo $INACTIVE_OSC "is Activate"
9390
9391         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9392 }
9393
9394 test_65k() { # bug11679
9395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9396         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9397         remote_mds_nodsh && skip "remote MDS with nodsh"
9398
9399         local disable_precreate=true
9400         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9401                 disable_precreate=false
9402
9403         echo "Check OST status: "
9404         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9405                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9406
9407         for OSC in $MDS_OSCS; do
9408                 echo $OSC "is active"
9409                 do_facet $SINGLEMDS lctl --device %$OSC activate
9410         done
9411
9412         for INACTIVE_OSC in $MDS_OSCS; do
9413                 local ost=$(osc_to_ost $INACTIVE_OSC)
9414                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9415                                lov.*md*.target_obd |
9416                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9417
9418                 mkdir -p $DIR/$tdir
9419                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9420                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9421
9422                 echo "Deactivate: " $INACTIVE_OSC
9423                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9424
9425                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9426                               osp.$ost*MDT0000.create_count")
9427                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9428                                   osp.$ost*MDT0000.max_create_count")
9429                 $disable_precreate &&
9430                         do_facet $SINGLEMDS "lctl set_param -n \
9431                                 osp.$ost*MDT0000.max_create_count=0"
9432
9433                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9434                         [ -f $DIR/$tdir/$idx ] && continue
9435                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9436                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9437                                 { cleanup_65k;
9438                                   error "setstripe $idx should succeed"; }
9439                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9440                 done
9441                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9442                 rmdir $DIR/$tdir
9443
9444                 do_facet $SINGLEMDS "lctl set_param -n \
9445                         osp.$ost*MDT0000.max_create_count=$max_count"
9446                 do_facet $SINGLEMDS "lctl set_param -n \
9447                         osp.$ost*MDT0000.create_count=$count"
9448                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9449                 echo $INACTIVE_OSC "is Activate"
9450
9451                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9452         done
9453 }
9454 run_test 65k "validate manual striping works properly with deactivated OSCs"
9455
9456 test_65l() { # bug 12836
9457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9458
9459         test_mkdir -p $DIR/$tdir/test_dir
9460         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9461         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9462 }
9463 run_test 65l "lfs find on -1 stripe dir ========================"
9464
9465 test_65m() {
9466         local layout=$(save_layout $MOUNT)
9467         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9468                 restore_layout $MOUNT $layout
9469                 error "setstripe should fail by non-root users"
9470         }
9471         true
9472 }
9473 run_test 65m "normal user can't set filesystem default stripe"
9474
9475 test_65n() {
9476         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9477         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9478                 skip "Need MDS version at least 2.12.50"
9479         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9480
9481         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9482         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9483         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9484
9485         save_layout_restore_at_exit $MOUNT
9486
9487         # new subdirectory under root directory should not inherit
9488         # the default layout from root
9489         local dir1=$MOUNT/$tdir-1
9490         mkdir $dir1 || error "mkdir $dir1 failed"
9491         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9492                 error "$dir1 shouldn't have LOV EA"
9493
9494         # delete the default layout on root directory
9495         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9496
9497         local dir2=$MOUNT/$tdir-2
9498         mkdir $dir2 || error "mkdir $dir2 failed"
9499         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9500                 error "$dir2 shouldn't have LOV EA"
9501
9502         # set a new striping pattern on root directory
9503         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9504         local new_def_stripe_size=$((def_stripe_size * 2))
9505         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9506                 error "set stripe size on $MOUNT failed"
9507
9508         # new file created in $dir2 should inherit the new stripe size from
9509         # the filesystem default
9510         local file2=$dir2/$tfile-2
9511         touch $file2 || error "touch $file2 failed"
9512
9513         local file2_stripe_size=$($LFS getstripe -S $file2)
9514         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9515         {
9516                 echo "file2_stripe_size: '$file2_stripe_size'"
9517                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9518                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9519         }
9520
9521         local dir3=$MOUNT/$tdir-3
9522         mkdir $dir3 || error "mkdir $dir3 failed"
9523         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9524         # the root layout, which is the actual default layout that will be used
9525         # when new files are created in $dir3.
9526         local dir3_layout=$(get_layout_param $dir3)
9527         local root_dir_layout=$(get_layout_param $MOUNT)
9528         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9529         {
9530                 echo "dir3_layout: '$dir3_layout'"
9531                 echo "root_dir_layout: '$root_dir_layout'"
9532                 error "$dir3 should show the default layout from $MOUNT"
9533         }
9534
9535         # set OST pool on root directory
9536         local pool=$TESTNAME
9537         pool_add $pool || error "add $pool failed"
9538         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9539                 error "add targets to $pool failed"
9540
9541         $LFS setstripe -p $pool $MOUNT ||
9542                 error "set OST pool on $MOUNT failed"
9543
9544         # new file created in $dir3 should inherit the pool from
9545         # the filesystem default
9546         local file3=$dir3/$tfile-3
9547         touch $file3 || error "touch $file3 failed"
9548
9549         local file3_pool=$($LFS getstripe -p $file3)
9550         [[ "$file3_pool" = "$pool" ]] ||
9551                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9552
9553         local dir4=$MOUNT/$tdir-4
9554         mkdir $dir4 || error "mkdir $dir4 failed"
9555         local dir4_layout=$(get_layout_param $dir4)
9556         root_dir_layout=$(get_layout_param $MOUNT)
9557         echo "$LFS getstripe -d $dir4"
9558         $LFS getstripe -d $dir4
9559         echo "$LFS getstripe -d $MOUNT"
9560         $LFS getstripe -d $MOUNT
9561         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9562         {
9563                 echo "dir4_layout: '$dir4_layout'"
9564                 echo "root_dir_layout: '$root_dir_layout'"
9565                 error "$dir4 should show the default layout from $MOUNT"
9566         }
9567
9568         # new file created in $dir4 should inherit the pool from
9569         # the filesystem default
9570         local file4=$dir4/$tfile-4
9571         touch $file4 || error "touch $file4 failed"
9572
9573         local file4_pool=$($LFS getstripe -p $file4)
9574         [[ "$file4_pool" = "$pool" ]] ||
9575                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9576
9577         # new subdirectory under non-root directory should inherit
9578         # the default layout from its parent directory
9579         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9580                 error "set directory layout on $dir4 failed"
9581
9582         local dir5=$dir4/$tdir-5
9583         mkdir $dir5 || error "mkdir $dir5 failed"
9584
9585         dir4_layout=$(get_layout_param $dir4)
9586         local dir5_layout=$(get_layout_param $dir5)
9587         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9588         {
9589                 echo "dir4_layout: '$dir4_layout'"
9590                 echo "dir5_layout: '$dir5_layout'"
9591                 error "$dir5 should inherit the default layout from $dir4"
9592         }
9593
9594         # though subdir under ROOT doesn't inherit default layout, but
9595         # its sub dir/file should be created with default layout.
9596         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9597         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9598                 skip "Need MDS version at least 2.12.59"
9599
9600         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9601         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9602         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9603
9604         if [ $default_lmv_hash == "none" ]; then
9605                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9606         else
9607                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9608                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9609         fi
9610
9611         $LFS setdirstripe -D -c 2 $MOUNT ||
9612                 error "setdirstripe -D -c 2 failed"
9613         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9614         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9615         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9616
9617         # $dir4 layout includes pool
9618         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9619         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9620                 error "pool lost on setstripe"
9621         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9622         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9623                 error "pool lost on compound layout setstripe"
9624 }
9625 run_test 65n "don't inherit default layout from root for new subdirectories"
9626
9627 test_65o() {
9628         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9629                 skip "need MDS version at least 2.14.57"
9630
9631         # set OST pool on root directory
9632         local pool=$TESTNAME
9633
9634         pool_add $pool || error "add $pool failed"
9635         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9636                 error "add targets to $pool failed"
9637
9638         local dir1=$MOUNT/$tdir
9639
9640         mkdir $dir1 || error "mkdir $dir1 failed"
9641
9642         # set a new striping pattern on root directory
9643         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9644
9645         $LFS setstripe -p $pool $dir1 ||
9646                 error "set directory layout on $dir1 failed"
9647
9648         # $dir1 layout includes pool
9649         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9650         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9651                 error "pool lost on setstripe"
9652         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9653         $LFS getstripe $dir1
9654         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9655                 error "pool lost on compound layout setstripe"
9656
9657         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9658                 error "setdirstripe failed on sub-dir with inherited pool"
9659         $LFS getstripe $dir1/dir2
9660         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9661                 error "pool lost on compound layout setdirstripe"
9662
9663         $LFS setstripe -E -1 -c 1 $dir1
9664         $LFS getstripe -d $dir1
9665         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9666                 error "pool lost on setstripe"
9667 }
9668 run_test 65o "pool inheritance for mdt component"
9669
9670 # bug 2543 - update blocks count on client
9671 test_66() {
9672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9673
9674         local COUNT=${COUNT:-8}
9675         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9676         sync; sync_all_data; sync; sync_all_data
9677         cancel_lru_locks osc
9678         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9679         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9680 }
9681 run_test 66 "update inode blocks count on client ==============="
9682
9683 meminfo() {
9684         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9685 }
9686
9687 swap_used() {
9688         swapon -s | awk '($1 == "'$1'") { print $4 }'
9689 }
9690
9691 # bug5265, obdfilter oa2dentry return -ENOENT
9692 # #define OBD_FAIL_SRV_ENOENT 0x217
9693 test_69() {
9694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9695         remote_ost_nodsh && skip "remote OST with nodsh"
9696
9697         f="$DIR/$tfile"
9698         $LFS setstripe -c 1 -i 0 $f
9699
9700         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9701
9702         do_facet ost1 lctl set_param fail_loc=0x217
9703         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9704         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9705
9706         do_facet ost1 lctl set_param fail_loc=0
9707         $DIRECTIO write $f 0 2 || error "write error"
9708
9709         cancel_lru_locks osc
9710         $DIRECTIO read $f 0 1 || error "read error"
9711
9712         do_facet ost1 lctl set_param fail_loc=0x217
9713         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9714
9715         do_facet ost1 lctl set_param fail_loc=0
9716         rm -f $f
9717 }
9718 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9719
9720 test_71() {
9721         test_mkdir $DIR/$tdir
9722         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9723         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9724 }
9725 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9726
9727 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9729         [ "$RUNAS_ID" = "$UID" ] &&
9730                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9731         # Check that testing environment is properly set up. Skip if not
9732         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9733                 skip_env "User $RUNAS_ID does not exist - skipping"
9734
9735         touch $DIR/$tfile
9736         chmod 777 $DIR/$tfile
9737         chmod ug+s $DIR/$tfile
9738         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9739                 error "$RUNAS dd $DIR/$tfile failed"
9740         # See if we are still setuid/sgid
9741         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9742                 error "S/gid is not dropped on write"
9743         # Now test that MDS is updated too
9744         cancel_lru_locks mdc
9745         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9746                 error "S/gid is not dropped on MDS"
9747         rm -f $DIR/$tfile
9748 }
9749 run_test 72a "Test that remove suid works properly (bug5695) ===="
9750
9751 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9752         local perm
9753
9754         [ "$RUNAS_ID" = "$UID" ] &&
9755                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9756         [ "$RUNAS_ID" -eq 0 ] &&
9757                 skip_env "RUNAS_ID = 0 -- skipping"
9758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9759         # Check that testing environment is properly set up. Skip if not
9760         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9761                 skip_env "User $RUNAS_ID does not exist - skipping"
9762
9763         touch $DIR/${tfile}-f{g,u}
9764         test_mkdir $DIR/${tfile}-dg
9765         test_mkdir $DIR/${tfile}-du
9766         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9767         chmod g+s $DIR/${tfile}-{f,d}g
9768         chmod u+s $DIR/${tfile}-{f,d}u
9769         for perm in 777 2777 4777; do
9770                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9771                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9772                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9773                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9774         done
9775         true
9776 }
9777 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9778
9779 # bug 3462 - multiple simultaneous MDC requests
9780 test_73() {
9781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9782
9783         test_mkdir $DIR/d73-1
9784         test_mkdir $DIR/d73-2
9785         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9786         pid1=$!
9787
9788         lctl set_param fail_loc=0x80000129
9789         $MULTIOP $DIR/d73-1/f73-2 Oc &
9790         sleep 1
9791         lctl set_param fail_loc=0
9792
9793         $MULTIOP $DIR/d73-2/f73-3 Oc &
9794         pid3=$!
9795
9796         kill -USR1 $pid1
9797         wait $pid1 || return 1
9798
9799         sleep 25
9800
9801         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9802         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9803         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9804
9805         rm -rf $DIR/d73-*
9806 }
9807 run_test 73 "multiple MDC requests (should not deadlock)"
9808
9809 test_74a() { # bug 6149, 6184
9810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9811
9812         touch $DIR/f74a
9813         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9814         #
9815         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9816         # will spin in a tight reconnection loop
9817         $LCTL set_param fail_loc=0x8000030e
9818         # get any lock that won't be difficult - lookup works.
9819         ls $DIR/f74a
9820         $LCTL set_param fail_loc=0
9821         rm -f $DIR/f74a
9822         true
9823 }
9824 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9825
9826 test_74b() { # bug 13310
9827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9828
9829         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9830         #
9831         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9832         # will spin in a tight reconnection loop
9833         $LCTL set_param fail_loc=0x8000030e
9834         # get a "difficult" lock
9835         touch $DIR/f74b
9836         $LCTL set_param fail_loc=0
9837         rm -f $DIR/f74b
9838         true
9839 }
9840 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9841
9842 test_74c() {
9843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9844
9845         #define OBD_FAIL_LDLM_NEW_LOCK
9846         $LCTL set_param fail_loc=0x319
9847         touch $DIR/$tfile && error "touch successful"
9848         $LCTL set_param fail_loc=0
9849         true
9850 }
9851 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9852
9853 slab_lic=/sys/kernel/slab/lustre_inode_cache
9854 num_objects() {
9855         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9856         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9857                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9858 }
9859
9860 test_76a() { # Now for b=20433, added originally in b=1443
9861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9862
9863         cancel_lru_locks osc
9864         # there may be some slab objects cached per core
9865         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9866         local before=$(num_objects)
9867         local count=$((512 * cpus))
9868         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9869         local margin=$((count / 10))
9870         if [[ -f $slab_lic/aliases ]]; then
9871                 local aliases=$(cat $slab_lic/aliases)
9872                 (( aliases > 0 )) && margin=$((margin * aliases))
9873         fi
9874
9875         echo "before slab objects: $before"
9876         for i in $(seq $count); do
9877                 touch $DIR/$tfile
9878                 rm -f $DIR/$tfile
9879         done
9880         cancel_lru_locks osc
9881         local after=$(num_objects)
9882         echo "created: $count, after slab objects: $after"
9883         # shared slab counts are not very accurate, allow significant margin
9884         # the main goal is that the cache growth is not permanently > $count
9885         while (( after > before + margin )); do
9886                 sleep 1
9887                 after=$(num_objects)
9888                 wait=$((wait + 1))
9889                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9890                 if (( wait > 60 )); then
9891                         error "inode slab grew from $before+$margin to $after"
9892                 fi
9893         done
9894 }
9895 run_test 76a "confirm clients recycle inodes properly ===="
9896
9897 test_76b() {
9898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9899         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9900
9901         local count=512
9902         local before=$(num_objects)
9903
9904         for i in $(seq $count); do
9905                 mkdir $DIR/$tdir
9906                 rmdir $DIR/$tdir
9907         done
9908
9909         local after=$(num_objects)
9910         local wait=0
9911
9912         while (( after > before )); do
9913                 sleep 1
9914                 after=$(num_objects)
9915                 wait=$((wait + 1))
9916                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9917                 if (( wait > 60 )); then
9918                         error "inode slab grew from $before to $after"
9919                 fi
9920         done
9921
9922         echo "slab objects before: $before, after: $after"
9923 }
9924 run_test 76b "confirm clients recycle directory inodes properly ===="
9925
9926 export ORIG_CSUM=""
9927 set_checksums()
9928 {
9929         # Note: in sptlrpc modes which enable its own bulk checksum, the
9930         # original crc32_le bulk checksum will be automatically disabled,
9931         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9932         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9933         # In this case set_checksums() will not be no-op, because sptlrpc
9934         # bulk checksum will be enabled all through the test.
9935
9936         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9937         lctl set_param -n osc.*.checksums $1
9938         return 0
9939 }
9940
9941 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9942                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9943 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9944                              tr -d [] | head -n1)}
9945 set_checksum_type()
9946 {
9947         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9948         rc=$?
9949         log "set checksum type to $1, rc = $rc"
9950         return $rc
9951 }
9952
9953 get_osc_checksum_type()
9954 {
9955         # arugment 1: OST name, like OST0000
9956         ost=$1
9957         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9958                         sed 's/.*\[\(.*\)\].*/\1/g')
9959         rc=$?
9960         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9961         echo $checksum_type
9962 }
9963
9964 F77_TMP=$TMP/f77-temp
9965 F77SZ=8
9966 setup_f77() {
9967         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9968                 error "error writing to $F77_TMP"
9969 }
9970
9971 test_77a() { # bug 10889
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973         $GSS && skip_env "could not run with gss"
9974
9975         [ ! -f $F77_TMP ] && setup_f77
9976         set_checksums 1
9977         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9978         set_checksums 0
9979         rm -f $DIR/$tfile
9980 }
9981 run_test 77a "normal checksum read/write operation"
9982
9983 test_77b() { # bug 10889
9984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9985         $GSS && skip_env "could not run with gss"
9986
9987         [ ! -f $F77_TMP ] && setup_f77
9988         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9989         $LCTL set_param fail_loc=0x80000409
9990         set_checksums 1
9991
9992         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9993                 error "dd error: $?"
9994         $LCTL set_param fail_loc=0
9995
9996         for algo in $CKSUM_TYPES; do
9997                 cancel_lru_locks osc
9998                 set_checksum_type $algo
9999                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10000                 $LCTL set_param fail_loc=0x80000408
10001                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10002                 $LCTL set_param fail_loc=0
10003         done
10004         set_checksums 0
10005         set_checksum_type $ORIG_CSUM_TYPE
10006         rm -f $DIR/$tfile
10007 }
10008 run_test 77b "checksum error on client write, read"
10009
10010 cleanup_77c() {
10011         trap 0
10012         set_checksums 0
10013         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10014         $check_ost &&
10015                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10016         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10017         $check_ost && [ -n "$ost_file_prefix" ] &&
10018                 do_facet ost1 rm -f ${ost_file_prefix}\*
10019 }
10020
10021 test_77c() {
10022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10023         $GSS && skip_env "could not run with gss"
10024         remote_ost_nodsh && skip "remote OST with nodsh"
10025
10026         local bad1
10027         local osc_file_prefix
10028         local osc_file
10029         local check_ost=false
10030         local ost_file_prefix
10031         local ost_file
10032         local orig_cksum
10033         local dump_cksum
10034         local fid
10035
10036         # ensure corruption will occur on first OSS/OST
10037         $LFS setstripe -i 0 $DIR/$tfile
10038
10039         [ ! -f $F77_TMP ] && setup_f77
10040         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10041                 error "dd write error: $?"
10042         fid=$($LFS path2fid $DIR/$tfile)
10043
10044         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10045         then
10046                 check_ost=true
10047                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10048                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10049         else
10050                 echo "OSS do not support bulk pages dump upon error"
10051         fi
10052
10053         osc_file_prefix=$($LCTL get_param -n debug_path)
10054         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10055
10056         trap cleanup_77c EXIT
10057
10058         set_checksums 1
10059         # enable bulk pages dump upon error on Client
10060         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10061         # enable bulk pages dump upon error on OSS
10062         $check_ost &&
10063                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10064
10065         # flush Client cache to allow next read to reach OSS
10066         cancel_lru_locks osc
10067
10068         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10069         $LCTL set_param fail_loc=0x80000408
10070         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10071         $LCTL set_param fail_loc=0
10072
10073         rm -f $DIR/$tfile
10074
10075         # check cksum dump on Client
10076         osc_file=$(ls ${osc_file_prefix}*)
10077         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10078         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10079         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10080         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10081         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10082                      cksum)
10083         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10084         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10085                 error "dump content does not match on Client"
10086
10087         $check_ost || skip "No need to check cksum dump on OSS"
10088
10089         # check cksum dump on OSS
10090         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10091         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10092         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10093         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10094         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10095                 error "dump content does not match on OSS"
10096
10097         cleanup_77c
10098 }
10099 run_test 77c "checksum error on client read with debug"
10100
10101 test_77d() { # bug 10889
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103         $GSS && skip_env "could not run with gss"
10104
10105         stack_trap "rm -f $DIR/$tfile"
10106         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10107         $LCTL set_param fail_loc=0x80000409
10108         set_checksums 1
10109         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10110                 error "direct write: rc=$?"
10111         $LCTL set_param fail_loc=0
10112         set_checksums 0
10113
10114         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10115         $LCTL set_param fail_loc=0x80000408
10116         set_checksums 1
10117         cancel_lru_locks osc
10118         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10119                 error "direct read: rc=$?"
10120         $LCTL set_param fail_loc=0
10121         set_checksums 0
10122 }
10123 run_test 77d "checksum error on OST direct write, read"
10124
10125 test_77f() { # bug 10889
10126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10127         $GSS && skip_env "could not run with gss"
10128
10129         set_checksums 1
10130         stack_trap "rm -f $DIR/$tfile"
10131         for algo in $CKSUM_TYPES; do
10132                 cancel_lru_locks osc
10133                 set_checksum_type $algo
10134                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10135                 $LCTL set_param fail_loc=0x409
10136                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10137                         error "direct write succeeded"
10138                 $LCTL set_param fail_loc=0
10139         done
10140         set_checksum_type $ORIG_CSUM_TYPE
10141         set_checksums 0
10142 }
10143 run_test 77f "repeat checksum error on write (expect error)"
10144
10145 test_77g() { # bug 10889
10146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10147         $GSS && skip_env "could not run with gss"
10148         remote_ost_nodsh && skip "remote OST with nodsh"
10149
10150         [ ! -f $F77_TMP ] && setup_f77
10151
10152         local file=$DIR/$tfile
10153         stack_trap "rm -f $file" EXIT
10154
10155         $LFS setstripe -c 1 -i 0 $file
10156         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10157         do_facet ost1 lctl set_param fail_loc=0x8000021a
10158         set_checksums 1
10159         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10160                 error "write error: rc=$?"
10161         do_facet ost1 lctl set_param fail_loc=0
10162         set_checksums 0
10163
10164         cancel_lru_locks osc
10165         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10166         do_facet ost1 lctl set_param fail_loc=0x8000021b
10167         set_checksums 1
10168         cmp $F77_TMP $file || error "file compare failed"
10169         do_facet ost1 lctl set_param fail_loc=0
10170         set_checksums 0
10171 }
10172 run_test 77g "checksum error on OST write, read"
10173
10174 test_77k() { # LU-10906
10175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10176         $GSS && skip_env "could not run with gss"
10177
10178         local cksum_param="osc.$FSNAME*.checksums"
10179         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10180         local checksum
10181         local i
10182
10183         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10184         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10185         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10186
10187         for i in 0 1; do
10188                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10189                         error "failed to set checksum=$i on MGS"
10190                 wait_update $HOSTNAME "$get_checksum" $i
10191                 #remount
10192                 echo "remount client, checksum should be $i"
10193                 remount_client $MOUNT || error "failed to remount client"
10194                 checksum=$(eval $get_checksum)
10195                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10196         done
10197         # remove persistent param to avoid races with checksum mountopt below
10198         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10199                 error "failed to delete checksum on MGS"
10200
10201         for opt in "checksum" "nochecksum"; do
10202                 #remount with mount option
10203                 echo "remount client with option $opt, checksum should be $i"
10204                 umount_client $MOUNT || error "failed to umount client"
10205                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10206                         error "failed to mount client with option '$opt'"
10207                 checksum=$(eval $get_checksum)
10208                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10209                 i=$((i - 1))
10210         done
10211
10212         remount_client $MOUNT || error "failed to remount client"
10213 }
10214 run_test 77k "enable/disable checksum correctly"
10215
10216 test_77l() {
10217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10218         $GSS && skip_env "could not run with gss"
10219
10220         set_checksums 1
10221         stack_trap "set_checksums $ORIG_CSUM" EXIT
10222         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10223
10224         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10225
10226         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10227         for algo in $CKSUM_TYPES; do
10228                 set_checksum_type $algo || error "fail to set checksum type $algo"
10229                 osc_algo=$(get_osc_checksum_type OST0000)
10230                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10231
10232                 # no locks, no reqs to let the connection idle
10233                 cancel_lru_locks osc
10234                 lru_resize_disable osc
10235                 wait_osc_import_state client ost1 IDLE
10236
10237                 # ensure ost1 is connected
10238                 stat $DIR/$tfile >/dev/null || error "can't stat"
10239                 wait_osc_import_state client ost1 FULL
10240
10241                 osc_algo=$(get_osc_checksum_type OST0000)
10242                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10243         done
10244         return 0
10245 }
10246 run_test 77l "preferred checksum type is remembered after reconnected"
10247
10248 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10249 rm -f $F77_TMP
10250 unset F77_TMP
10251
10252 test_77m() {
10253         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10254                 skip "Need at least version 2.14.52"
10255         local param=checksum_speed
10256
10257         $LCTL get_param $param || error "reading $param failed"
10258
10259         csum_speeds=$($LCTL get_param -n $param)
10260
10261         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10262                 error "known checksum types are missing"
10263 }
10264 run_test 77m "Verify checksum_speed is correctly read"
10265
10266 check_filefrag_77n() {
10267         local nr_ext=0
10268         local starts=()
10269         local ends=()
10270
10271         while read extidx a b start end rest; do
10272                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10273                         nr_ext=$(( $nr_ext + 1 ))
10274                         starts+=( ${start%..} )
10275                         ends+=( ${end%:} )
10276                 fi
10277         done < <( filefrag -sv $1 )
10278
10279         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10280         return 1
10281 }
10282
10283 test_77n() {
10284         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10285
10286         touch $DIR/$tfile
10287         $TRUNCATE $DIR/$tfile 0
10288         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10289         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10290         check_filefrag_77n $DIR/$tfile ||
10291                 skip "$tfile blocks not contiguous around hole"
10292
10293         set_checksums 1
10294         stack_trap "set_checksums $ORIG_CSUM" EXIT
10295         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10296         stack_trap "rm -f $DIR/$tfile"
10297
10298         for algo in $CKSUM_TYPES; do
10299                 if [[ "$algo" =~ ^t10 ]]; then
10300                         set_checksum_type $algo ||
10301                                 error "fail to set checksum type $algo"
10302                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10303                                 error "fail to read $tfile with $algo"
10304                 fi
10305         done
10306         rm -f $DIR/$tfile
10307         return 0
10308 }
10309 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10310
10311 test_77o() {
10312         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10313                 skip "Need MDS version at least 2.14.55"
10314         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10315                 skip "Need OST version at least 2.14.55"
10316         local ofd=obdfilter
10317         local mdt=mdt
10318
10319         # print OST checksum_type
10320         echo "$ofd.$FSNAME-*.checksum_type:"
10321         do_nodes $(comma_list $(osts_nodes)) \
10322                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10323
10324         # print MDT checksum_type
10325         echo "$mdt.$FSNAME-*.checksum_type:"
10326         do_nodes $(comma_list $(mdts_nodes)) \
10327                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10328
10329         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10330                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10331
10332         (( $o_count == $OSTCOUNT )) ||
10333                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10334
10335         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10336                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10337
10338         (( $m_count == $MDSCOUNT )) ||
10339                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10340 }
10341 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10342
10343 cleanup_test_78() {
10344         trap 0
10345         rm -f $DIR/$tfile
10346 }
10347
10348 test_78() { # bug 10901
10349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10350         remote_ost || skip_env "local OST"
10351
10352         NSEQ=5
10353         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10354         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10355         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10356         echo "MemTotal: $MEMTOTAL"
10357
10358         # reserve 256MB of memory for the kernel and other running processes,
10359         # and then take 1/2 of the remaining memory for the read/write buffers.
10360         if [ $MEMTOTAL -gt 512 ] ;then
10361                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10362         else
10363                 # for those poor memory-starved high-end clusters...
10364                 MEMTOTAL=$((MEMTOTAL / 2))
10365         fi
10366         echo "Mem to use for directio: $MEMTOTAL"
10367
10368         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10369         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10370         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10371         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10372                 head -n1)
10373         echo "Smallest OST: $SMALLESTOST"
10374         [[ $SMALLESTOST -lt 10240 ]] &&
10375                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10376
10377         trap cleanup_test_78 EXIT
10378
10379         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10380                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10381
10382         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10383         echo "File size: $F78SIZE"
10384         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10385         for i in $(seq 1 $NSEQ); do
10386                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10387                 echo directIO rdwr round $i of $NSEQ
10388                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10389         done
10390
10391         cleanup_test_78
10392 }
10393 run_test 78 "handle large O_DIRECT writes correctly ============"
10394
10395 test_79() { # bug 12743
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397
10398         wait_delete_completed
10399
10400         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10401         BKFREE=$(calc_osc_kbytes kbytesfree)
10402         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10403
10404         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10405         DFTOTAL=`echo $STRING | cut -d, -f1`
10406         DFUSED=`echo $STRING  | cut -d, -f2`
10407         DFAVAIL=`echo $STRING | cut -d, -f3`
10408         DFFREE=$(($DFTOTAL - $DFUSED))
10409
10410         ALLOWANCE=$((64 * $OSTCOUNT))
10411
10412         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10413            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10414                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10415         fi
10416         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10417            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10418                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10419         fi
10420         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10421            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10422                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10423         fi
10424 }
10425 run_test 79 "df report consistency check ======================="
10426
10427 test_80() { # bug 10718
10428         remote_ost_nodsh && skip "remote OST with nodsh"
10429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10430
10431         # relax strong synchronous semantics for slow backends like ZFS
10432         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10433                 local soc="obdfilter.*.sync_lock_cancel"
10434                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10435
10436                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10437                 if [ -z "$save" ]; then
10438                         soc="obdfilter.*.sync_on_lock_cancel"
10439                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10440                 fi
10441
10442                 if [ "$save" != "never" ]; then
10443                         local hosts=$(comma_list $(osts_nodes))
10444
10445                         do_nodes $hosts $LCTL set_param $soc=never
10446                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10447                 fi
10448         fi
10449
10450         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10451         sync; sleep 1; sync
10452         local before=$(date +%s)
10453         cancel_lru_locks osc
10454         local after=$(date +%s)
10455         local diff=$((after - before))
10456         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10457
10458         rm -f $DIR/$tfile
10459 }
10460 run_test 80 "Page eviction is equally fast at high offsets too"
10461
10462 test_81a() { # LU-456
10463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10464         remote_ost_nodsh && skip "remote OST with nodsh"
10465
10466         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10467         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10468         do_facet ost1 lctl set_param fail_loc=0x80000228
10469
10470         # write should trigger a retry and success
10471         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10472         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10473         RC=$?
10474         if [ $RC -ne 0 ] ; then
10475                 error "write should success, but failed for $RC"
10476         fi
10477 }
10478 run_test 81a "OST should retry write when get -ENOSPC ==============="
10479
10480 test_81b() { # LU-456
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         remote_ost_nodsh && skip "remote OST with nodsh"
10483
10484         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10485         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10486         do_facet ost1 lctl set_param fail_loc=0x228
10487
10488         # write should retry several times and return -ENOSPC finally
10489         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10490         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10491         RC=$?
10492         ENOSPC=28
10493         if [ $RC -ne $ENOSPC ] ; then
10494                 error "dd should fail for -ENOSPC, but succeed."
10495         fi
10496 }
10497 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10498
10499 test_99() {
10500         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10501
10502         test_mkdir $DIR/$tdir.cvsroot
10503         chown $RUNAS_ID $DIR/$tdir.cvsroot
10504
10505         cd $TMP
10506         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10507
10508         cd /etc/init.d
10509         # some versions of cvs import exit(1) when asked to import links or
10510         # files they can't read.  ignore those files.
10511         local toignore=$(find . -type l -printf '-I %f\n' -o \
10512                          ! -perm /4 -printf '-I %f\n')
10513         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10514                 $tdir.reposname vtag rtag
10515
10516         cd $DIR
10517         test_mkdir $DIR/$tdir.reposname
10518         chown $RUNAS_ID $DIR/$tdir.reposname
10519         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10520
10521         cd $DIR/$tdir.reposname
10522         $RUNAS touch foo99
10523         $RUNAS cvs add -m 'addmsg' foo99
10524         $RUNAS cvs update
10525         $RUNAS cvs commit -m 'nomsg' foo99
10526         rm -fr $DIR/$tdir.cvsroot
10527 }
10528 run_test 99 "cvs strange file/directory operations"
10529
10530 test_100() {
10531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10532         [[ "$NETTYPE" =~ tcp ]] ||
10533                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10534         remote_ost_nodsh && skip "remote OST with nodsh"
10535         remote_mds_nodsh && skip "remote MDS with nodsh"
10536         remote_servers ||
10537                 skip "useless for local single node setup"
10538
10539         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10540                 [ "$PROT" != "tcp" ] && continue
10541                 RPORT=$(echo $REMOTE | cut -d: -f2)
10542                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10543
10544                 rc=0
10545                 LPORT=`echo $LOCAL | cut -d: -f2`
10546                 if [ $LPORT -ge 1024 ]; then
10547                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10548                         netstat -tna
10549                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10550                 fi
10551         done
10552         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10553 }
10554 run_test 100 "check local port using privileged port ==========="
10555
10556 function get_named_value()
10557 {
10558     local tag=$1
10559
10560     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10561 }
10562
10563 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10564                    awk '/^max_cached_mb/ { print $2 }')
10565
10566 cleanup_101a() {
10567         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10568         trap 0
10569 }
10570
10571 test_101a() {
10572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10573
10574         local s
10575         local discard
10576         local nreads=10000
10577         local cache_limit=32
10578
10579         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10580         trap cleanup_101a EXIT
10581         $LCTL set_param -n llite.*.read_ahead_stats=0
10582         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10583
10584         #
10585         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10586         #
10587         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10588         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10589
10590         discard=0
10591         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10592                    get_named_value 'read.but.discarded'); do
10593                         discard=$(($discard + $s))
10594         done
10595         cleanup_101a
10596
10597         $LCTL get_param osc.*-osc*.rpc_stats
10598         $LCTL get_param llite.*.read_ahead_stats
10599
10600         # Discard is generally zero, but sometimes a few random reads line up
10601         # and trigger larger readahead, which is wasted & leads to discards.
10602         if [[ $(($discard)) -gt $nreads ]]; then
10603                 error "too many ($discard) discarded pages"
10604         fi
10605         rm -f $DIR/$tfile || true
10606 }
10607 run_test 101a "check read-ahead for random reads"
10608
10609 setup_test101bc() {
10610         test_mkdir $DIR/$tdir
10611         local ssize=$1
10612         local FILE_LENGTH=$2
10613         STRIPE_OFFSET=0
10614
10615         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10616
10617         local list=$(comma_list $(osts_nodes))
10618         set_osd_param $list '' read_cache_enable 0
10619         set_osd_param $list '' writethrough_cache_enable 0
10620
10621         trap cleanup_test101bc EXIT
10622         # prepare the read-ahead file
10623         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10624
10625         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10626                                 count=$FILE_SIZE_MB 2> /dev/null
10627
10628 }
10629
10630 cleanup_test101bc() {
10631         trap 0
10632         rm -rf $DIR/$tdir
10633         rm -f $DIR/$tfile
10634
10635         local list=$(comma_list $(osts_nodes))
10636         set_osd_param $list '' read_cache_enable 1
10637         set_osd_param $list '' writethrough_cache_enable 1
10638 }
10639
10640 calc_total() {
10641         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10642 }
10643
10644 ra_check_101() {
10645         local read_size=$1
10646         local stripe_size=$2
10647         local stride_length=$((stripe_size / read_size))
10648         local stride_width=$((stride_length * OSTCOUNT))
10649         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10650                                 (stride_width - stride_length) ))
10651         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10652                   get_named_value 'read.but.discarded' | calc_total)
10653
10654         if [[ $discard -gt $discard_limit ]]; then
10655                 $LCTL get_param llite.*.read_ahead_stats
10656                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10657         else
10658                 echo "Read-ahead success for size ${read_size}"
10659         fi
10660 }
10661
10662 test_101b() {
10663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10664         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10665
10666         local STRIPE_SIZE=1048576
10667         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10668
10669         if [ $SLOW == "yes" ]; then
10670                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10671         else
10672                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10673         fi
10674
10675         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10676
10677         # prepare the read-ahead file
10678         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10679         cancel_lru_locks osc
10680         for BIDX in 2 4 8 16 32 64 128 256
10681         do
10682                 local BSIZE=$((BIDX*4096))
10683                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10684                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10685                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10686                 $LCTL set_param -n llite.*.read_ahead_stats=0
10687                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10688                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10689                 cancel_lru_locks osc
10690                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10691         done
10692         cleanup_test101bc
10693         true
10694 }
10695 run_test 101b "check stride-io mode read-ahead ================="
10696
10697 test_101c() {
10698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10699
10700         local STRIPE_SIZE=1048576
10701         local FILE_LENGTH=$((STRIPE_SIZE*100))
10702         local nreads=10000
10703         local rsize=65536
10704         local osc_rpc_stats
10705
10706         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10707
10708         cancel_lru_locks osc
10709         $LCTL set_param osc.*.rpc_stats=0
10710         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10711         $LCTL get_param osc.*.rpc_stats
10712         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10713                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10714                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10715                 local size
10716
10717                 if [ $lines -le 20 ]; then
10718                         echo "continue debug"
10719                         continue
10720                 fi
10721                 for size in 1 2 4 8; do
10722                         local rpc=$(echo "$stats" |
10723                                     awk '($1 == "'$size':") {print $2; exit; }')
10724                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10725                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10726                 done
10727                 echo "$osc_rpc_stats check passed!"
10728         done
10729         cleanup_test101bc
10730         true
10731 }
10732 run_test 101c "check stripe_size aligned read-ahead"
10733
10734 test_101d() {
10735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10736
10737         local file=$DIR/$tfile
10738         local sz_MB=${FILESIZE_101d:-80}
10739         local ra_MB=${READAHEAD_MB:-40}
10740
10741         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10742         [ $free_MB -lt $sz_MB ] &&
10743                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10744
10745         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10746         $LFS setstripe -c -1 $file || error "setstripe failed"
10747
10748         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10749         echo Cancel LRU locks on lustre client to flush the client cache
10750         cancel_lru_locks osc
10751
10752         echo Disable read-ahead
10753         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10754         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10755         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10756         $LCTL get_param -n llite.*.max_read_ahead_mb
10757
10758         echo "Reading the test file $file with read-ahead disabled"
10759         local sz_KB=$((sz_MB * 1024 / 4))
10760         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10761         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10762         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10763                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10764
10765         echo "Cancel LRU locks on lustre client to flush the client cache"
10766         cancel_lru_locks osc
10767         echo Enable read-ahead with ${ra_MB}MB
10768         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10769
10770         echo "Reading the test file $file with read-ahead enabled"
10771         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10772                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10773
10774         echo "read-ahead disabled time read $raOFF"
10775         echo "read-ahead enabled time read $raON"
10776
10777         rm -f $file
10778         wait_delete_completed
10779
10780         # use awk for this check instead of bash because it handles decimals
10781         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10782                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10783 }
10784 run_test 101d "file read with and without read-ahead enabled"
10785
10786 test_101e() {
10787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10788
10789         local file=$DIR/$tfile
10790         local size_KB=500  #KB
10791         local count=100
10792         local bsize=1024
10793
10794         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10795         local need_KB=$((count * size_KB))
10796         [[ $free_KB -le $need_KB ]] &&
10797                 skip_env "Need free space $need_KB, have $free_KB"
10798
10799         echo "Creating $count ${size_KB}K test files"
10800         for ((i = 0; i < $count; i++)); do
10801                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10802         done
10803
10804         echo "Cancel LRU locks on lustre client to flush the client cache"
10805         cancel_lru_locks $OSC
10806
10807         echo "Reset readahead stats"
10808         $LCTL set_param -n llite.*.read_ahead_stats=0
10809
10810         for ((i = 0; i < $count; i++)); do
10811                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10812         done
10813
10814         $LCTL get_param llite.*.max_cached_mb
10815         $LCTL get_param llite.*.read_ahead_stats
10816         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10817                      get_named_value 'misses' | calc_total)
10818
10819         for ((i = 0; i < $count; i++)); do
10820                 rm -rf $file.$i 2>/dev/null
10821         done
10822
10823         #10000 means 20% reads are missing in readahead
10824         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10825 }
10826 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10827
10828 test_101f() {
10829         which iozone || skip_env "no iozone installed"
10830
10831         local old_debug=$($LCTL get_param debug)
10832         old_debug=${old_debug#*=}
10833         $LCTL set_param debug="reada mmap"
10834
10835         # create a test file
10836         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10837
10838         echo Cancel LRU locks on lustre client to flush the client cache
10839         cancel_lru_locks osc
10840
10841         echo Reset readahead stats
10842         $LCTL set_param -n llite.*.read_ahead_stats=0
10843
10844         echo mmap read the file with small block size
10845         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10846                 > /dev/null 2>&1
10847
10848         echo checking missing pages
10849         $LCTL get_param llite.*.read_ahead_stats
10850         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10851                         get_named_value 'misses' | calc_total)
10852
10853         $LCTL set_param debug="$old_debug"
10854         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10855         rm -f $DIR/$tfile
10856 }
10857 run_test 101f "check mmap read performance"
10858
10859 test_101g_brw_size_test() {
10860         local mb=$1
10861         local pages=$((mb * 1048576 / PAGE_SIZE))
10862         local file=$DIR/$tfile
10863
10864         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10865                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10866         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10867                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10868                         return 2
10869         done
10870
10871         stack_trap "rm -f $file" EXIT
10872         $LCTL set_param -n osc.*.rpc_stats=0
10873
10874         # 10 RPCs should be enough for the test
10875         local count=10
10876         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10877                 { error "dd write ${mb} MB blocks failed"; return 3; }
10878         cancel_lru_locks osc
10879         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10880                 { error "dd write ${mb} MB blocks failed"; return 4; }
10881
10882         # calculate number of full-sized read and write RPCs
10883         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10884                 sed -n '/pages per rpc/,/^$/p' |
10885                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10886                 END { print reads,writes }'))
10887         # allow one extra full-sized read RPC for async readahead
10888         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10889                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10890         [[ ${rpcs[1]} == $count ]] ||
10891                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10892 }
10893
10894 test_101g() {
10895         remote_ost_nodsh && skip "remote OST with nodsh"
10896
10897         local rpcs
10898         local osts=$(get_facets OST)
10899         local list=$(comma_list $(osts_nodes))
10900         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10901         local brw_size="obdfilter.*.brw_size"
10902
10903         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10904
10905         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10906
10907         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10908                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10909                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10910            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10911                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10912                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10913
10914                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10915                         suffix="M"
10916
10917                 if [[ $orig_mb -lt 16 ]]; then
10918                         save_lustre_params $osts "$brw_size" > $p
10919                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10920                                 error "set 16MB RPC size failed"
10921
10922                         echo "remount client to enable new RPC size"
10923                         remount_client $MOUNT || error "remount_client failed"
10924                 fi
10925
10926                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10927                 # should be able to set brw_size=12, but no rpc_stats for that
10928                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10929         fi
10930
10931         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10932
10933         if [[ $orig_mb -lt 16 ]]; then
10934                 restore_lustre_params < $p
10935                 remount_client $MOUNT || error "remount_client restore failed"
10936         fi
10937
10938         rm -f $p $DIR/$tfile
10939 }
10940 run_test 101g "Big bulk(4/16 MiB) readahead"
10941
10942 test_101h() {
10943         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10944
10945         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10946                 error "dd 70M file failed"
10947         echo Cancel LRU locks on lustre client to flush the client cache
10948         cancel_lru_locks osc
10949
10950         echo "Reset readahead stats"
10951         $LCTL set_param -n llite.*.read_ahead_stats 0
10952
10953         echo "Read 10M of data but cross 64M bundary"
10954         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10955         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10956                      get_named_value 'misses' | calc_total)
10957         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10958         rm -f $p $DIR/$tfile
10959 }
10960 run_test 101h "Readahead should cover current read window"
10961
10962 test_101i() {
10963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10964                 error "dd 10M file failed"
10965
10966         local max_per_file_mb=$($LCTL get_param -n \
10967                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10968         cancel_lru_locks osc
10969         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10970         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10971                 error "set max_read_ahead_per_file_mb to 1 failed"
10972
10973         echo "Reset readahead stats"
10974         $LCTL set_param llite.*.read_ahead_stats=0
10975
10976         dd if=$DIR/$tfile of=/dev/null bs=2M
10977
10978         $LCTL get_param llite.*.read_ahead_stats
10979         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10980                      awk '/misses/ { print $2 }')
10981         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10982         rm -f $DIR/$tfile
10983 }
10984 run_test 101i "allow current readahead to exceed reservation"
10985
10986 test_101j() {
10987         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10988                 error "setstripe $DIR/$tfile failed"
10989         local file_size=$((1048576 * 16))
10990         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10991         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10992
10993         echo Disable read-ahead
10994         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10995
10996         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10997         for blk in $PAGE_SIZE 1048576 $file_size; do
10998                 cancel_lru_locks osc
10999                 echo "Reset readahead stats"
11000                 $LCTL set_param -n llite.*.read_ahead_stats=0
11001                 local count=$(($file_size / $blk))
11002                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11003                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11004                              get_named_value 'failed.to.fast.read' | calc_total)
11005                 $LCTL get_param -n llite.*.read_ahead_stats
11006                 [ $miss -eq $count ] || error "expected $count got $miss"
11007         done
11008
11009         rm -f $p $DIR/$tfile
11010 }
11011 run_test 101j "A complete read block should be submitted when no RA"
11012
11013 setup_test102() {
11014         test_mkdir $DIR/$tdir
11015         chown $RUNAS_ID $DIR/$tdir
11016         STRIPE_SIZE=65536
11017         STRIPE_OFFSET=1
11018         STRIPE_COUNT=$OSTCOUNT
11019         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11020
11021         trap cleanup_test102 EXIT
11022         cd $DIR
11023         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11024         cd $DIR/$tdir
11025         for num in 1 2 3 4; do
11026                 for count in $(seq 1 $STRIPE_COUNT); do
11027                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11028                                 local size=`expr $STRIPE_SIZE \* $num`
11029                                 local file=file"$num-$idx-$count"
11030                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11031                         done
11032                 done
11033         done
11034
11035         cd $DIR
11036         $1 tar cf $TMP/f102.tar $tdir --xattrs
11037 }
11038
11039 cleanup_test102() {
11040         trap 0
11041         rm -f $TMP/f102.tar
11042         rm -rf $DIR/d0.sanity/d102
11043 }
11044
11045 test_102a() {
11046         [ "$UID" != 0 ] && skip "must run as root"
11047         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11048                 skip_env "must have user_xattr"
11049
11050         [ -z "$(which setfattr 2>/dev/null)" ] &&
11051                 skip_env "could not find setfattr"
11052
11053         local testfile=$DIR/$tfile
11054
11055         touch $testfile
11056         echo "set/get xattr..."
11057         setfattr -n trusted.name1 -v value1 $testfile ||
11058                 error "setfattr -n trusted.name1=value1 $testfile failed"
11059         getfattr -n trusted.name1 $testfile 2> /dev/null |
11060           grep "trusted.name1=.value1" ||
11061                 error "$testfile missing trusted.name1=value1"
11062
11063         setfattr -n user.author1 -v author1 $testfile ||
11064                 error "setfattr -n user.author1=author1 $testfile failed"
11065         getfattr -n user.author1 $testfile 2> /dev/null |
11066           grep "user.author1=.author1" ||
11067                 error "$testfile missing trusted.author1=author1"
11068
11069         echo "listxattr..."
11070         setfattr -n trusted.name2 -v value2 $testfile ||
11071                 error "$testfile unable to set trusted.name2"
11072         setfattr -n trusted.name3 -v value3 $testfile ||
11073                 error "$testfile unable to set trusted.name3"
11074         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11075             grep "trusted.name" | wc -l) -eq 3 ] ||
11076                 error "$testfile missing 3 trusted.name xattrs"
11077
11078         setfattr -n user.author2 -v author2 $testfile ||
11079                 error "$testfile unable to set user.author2"
11080         setfattr -n user.author3 -v author3 $testfile ||
11081                 error "$testfile unable to set user.author3"
11082         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11083             grep "user.author" | wc -l) -eq 3 ] ||
11084                 error "$testfile missing 3 user.author xattrs"
11085
11086         echo "remove xattr..."
11087         setfattr -x trusted.name1 $testfile ||
11088                 error "$testfile error deleting trusted.name1"
11089         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11090                 error "$testfile did not delete trusted.name1 xattr"
11091
11092         setfattr -x user.author1 $testfile ||
11093                 error "$testfile error deleting user.author1"
11094         echo "set lustre special xattr ..."
11095         $LFS setstripe -c1 $testfile
11096         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11097                 awk -F "=" '/trusted.lov/ { print $2 }' )
11098         setfattr -n "trusted.lov" -v $lovea $testfile ||
11099                 error "$testfile doesn't ignore setting trusted.lov again"
11100         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11101                 error "$testfile allow setting invalid trusted.lov"
11102         rm -f $testfile
11103 }
11104 run_test 102a "user xattr test =================================="
11105
11106 check_102b_layout() {
11107         local layout="$*"
11108         local testfile=$DIR/$tfile
11109
11110         echo "test layout '$layout'"
11111         $LFS setstripe $layout $testfile || error "setstripe failed"
11112         $LFS getstripe -y $testfile
11113
11114         echo "get/set/list trusted.lov xattr ..." # b=10930
11115         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11116         [[ "$value" =~ "trusted.lov" ]] ||
11117                 error "can't get trusted.lov from $testfile"
11118         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11119                 error "getstripe failed"
11120
11121         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11122
11123         value=$(cut -d= -f2 <<<$value)
11124         # LU-13168: truncated xattr should fail if short lov_user_md header
11125         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11126                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11127         for len in $lens; do
11128                 echo "setfattr $len $testfile.2"
11129                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11130                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11131         done
11132         local stripe_size=$($LFS getstripe -S $testfile.2)
11133         local stripe_count=$($LFS getstripe -c $testfile.2)
11134         [[ $stripe_size -eq 65536 ]] ||
11135                 error "stripe size $stripe_size != 65536"
11136         [[ $stripe_count -eq $stripe_count_orig ]] ||
11137                 error "stripe count $stripe_count != $stripe_count_orig"
11138         rm $testfile $testfile.2
11139 }
11140
11141 test_102b() {
11142         [ -z "$(which setfattr 2>/dev/null)" ] &&
11143                 skip_env "could not find setfattr"
11144         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11145
11146         # check plain layout
11147         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11148
11149         # and also check composite layout
11150         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11151
11152 }
11153 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11154
11155 test_102c() {
11156         [ -z "$(which setfattr 2>/dev/null)" ] &&
11157                 skip_env "could not find setfattr"
11158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11159
11160         # b10930: get/set/list lustre.lov xattr
11161         echo "get/set/list lustre.lov xattr ..."
11162         test_mkdir $DIR/$tdir
11163         chown $RUNAS_ID $DIR/$tdir
11164         local testfile=$DIR/$tdir/$tfile
11165         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11166                 error "setstripe failed"
11167         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11168                 error "getstripe failed"
11169         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11170         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11171
11172         local testfile2=${testfile}2
11173         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11174                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11175
11176         $RUNAS $MCREATE $testfile2
11177         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11178         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11179         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11180         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11181         [ $stripe_count -eq $STRIPECOUNT ] ||
11182                 error "stripe count $stripe_count != $STRIPECOUNT"
11183 }
11184 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11185
11186 compare_stripe_info1() {
11187         local stripe_index_all_zero=true
11188
11189         for num in 1 2 3 4; do
11190                 for count in $(seq 1 $STRIPE_COUNT); do
11191                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11192                                 local size=$((STRIPE_SIZE * num))
11193                                 local file=file"$num-$offset-$count"
11194                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11195                                 [[ $stripe_size -ne $size ]] &&
11196                                     error "$file: size $stripe_size != $size"
11197                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11198                                 # allow fewer stripes to be created, ORI-601
11199                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11200                                     error "$file: count $stripe_count != $count"
11201                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11202                                 [[ $stripe_index -ne 0 ]] &&
11203                                         stripe_index_all_zero=false
11204                         done
11205                 done
11206         done
11207         $stripe_index_all_zero &&
11208                 error "all files are being extracted starting from OST index 0"
11209         return 0
11210 }
11211
11212 have_xattrs_include() {
11213         tar --help | grep -q xattrs-include &&
11214                 echo --xattrs-include="lustre.*"
11215 }
11216
11217 test_102d() {
11218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11220
11221         XINC=$(have_xattrs_include)
11222         setup_test102
11223         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11224         cd $DIR/$tdir/$tdir
11225         compare_stripe_info1
11226 }
11227 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11228
11229 test_102f() {
11230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11231         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11232
11233         XINC=$(have_xattrs_include)
11234         setup_test102
11235         test_mkdir $DIR/$tdir.restore
11236         cd $DIR
11237         tar cf - --xattrs $tdir | tar xf - \
11238                 -C $DIR/$tdir.restore --xattrs $XINC
11239         cd $DIR/$tdir.restore/$tdir
11240         compare_stripe_info1
11241 }
11242 run_test 102f "tar copy files, not keep osts"
11243
11244 grow_xattr() {
11245         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11246                 skip "must have user_xattr"
11247         [ -z "$(which setfattr 2>/dev/null)" ] &&
11248                 skip_env "could not find setfattr"
11249         [ -z "$(which getfattr 2>/dev/null)" ] &&
11250                 skip_env "could not find getfattr"
11251
11252         local xsize=${1:-1024}  # in bytes
11253         local file=$DIR/$tfile
11254         local value="$(generate_string $xsize)"
11255         local xbig=trusted.big
11256         local toobig=$2
11257
11258         touch $file
11259         log "save $xbig on $file"
11260         if [ -z "$toobig" ]
11261         then
11262                 setfattr -n $xbig -v $value $file ||
11263                         error "saving $xbig on $file failed"
11264         else
11265                 setfattr -n $xbig -v $value $file &&
11266                         error "saving $xbig on $file succeeded"
11267                 return 0
11268         fi
11269
11270         local orig=$(get_xattr_value $xbig $file)
11271         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11272
11273         local xsml=trusted.sml
11274         log "save $xsml on $file"
11275         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11276
11277         local new=$(get_xattr_value $xbig $file)
11278         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11279
11280         log "grow $xsml on $file"
11281         setfattr -n $xsml -v "$value" $file ||
11282                 error "growing $xsml on $file failed"
11283
11284         new=$(get_xattr_value $xbig $file)
11285         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11286         log "$xbig still valid after growing $xsml"
11287
11288         rm -f $file
11289 }
11290
11291 test_102h() { # bug 15777
11292         grow_xattr 1024
11293 }
11294 run_test 102h "grow xattr from inside inode to external block"
11295
11296 test_102ha() {
11297         large_xattr_enabled || skip_env "ea_inode feature disabled"
11298
11299         echo "setting xattr of max xattr size: $(max_xattr_size)"
11300         grow_xattr $(max_xattr_size)
11301
11302         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11303         echo "This should fail:"
11304         grow_xattr $(($(max_xattr_size) + 10)) 1
11305 }
11306 run_test 102ha "grow xattr from inside inode to external inode"
11307
11308 test_102i() { # bug 17038
11309         [ -z "$(which getfattr 2>/dev/null)" ] &&
11310                 skip "could not find getfattr"
11311
11312         touch $DIR/$tfile
11313         ln -s $DIR/$tfile $DIR/${tfile}link
11314         getfattr -n trusted.lov $DIR/$tfile ||
11315                 error "lgetxattr on $DIR/$tfile failed"
11316         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11317                 grep -i "no such attr" ||
11318                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11319         rm -f $DIR/$tfile $DIR/${tfile}link
11320 }
11321 run_test 102i "lgetxattr test on symbolic link ============"
11322
11323 test_102j() {
11324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11325         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11326
11327         XINC=$(have_xattrs_include)
11328         setup_test102 "$RUNAS"
11329         chown $RUNAS_ID $DIR/$tdir
11330         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11331         cd $DIR/$tdir/$tdir
11332         compare_stripe_info1 "$RUNAS"
11333 }
11334 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11335
11336 test_102k() {
11337         [ -z "$(which setfattr 2>/dev/null)" ] &&
11338                 skip "could not find setfattr"
11339
11340         touch $DIR/$tfile
11341         # b22187 just check that does not crash for regular file.
11342         setfattr -n trusted.lov $DIR/$tfile
11343         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11344         local test_kdir=$DIR/$tdir
11345         test_mkdir $test_kdir
11346         local default_size=$($LFS getstripe -S $test_kdir)
11347         local default_count=$($LFS getstripe -c $test_kdir)
11348         local default_offset=$($LFS getstripe -i $test_kdir)
11349         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11350                 error 'dir setstripe failed'
11351         setfattr -n trusted.lov $test_kdir
11352         local stripe_size=$($LFS getstripe -S $test_kdir)
11353         local stripe_count=$($LFS getstripe -c $test_kdir)
11354         local stripe_offset=$($LFS getstripe -i $test_kdir)
11355         [ $stripe_size -eq $default_size ] ||
11356                 error "stripe size $stripe_size != $default_size"
11357         [ $stripe_count -eq $default_count ] ||
11358                 error "stripe count $stripe_count != $default_count"
11359         [ $stripe_offset -eq $default_offset ] ||
11360                 error "stripe offset $stripe_offset != $default_offset"
11361         rm -rf $DIR/$tfile $test_kdir
11362 }
11363 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11364
11365 test_102l() {
11366         [ -z "$(which getfattr 2>/dev/null)" ] &&
11367                 skip "could not find getfattr"
11368
11369         # LU-532 trusted. xattr is invisible to non-root
11370         local testfile=$DIR/$tfile
11371
11372         touch $testfile
11373
11374         echo "listxattr as user..."
11375         chown $RUNAS_ID $testfile
11376         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11377             grep -q "trusted" &&
11378                 error "$testfile trusted xattrs are user visible"
11379
11380         return 0;
11381 }
11382 run_test 102l "listxattr size test =================================="
11383
11384 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11385         local path=$DIR/$tfile
11386         touch $path
11387
11388         listxattr_size_check $path || error "listattr_size_check $path failed"
11389 }
11390 run_test 102m "Ensure listxattr fails on small bufffer ========"
11391
11392 cleanup_test102
11393
11394 getxattr() { # getxattr path name
11395         # Return the base64 encoding of the value of xattr name on path.
11396         local path=$1
11397         local name=$2
11398
11399         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11400         # file: $path
11401         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11402         #
11403         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11404
11405         getfattr --absolute-names --encoding=base64 --name=$name $path |
11406                 awk -F= -v name=$name '$1 == name {
11407                         print substr($0, index($0, "=") + 1);
11408         }'
11409 }
11410
11411 test_102n() { # LU-4101 mdt: protect internal xattrs
11412         [ -z "$(which setfattr 2>/dev/null)" ] &&
11413                 skip "could not find setfattr"
11414         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11415         then
11416                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11417         fi
11418
11419         local file0=$DIR/$tfile.0
11420         local file1=$DIR/$tfile.1
11421         local xattr0=$TMP/$tfile.0
11422         local xattr1=$TMP/$tfile.1
11423         local namelist="lov lma lmv link fid version som hsm"
11424         local name
11425         local value
11426
11427         rm -rf $file0 $file1 $xattr0 $xattr1
11428         touch $file0 $file1
11429
11430         # Get 'before' xattrs of $file1.
11431         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11432
11433         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11434                 namelist+=" lfsck_namespace"
11435         for name in $namelist; do
11436                 # Try to copy xattr from $file0 to $file1.
11437                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11438
11439                 setfattr --name=trusted.$name --value="$value" $file1 ||
11440                         error "setxattr 'trusted.$name' failed"
11441
11442                 # Try to set a garbage xattr.
11443                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11444
11445                 if [[ x$name == "xlov" ]]; then
11446                         setfattr --name=trusted.lov --value="$value" $file1 &&
11447                         error "setxattr invalid 'trusted.lov' success"
11448                 else
11449                         setfattr --name=trusted.$name --value="$value" $file1 ||
11450                                 error "setxattr invalid 'trusted.$name' failed"
11451                 fi
11452
11453                 # Try to remove the xattr from $file1. We don't care if this
11454                 # appears to succeed or fail, we just don't want there to be
11455                 # any changes or crashes.
11456                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11457         done
11458
11459         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11460         then
11461                 name="lfsck_ns"
11462                 # Try to copy xattr from $file0 to $file1.
11463                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11464
11465                 setfattr --name=trusted.$name --value="$value" $file1 ||
11466                         error "setxattr 'trusted.$name' failed"
11467
11468                 # Try to set a garbage xattr.
11469                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11470
11471                 setfattr --name=trusted.$name --value="$value" $file1 ||
11472                         error "setxattr 'trusted.$name' failed"
11473
11474                 # Try to remove the xattr from $file1. We don't care if this
11475                 # appears to succeed or fail, we just don't want there to be
11476                 # any changes or crashes.
11477                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11478         fi
11479
11480         # Get 'after' xattrs of file1.
11481         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11482
11483         if ! diff $xattr0 $xattr1; then
11484                 error "before and after xattrs of '$file1' differ"
11485         fi
11486
11487         rm -rf $file0 $file1 $xattr0 $xattr1
11488
11489         return 0
11490 }
11491 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11492
11493 test_102p() { # LU-4703 setxattr did not check ownership
11494         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11495                 skip "MDS needs to be at least 2.5.56"
11496
11497         local testfile=$DIR/$tfile
11498
11499         touch $testfile
11500
11501         echo "setfacl as user..."
11502         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11503         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11504
11505         echo "setfattr as user..."
11506         setfacl -m "u:$RUNAS_ID:---" $testfile
11507         $RUNAS setfattr -x system.posix_acl_access $testfile
11508         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11509 }
11510 run_test 102p "check setxattr(2) correctly fails without permission"
11511
11512 test_102q() {
11513         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11514                 skip "MDS needs to be at least 2.6.92"
11515
11516         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11517 }
11518 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11519
11520 test_102r() {
11521         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11522                 skip "MDS needs to be at least 2.6.93"
11523
11524         touch $DIR/$tfile || error "touch"
11525         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11526         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11527         rm $DIR/$tfile || error "rm"
11528
11529         #normal directory
11530         mkdir -p $DIR/$tdir || error "mkdir"
11531         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11532         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11533         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11534                 error "$testfile error deleting user.author1"
11535         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11536                 grep "user.$(basename $tdir)" &&
11537                 error "$tdir did not delete user.$(basename $tdir)"
11538         rmdir $DIR/$tdir || error "rmdir"
11539
11540         #striped directory
11541         test_mkdir $DIR/$tdir
11542         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11543         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11544         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11545                 error "$testfile error deleting user.author1"
11546         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11547                 grep "user.$(basename $tdir)" &&
11548                 error "$tdir did not delete user.$(basename $tdir)"
11549         rmdir $DIR/$tdir || error "rm striped dir"
11550 }
11551 run_test 102r "set EAs with empty values"
11552
11553 test_102s() {
11554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11555                 skip "MDS needs to be at least 2.11.52"
11556
11557         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11558
11559         save_lustre_params client "llite.*.xattr_cache" > $save
11560
11561         for cache in 0 1; do
11562                 lctl set_param llite.*.xattr_cache=$cache
11563
11564                 rm -f $DIR/$tfile
11565                 touch $DIR/$tfile || error "touch"
11566                 for prefix in lustre security system trusted user; do
11567                         # Note getxattr() may fail with 'Operation not
11568                         # supported' or 'No such attribute' depending
11569                         # on prefix and cache.
11570                         getfattr -n $prefix.n102s $DIR/$tfile &&
11571                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11572                 done
11573         done
11574
11575         restore_lustre_params < $save
11576 }
11577 run_test 102s "getting nonexistent xattrs should fail"
11578
11579 test_102t() {
11580         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11581                 skip "MDS needs to be at least 2.11.52"
11582
11583         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11584
11585         save_lustre_params client "llite.*.xattr_cache" > $save
11586
11587         for cache in 0 1; do
11588                 lctl set_param llite.*.xattr_cache=$cache
11589
11590                 for buf_size in 0 256; do
11591                         rm -f $DIR/$tfile
11592                         touch $DIR/$tfile || error "touch"
11593                         setfattr -n user.multiop $DIR/$tfile
11594                         $MULTIOP $DIR/$tfile oa$buf_size ||
11595                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11596                 done
11597         done
11598
11599         restore_lustre_params < $save
11600 }
11601 run_test 102t "zero length xattr values handled correctly"
11602
11603 run_acl_subtest()
11604 {
11605         local test=$LUSTRE/tests/acl/$1.test
11606         local tmp=$(mktemp -t $1-XXXXXX).test
11607         local bin=$2
11608         local dmn=$3
11609         local grp=$4
11610         local nbd=$5
11611         export LANG=C
11612
11613
11614         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11615         local sedgroups="-e s/:users/:$grp/g"
11616         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11617
11618         sed $sedusers $sedgroups < $test > $tmp
11619         stack_trap "rm -f $tmp"
11620         [[ -s $tmp ]] || error "sed failed to create test script"
11621
11622         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11623         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11624 }
11625
11626 test_103a() {
11627         [ "$UID" != 0 ] && skip "must run as root"
11628         $GSS && skip_env "could not run under gss"
11629         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11630                 skip_env "must have acl enabled"
11631         which setfacl || skip_env "could not find setfacl"
11632         remote_mds_nodsh && skip "remote MDS with nodsh"
11633
11634         ACLBIN=${ACLBIN:-"bin"}
11635         ACLDMN=${ACLDMN:-"daemon"}
11636         ACLGRP=${ACLGRP:-"users"}
11637         ACLNBD=${ACLNBD:-"nobody"}
11638
11639         if ! id $ACLBIN ||
11640            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11641                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11642                 ACLBIN=$USER0
11643                 if ! id $ACLBIN ; then
11644                         cat /etc/passwd
11645                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11646                 fi
11647         fi
11648         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11649            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11650                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11651                 ACLDMN=$USER1
11652                 if ! id $ACLDMN ; then
11653                         cat /etc/passwd
11654                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11655                 fi
11656         fi
11657         if ! getent group $ACLGRP; then
11658                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11659                 ACLGRP="$TSTUSR"
11660                 if ! getent group $ACLGRP; then
11661                         echo "cannot find group '$ACLGRP', adding it"
11662                         cat /etc/group
11663                         add_group 60000 $ACLGRP
11664                 fi
11665         fi
11666
11667         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11668         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11669         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11670
11671         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11672                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11673                 ACLGRP="$TSTUSR"
11674                 if ! getent group $ACLGRP; then
11675                         echo "cannot find group '$ACLGRP', adding it"
11676                         cat /etc/group
11677                         add_group 60000 $ACLGRP
11678                 fi
11679                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11680                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11681                         cat /etc/group
11682                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11683                 fi
11684         fi
11685
11686         gpasswd -a $ACLDMN $ACLBIN ||
11687                 error "setting client group failed"             # LU-5641
11688         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11689                 error "setting MDS group failed"                # LU-5641
11690
11691         declare -a identity_old
11692
11693         for num in $(seq $MDSCOUNT); do
11694                 switch_identity $num true || identity_old[$num]=$?
11695         done
11696
11697         SAVE_UMASK=$(umask)
11698         umask 0022
11699         mkdir -p $DIR/$tdir
11700         cd $DIR/$tdir
11701
11702         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11703         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11704         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11705         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11706         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11707         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11708         if ! id -u $ACLNBD ||
11709            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11710                 ACLNBD="nfsnobody"
11711                 if ! id -u $ACLNBD; then
11712                         ACLNBD=""
11713                 fi
11714         fi
11715         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11716                 add_group $(id -u $ACLNBD) $ACLNBD
11717                 if ! getent group $ACLNBD; then
11718                         ACLNBD=""
11719                 fi
11720         fi
11721         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11722            [[ -n "$ACLNBD" ]] && which setfattr; then
11723                 run_acl_subtest permissions_xattr \
11724                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11725         elif [[ -z "$ACLNBD" ]]; then
11726                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11727         else
11728                 echo "skip 'permission_xattr' test - missing setfattr command"
11729         fi
11730         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11731
11732         # inheritance test got from HP
11733         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11734         chmod +x make-tree || error "chmod +x failed"
11735         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11736         rm -f make-tree
11737
11738         echo "LU-974 ignore umask when acl is enabled..."
11739         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11740         if [ $MDSCOUNT -ge 2 ]; then
11741                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11742         fi
11743
11744         echo "LU-2561 newly created file is same size as directory..."
11745         if [ "$mds1_FSTYPE" != "zfs" ]; then
11746                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11747         else
11748                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11749         fi
11750
11751         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11752
11753         cd $SAVE_PWD
11754         umask $SAVE_UMASK
11755
11756         for num in $(seq $MDSCOUNT); do
11757                 if [ "${identity_old[$num]}" = 1 ]; then
11758                         switch_identity $num false || identity_old[$num]=$?
11759                 fi
11760         done
11761 }
11762 run_test 103a "acl test"
11763
11764 test_103b() {
11765         declare -a pids
11766         local U
11767
11768         for U in {0..511}; do
11769                 {
11770                 local O=$(printf "%04o" $U)
11771
11772                 umask $(printf "%04o" $((511 ^ $O)))
11773                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11774                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11775
11776                 (( $S == ($O & 0666) )) ||
11777                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11778
11779                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11780                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11781                 (( $S == ($O & 0666) )) ||
11782                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11783
11784                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11785                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11786                 (( $S == ($O & 0666) )) ||
11787                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11788                 rm -f $DIR/$tfile.[smp]$0
11789                 } &
11790                 local pid=$!
11791
11792                 # limit the concurrently running threads to 64. LU-11878
11793                 local idx=$((U % 64))
11794                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11795                 pids[idx]=$pid
11796         done
11797         wait
11798 }
11799 run_test 103b "umask lfs setstripe"
11800
11801 test_103c() {
11802         mkdir -p $DIR/$tdir
11803         cp -rp $DIR/$tdir $DIR/$tdir.bak
11804
11805         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11806                 error "$DIR/$tdir shouldn't contain default ACL"
11807         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11808                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11809         true
11810 }
11811 run_test 103c "'cp -rp' won't set empty acl"
11812
11813 test_103e() {
11814         local numacl
11815         local fileacl
11816         local saved_debug=$($LCTL get_param -n debug)
11817
11818         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11819                 skip "MDS needs to be at least 2.14.52"
11820
11821         large_xattr_enabled || skip_env "ea_inode feature disabled"
11822
11823         mkdir -p $DIR/$tdir
11824         # add big LOV EA to cause reply buffer overflow earlier
11825         $LFS setstripe -C 1000 $DIR/$tdir
11826         lctl set_param mdc.*-mdc*.stats=clear
11827
11828         $LCTL set_param debug=0
11829         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11830         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11831
11832         # add a large number of default ACLs (expect 8000+ for 2.13+)
11833         for U in {2..7000}; do
11834                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11835                         error "Able to add just $U default ACLs"
11836         done
11837         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11838         echo "$numacl default ACLs created"
11839
11840         stat $DIR/$tdir || error "Cannot stat directory"
11841         # check file creation
11842         touch $DIR/$tdir/$tfile ||
11843                 error "failed to create $tfile with $numacl default ACLs"
11844         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11845         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11846         echo "$fileacl ACLs were inherited"
11847         (( $fileacl == $numacl )) ||
11848                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11849         # check that new ACLs creation adds new ACLs to inherited ACLs
11850         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11851                 error "Cannot set new ACL"
11852         numacl=$((numacl + 1))
11853         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11854         (( $fileacl == $numacl )) ||
11855                 error "failed to add new ACL: $fileacl != $numacl as expected"
11856         # adds more ACLs to a file to reach their maximum at 8000+
11857         numacl=0
11858         for U in {20000..25000}; do
11859                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11860                 numacl=$((numacl + 1))
11861         done
11862         echo "Added $numacl more ACLs to the file"
11863         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11864         echo "Total $fileacl ACLs in file"
11865         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11866         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11867         rmdir $DIR/$tdir || error "Cannot remove directory"
11868 }
11869 run_test 103e "inheritance of big amount of default ACLs"
11870
11871 test_103f() {
11872         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11873                 skip "MDS needs to be at least 2.14.51"
11874
11875         large_xattr_enabled || skip_env "ea_inode feature disabled"
11876
11877         # enable changelog to consume more internal MDD buffers
11878         changelog_register
11879
11880         mkdir -p $DIR/$tdir
11881         # add big LOV EA
11882         $LFS setstripe -C 1000 $DIR/$tdir
11883         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11884         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11885         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11886         rmdir $DIR/$tdir || error "Cannot remove directory"
11887 }
11888 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11889
11890 test_104a() {
11891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11892
11893         touch $DIR/$tfile
11894         lfs df || error "lfs df failed"
11895         lfs df -ih || error "lfs df -ih failed"
11896         lfs df -h $DIR || error "lfs df -h $DIR failed"
11897         lfs df -i $DIR || error "lfs df -i $DIR failed"
11898         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11899         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11900
11901         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11902         lctl --device %$OSC deactivate
11903         lfs df || error "lfs df with deactivated OSC failed"
11904         lctl --device %$OSC activate
11905         # wait the osc back to normal
11906         wait_osc_import_ready client ost
11907
11908         lfs df || error "lfs df with reactivated OSC failed"
11909         rm -f $DIR/$tfile
11910 }
11911 run_test 104a "lfs df [-ih] [path] test ========================="
11912
11913 test_104b() {
11914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11915         [ $RUNAS_ID -eq $UID ] &&
11916                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11917
11918         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11919                         grep "Permission denied" | wc -l)))
11920         if [ $denied_cnt -ne 0 ]; then
11921                 error "lfs check servers test failed"
11922         fi
11923 }
11924 run_test 104b "$RUNAS lfs check servers test ===================="
11925
11926 #
11927 # Verify $1 is within range of $2.
11928 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11929 # $1 is <= 2% of $2. Else Fail.
11930 #
11931 value_in_range() {
11932         # Strip all units (M, G, T)
11933         actual=$(echo $1 | tr -d A-Z)
11934         expect=$(echo $2 | tr -d A-Z)
11935
11936         expect_lo=$(($expect * 98 / 100)) # 2% below
11937         expect_hi=$(($expect * 102 / 100)) # 2% above
11938
11939         # permit 2% drift above and below
11940         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11941 }
11942
11943 test_104c() {
11944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11945         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11946
11947         local ost_param="osd-zfs.$FSNAME-OST0000."
11948         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11949         local ofacets=$(get_facets OST)
11950         local mfacets=$(get_facets MDS)
11951         local saved_ost_blocks=
11952         local saved_mdt_blocks=
11953
11954         echo "Before recordsize change"
11955         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11956         df=($(df -h | grep "$MOUNT"$))
11957
11958         # For checking.
11959         echo "lfs output : ${lfs_df[*]}"
11960         echo "df  output : ${df[*]}"
11961
11962         for facet in ${ofacets//,/ }; do
11963                 if [ -z $saved_ost_blocks ]; then
11964                         saved_ost_blocks=$(do_facet $facet \
11965                                 lctl get_param -n $ost_param.blocksize)
11966                         echo "OST Blocksize: $saved_ost_blocks"
11967                 fi
11968                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11969                 do_facet $facet zfs set recordsize=32768 $ost
11970         done
11971
11972         # BS too small. Sufficient for functional testing.
11973         for facet in ${mfacets//,/ }; do
11974                 if [ -z $saved_mdt_blocks ]; then
11975                         saved_mdt_blocks=$(do_facet $facet \
11976                                 lctl get_param -n $mdt_param.blocksize)
11977                         echo "MDT Blocksize: $saved_mdt_blocks"
11978                 fi
11979                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11980                 do_facet $facet zfs set recordsize=32768 $mdt
11981         done
11982
11983         # Give new values chance to reflect change
11984         sleep 2
11985
11986         echo "After recordsize change"
11987         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11988         df_after=($(df -h | grep "$MOUNT"$))
11989
11990         # For checking.
11991         echo "lfs output : ${lfs_df_after[*]}"
11992         echo "df  output : ${df_after[*]}"
11993
11994         # Verify lfs df
11995         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11996                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11997         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11998                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11999         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12000                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12001
12002         # Verify df
12003         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12004                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12005         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12006                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12007         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12008                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12009
12010         # Restore MDT recordize back to original
12011         for facet in ${mfacets//,/ }; do
12012                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12013                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12014         done
12015
12016         # Restore OST recordize back to original
12017         for facet in ${ofacets//,/ }; do
12018                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12019                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12020         done
12021
12022         return 0
12023 }
12024 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12025
12026 test_104d() {
12027         (( $RUNAS_ID != $UID )) ||
12028                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12029
12030         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12031                 skip "lustre version doesn't support lctl dl with non-root"
12032
12033         # debugfs only allows root users to access files, so the
12034         # previous move of the "devices" file to debugfs broke
12035         # "lctl dl" for non-root users. The LU-9680 Netlink
12036         # interface again allows non-root users to list devices.
12037         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12038                 error "lctl dl doesn't work for non root"
12039
12040         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12041         [ "$ost_count" -eq $OSTCOUNT ]  ||
12042                 error "lctl dl reports wrong number of OST devices"
12043
12044         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12045         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12046                 error "lctl dl reports wrong number of MDT devices"
12047 }
12048 run_test 104d "$RUNAS lctl dl test"
12049
12050 test_105a() {
12051         # doesn't work on 2.4 kernels
12052         touch $DIR/$tfile
12053         if $(flock_is_enabled); then
12054                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12055         else
12056                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12057         fi
12058         rm -f $DIR/$tfile
12059 }
12060 run_test 105a "flock when mounted without -o flock test ========"
12061
12062 test_105b() {
12063         touch $DIR/$tfile
12064         if $(flock_is_enabled); then
12065                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12066         else
12067                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12068         fi
12069         rm -f $DIR/$tfile
12070 }
12071 run_test 105b "fcntl when mounted without -o flock test ========"
12072
12073 test_105c() {
12074         touch $DIR/$tfile
12075         if $(flock_is_enabled); then
12076                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12077         else
12078                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12079         fi
12080         rm -f $DIR/$tfile
12081 }
12082 run_test 105c "lockf when mounted without -o flock test"
12083
12084 test_105d() { # bug 15924
12085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12086
12087         test_mkdir $DIR/$tdir
12088         flock_is_enabled || skip_env "mount w/o flock enabled"
12089         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12090         $LCTL set_param fail_loc=0x80000315
12091         flocks_test 2 $DIR/$tdir
12092 }
12093 run_test 105d "flock race (should not freeze) ========"
12094
12095 test_105e() { # bug 22660 && 22040
12096         flock_is_enabled || skip_env "mount w/o flock enabled"
12097
12098         touch $DIR/$tfile
12099         flocks_test 3 $DIR/$tfile
12100 }
12101 run_test 105e "Two conflicting flocks from same process"
12102
12103 test_106() { #bug 10921
12104         test_mkdir $DIR/$tdir
12105         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12106         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12107 }
12108 run_test 106 "attempt exec of dir followed by chown of that dir"
12109
12110 test_107() {
12111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12112
12113         CDIR=`pwd`
12114         local file=core
12115
12116         cd $DIR
12117         rm -f $file
12118
12119         local save_pattern=$(sysctl -n kernel.core_pattern)
12120         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12121         sysctl -w kernel.core_pattern=$file
12122         sysctl -w kernel.core_uses_pid=0
12123
12124         ulimit -c unlimited
12125         sleep 60 &
12126         SLEEPPID=$!
12127
12128         sleep 1
12129
12130         kill -s 11 $SLEEPPID
12131         wait $SLEEPPID
12132         if [ -e $file ]; then
12133                 size=`stat -c%s $file`
12134                 [ $size -eq 0 ] && error "Fail to create core file $file"
12135         else
12136                 error "Fail to create core file $file"
12137         fi
12138         rm -f $file
12139         sysctl -w kernel.core_pattern=$save_pattern
12140         sysctl -w kernel.core_uses_pid=$save_uses_pid
12141         cd $CDIR
12142 }
12143 run_test 107 "Coredump on SIG"
12144
12145 test_110() {
12146         test_mkdir $DIR/$tdir
12147         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12148         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12149                 error "mkdir with 256 char should fail, but did not"
12150         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12151                 error "create with 255 char failed"
12152         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12153                 error "create with 256 char should fail, but did not"
12154
12155         ls -l $DIR/$tdir
12156         rm -rf $DIR/$tdir
12157 }
12158 run_test 110 "filename length checking"
12159
12160 #
12161 # Purpose: To verify dynamic thread (OSS) creation.
12162 #
12163 test_115() {
12164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12165         remote_ost_nodsh && skip "remote OST with nodsh"
12166
12167         # Lustre does not stop service threads once they are started.
12168         # Reset number of running threads to default.
12169         stopall
12170         setupall
12171
12172         local OSTIO_pre
12173         local save_params="$TMP/sanity-$TESTNAME.parameters"
12174
12175         # Get ll_ost_io count before I/O
12176         OSTIO_pre=$(do_facet ost1 \
12177                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12178         # Exit if lustre is not running (ll_ost_io not running).
12179         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12180
12181         echo "Starting with $OSTIO_pre threads"
12182         local thread_max=$((OSTIO_pre * 2))
12183         local rpc_in_flight=$((thread_max * 2))
12184         # this is limited to OSC_MAX_RIF_MAX (256)
12185         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12186         thread_max=$((rpc_in_flight / 2))
12187         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12188                 return
12189
12190         # Number of I/O Process proposed to be started.
12191         local nfiles
12192         local facets=$(get_facets OST)
12193
12194         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12195         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12196
12197         # Set in_flight to $rpc_in_flight
12198         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12199                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12200         nfiles=${rpc_in_flight}
12201         # Set ost thread_max to $thread_max
12202         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12203
12204         # 5 Minutes should be sufficient for max number of OSS
12205         # threads(thread_max) to be created.
12206         local timeout=300
12207
12208         # Start I/O.
12209         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12210         test_mkdir $DIR/$tdir
12211         for i in $(seq $nfiles); do
12212                 local file=$DIR/$tdir/${tfile}-$i
12213                 $LFS setstripe -c -1 -i 0 $file
12214                 ($WTL $file $timeout)&
12215         done
12216
12217         # I/O Started - Wait for thread_started to reach thread_max or report
12218         # error if thread_started is more than thread_max.
12219         echo "Waiting for thread_started to reach thread_max"
12220         local thread_started=0
12221         local end_time=$((SECONDS + timeout))
12222
12223         while [ $SECONDS -le $end_time ] ; do
12224                 echo -n "."
12225                 # Get ost i/o thread_started count.
12226                 thread_started=$(do_facet ost1 \
12227                         "$LCTL get_param \
12228                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12229                 # Break out if thread_started is equal/greater than thread_max
12230                 if [[ $thread_started -ge $thread_max ]]; then
12231                         echo ll_ost_io thread_started $thread_started, \
12232                                 equal/greater than thread_max $thread_max
12233                         break
12234                 fi
12235                 sleep 1
12236         done
12237
12238         # Cleanup - We have the numbers, Kill i/o jobs if running.
12239         jobcount=($(jobs -p))
12240         for i in $(seq 0 $((${#jobcount[@]}-1)))
12241         do
12242                 kill -9 ${jobcount[$i]}
12243                 if [ $? -ne 0 ] ; then
12244                         echo Warning: \
12245                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12246                 fi
12247         done
12248
12249         # Cleanup files left by WTL binary.
12250         for i in $(seq $nfiles); do
12251                 local file=$DIR/$tdir/${tfile}-$i
12252                 rm -rf $file
12253                 if [ $? -ne 0 ] ; then
12254                         echo "Warning: Failed to delete file $file"
12255                 fi
12256         done
12257
12258         restore_lustre_params <$save_params
12259         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12260
12261         # Error out if no new thread has started or Thread started is greater
12262         # than thread max.
12263         if [[ $thread_started -le $OSTIO_pre ||
12264                         $thread_started -gt $thread_max ]]; then
12265                 error "ll_ost_io: thread_started $thread_started" \
12266                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12267                       "No new thread started or thread started greater " \
12268                       "than thread_max."
12269         fi
12270 }
12271 run_test 115 "verify dynamic thread creation===================="
12272
12273 test_116a() { # was previously test_116()
12274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12275         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12276         remote_mds_nodsh && skip "remote MDS with nodsh"
12277
12278         echo -n "Free space priority "
12279         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12280                 head -n1
12281         declare -a AVAIL
12282         free_min_max
12283
12284         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12285         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12286         stack_trap simple_cleanup_common
12287
12288         # Check if we need to generate uneven OSTs
12289         test_mkdir -p $DIR/$tdir/OST${MINI}
12290         local FILL=$((MINV / 4))
12291         local DIFF=$((MAXV - MINV))
12292         local DIFF2=$((DIFF * 100 / MINV))
12293
12294         local threshold=$(do_facet $SINGLEMDS \
12295                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12296         threshold=${threshold%%%}
12297         echo -n "Check for uneven OSTs: "
12298         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12299
12300         if [[ $DIFF2 -gt $threshold ]]; then
12301                 echo "ok"
12302                 echo "Don't need to fill OST$MINI"
12303         else
12304                 # generate uneven OSTs. Write 2% over the QOS threshold value
12305                 echo "no"
12306                 DIFF=$((threshold - DIFF2 + 2))
12307                 DIFF2=$((MINV * DIFF / 100))
12308                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12309                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12310                         error "setstripe failed"
12311                 DIFF=$((DIFF2 / 2048))
12312                 i=0
12313                 while [ $i -lt $DIFF ]; do
12314                         i=$((i + 1))
12315                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12316                                 bs=2M count=1 2>/dev/null
12317                         echo -n .
12318                 done
12319                 echo .
12320                 sync
12321                 sleep_maxage
12322                 free_min_max
12323         fi
12324
12325         DIFF=$((MAXV - MINV))
12326         DIFF2=$((DIFF * 100 / MINV))
12327         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12328         if [ $DIFF2 -gt $threshold ]; then
12329                 echo "ok"
12330         else
12331                 skip "QOS imbalance criteria not met"
12332         fi
12333
12334         MINI1=$MINI
12335         MINV1=$MINV
12336         MAXI1=$MAXI
12337         MAXV1=$MAXV
12338
12339         # now fill using QOS
12340         $LFS setstripe -c 1 $DIR/$tdir
12341         FILL=$((FILL / 200))
12342         if [ $FILL -gt 600 ]; then
12343                 FILL=600
12344         fi
12345         echo "writing $FILL files to QOS-assigned OSTs"
12346         i=0
12347         while [ $i -lt $FILL ]; do
12348                 i=$((i + 1))
12349                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12350                         count=1 2>/dev/null
12351                 echo -n .
12352         done
12353         echo "wrote $i 200k files"
12354         sync
12355         sleep_maxage
12356
12357         echo "Note: free space may not be updated, so measurements might be off"
12358         free_min_max
12359         DIFF2=$((MAXV - MINV))
12360         echo "free space delta: orig $DIFF final $DIFF2"
12361         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12362         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12363         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12364         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12365         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12366         if [[ $DIFF -gt 0 ]]; then
12367                 FILL=$((DIFF2 * 100 / DIFF - 100))
12368                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12369         fi
12370
12371         # Figure out which files were written where
12372         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12373                awk '/'$MINI1': / {print $2; exit}')
12374         echo $UUID
12375         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12376         echo "$MINC files created on smaller OST $MINI1"
12377         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12378                awk '/'$MAXI1': / {print $2; exit}')
12379         echo $UUID
12380         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12381         echo "$MAXC files created on larger OST $MAXI1"
12382         if [[ $MINC -gt 0 ]]; then
12383                 FILL=$((MAXC * 100 / MINC - 100))
12384                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12385         fi
12386         [[ $MAXC -gt $MINC ]] ||
12387                 error_ignore LU-9 "stripe QOS didn't balance free space"
12388 }
12389 run_test 116a "stripe QOS: free space balance ==================="
12390
12391 test_116b() { # LU-2093
12392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12393         remote_mds_nodsh && skip "remote MDS with nodsh"
12394
12395 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12396         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12397                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12398         [ -z "$old_rr" ] && skip "no QOS"
12399         do_facet $SINGLEMDS lctl set_param \
12400                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12401         mkdir -p $DIR/$tdir
12402         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12403         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12404         do_facet $SINGLEMDS lctl set_param fail_loc=0
12405         rm -rf $DIR/$tdir
12406         do_facet $SINGLEMDS lctl set_param \
12407                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12408 }
12409 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12410
12411 test_117() # bug 10891
12412 {
12413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12414
12415         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12416         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12417         lctl set_param fail_loc=0x21e
12418         > $DIR/$tfile || error "truncate failed"
12419         lctl set_param fail_loc=0
12420         echo "Truncate succeeded."
12421         rm -f $DIR/$tfile
12422 }
12423 run_test 117 "verify osd extend =========="
12424
12425 NO_SLOW_RESENDCOUNT=4
12426 export OLD_RESENDCOUNT=""
12427 set_resend_count () {
12428         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12429         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12430         lctl set_param -n $PROC_RESENDCOUNT $1
12431         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12432 }
12433
12434 # for reduce test_118* time (b=14842)
12435 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12436
12437 # Reset async IO behavior after error case
12438 reset_async() {
12439         FILE=$DIR/reset_async
12440
12441         # Ensure all OSCs are cleared
12442         $LFS setstripe -c -1 $FILE
12443         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12444         sync
12445         rm $FILE
12446 }
12447
12448 test_118a() #bug 11710
12449 {
12450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12451
12452         reset_async
12453
12454         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12455         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12456         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12457
12458         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12459                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12460                 return 1;
12461         fi
12462         rm -f $DIR/$tfile
12463 }
12464 run_test 118a "verify O_SYNC works =========="
12465
12466 test_118b()
12467 {
12468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12469         remote_ost_nodsh && skip "remote OST with nodsh"
12470
12471         reset_async
12472
12473         #define OBD_FAIL_SRV_ENOENT 0x217
12474         set_nodes_failloc "$(osts_nodes)" 0x217
12475         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12476         RC=$?
12477         set_nodes_failloc "$(osts_nodes)" 0
12478         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12479         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12480                     grep -c writeback)
12481
12482         if [[ $RC -eq 0 ]]; then
12483                 error "Must return error due to dropped pages, rc=$RC"
12484                 return 1;
12485         fi
12486
12487         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12488                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12489                 return 1;
12490         fi
12491
12492         echo "Dirty pages not leaked on ENOENT"
12493
12494         # Due to the above error the OSC will issue all RPCs syncronously
12495         # until a subsequent RPC completes successfully without error.
12496         $MULTIOP $DIR/$tfile Ow4096yc
12497         rm -f $DIR/$tfile
12498
12499         return 0
12500 }
12501 run_test 118b "Reclaim dirty pages on fatal error =========="
12502
12503 test_118c()
12504 {
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506
12507         # for 118c, restore the original resend count, LU-1940
12508         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12509                                 set_resend_count $OLD_RESENDCOUNT
12510         remote_ost_nodsh && skip "remote OST with nodsh"
12511
12512         reset_async
12513
12514         #define OBD_FAIL_OST_EROFS               0x216
12515         set_nodes_failloc "$(osts_nodes)" 0x216
12516
12517         # multiop should block due to fsync until pages are written
12518         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12519         MULTIPID=$!
12520         sleep 1
12521
12522         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12523                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12524         fi
12525
12526         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12527                     grep -c writeback)
12528         if [[ $WRITEBACK -eq 0 ]]; then
12529                 error "No page in writeback, writeback=$WRITEBACK"
12530         fi
12531
12532         set_nodes_failloc "$(osts_nodes)" 0
12533         wait $MULTIPID
12534         RC=$?
12535         if [[ $RC -ne 0 ]]; then
12536                 error "Multiop fsync failed, rc=$RC"
12537         fi
12538
12539         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12540         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12541                     grep -c writeback)
12542         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12543                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12544         fi
12545
12546         rm -f $DIR/$tfile
12547         echo "Dirty pages flushed via fsync on EROFS"
12548         return 0
12549 }
12550 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12551
12552 # continue to use small resend count to reduce test_118* time (b=14842)
12553 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12554
12555 test_118d()
12556 {
12557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12558         remote_ost_nodsh && skip "remote OST with nodsh"
12559
12560         reset_async
12561
12562         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12563         set_nodes_failloc "$(osts_nodes)" 0x214
12564         # multiop should block due to fsync until pages are written
12565         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12566         MULTIPID=$!
12567         sleep 1
12568
12569         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12570                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12571         fi
12572
12573         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12574                     grep -c writeback)
12575         if [[ $WRITEBACK -eq 0 ]]; then
12576                 error "No page in writeback, writeback=$WRITEBACK"
12577         fi
12578
12579         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12580         set_nodes_failloc "$(osts_nodes)" 0
12581
12582         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12583         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12584                     grep -c writeback)
12585         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12586                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12587         fi
12588
12589         rm -f $DIR/$tfile
12590         echo "Dirty pages gaurenteed flushed via fsync"
12591         return 0
12592 }
12593 run_test 118d "Fsync validation inject a delay of the bulk =========="
12594
12595 test_118f() {
12596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12597
12598         reset_async
12599
12600         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12601         lctl set_param fail_loc=0x8000040a
12602
12603         # Should simulate EINVAL error which is fatal
12604         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12605         RC=$?
12606         if [[ $RC -eq 0 ]]; then
12607                 error "Must return error due to dropped pages, rc=$RC"
12608         fi
12609
12610         lctl set_param fail_loc=0x0
12611
12612         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12613         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12614         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12615                     grep -c writeback)
12616         if [[ $LOCKED -ne 0 ]]; then
12617                 error "Locked pages remain in cache, locked=$LOCKED"
12618         fi
12619
12620         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12621                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12622         fi
12623
12624         rm -f $DIR/$tfile
12625         echo "No pages locked after fsync"
12626
12627         reset_async
12628         return 0
12629 }
12630 run_test 118f "Simulate unrecoverable OSC side error =========="
12631
12632 test_118g() {
12633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12634
12635         reset_async
12636
12637         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12638         lctl set_param fail_loc=0x406
12639
12640         # simulate local -ENOMEM
12641         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12642         RC=$?
12643
12644         lctl set_param fail_loc=0
12645         if [[ $RC -eq 0 ]]; then
12646                 error "Must return error due to dropped pages, rc=$RC"
12647         fi
12648
12649         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12650         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12651         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12652                         grep -c writeback)
12653         if [[ $LOCKED -ne 0 ]]; then
12654                 error "Locked pages remain in cache, locked=$LOCKED"
12655         fi
12656
12657         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12658                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12659         fi
12660
12661         rm -f $DIR/$tfile
12662         echo "No pages locked after fsync"
12663
12664         reset_async
12665         return 0
12666 }
12667 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12668
12669 test_118h() {
12670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12671         remote_ost_nodsh && skip "remote OST with nodsh"
12672
12673         reset_async
12674
12675         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12676         set_nodes_failloc "$(osts_nodes)" 0x20e
12677         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12678         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12679         RC=$?
12680
12681         set_nodes_failloc "$(osts_nodes)" 0
12682         if [[ $RC -eq 0 ]]; then
12683                 error "Must return error due to dropped pages, rc=$RC"
12684         fi
12685
12686         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12687         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12688         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12689                     grep -c writeback)
12690         if [[ $LOCKED -ne 0 ]]; then
12691                 error "Locked pages remain in cache, locked=$LOCKED"
12692         fi
12693
12694         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12695                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12696         fi
12697
12698         rm -f $DIR/$tfile
12699         echo "No pages locked after fsync"
12700
12701         return 0
12702 }
12703 run_test 118h "Verify timeout in handling recoverables errors  =========="
12704
12705 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12706
12707 test_118i() {
12708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12709         remote_ost_nodsh && skip "remote OST with nodsh"
12710
12711         reset_async
12712
12713         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12714         set_nodes_failloc "$(osts_nodes)" 0x20e
12715
12716         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12717         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12718         PID=$!
12719         sleep 5
12720         set_nodes_failloc "$(osts_nodes)" 0
12721
12722         wait $PID
12723         RC=$?
12724         if [[ $RC -ne 0 ]]; then
12725                 error "got error, but should be not, rc=$RC"
12726         fi
12727
12728         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12729         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12730         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12731         if [[ $LOCKED -ne 0 ]]; then
12732                 error "Locked pages remain in cache, locked=$LOCKED"
12733         fi
12734
12735         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12736                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12737         fi
12738
12739         rm -f $DIR/$tfile
12740         echo "No pages locked after fsync"
12741
12742         return 0
12743 }
12744 run_test 118i "Fix error before timeout in recoverable error  =========="
12745
12746 [ "$SLOW" = "no" ] && set_resend_count 4
12747
12748 test_118j() {
12749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12750         remote_ost_nodsh && skip "remote OST with nodsh"
12751
12752         reset_async
12753
12754         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12755         set_nodes_failloc "$(osts_nodes)" 0x220
12756
12757         # return -EIO from OST
12758         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12759         RC=$?
12760         set_nodes_failloc "$(osts_nodes)" 0x0
12761         if [[ $RC -eq 0 ]]; then
12762                 error "Must return error due to dropped pages, rc=$RC"
12763         fi
12764
12765         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12766         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12767         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12768         if [[ $LOCKED -ne 0 ]]; then
12769                 error "Locked pages remain in cache, locked=$LOCKED"
12770         fi
12771
12772         # in recoverable error on OST we want resend and stay until it finished
12773         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12774                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12775         fi
12776
12777         rm -f $DIR/$tfile
12778         echo "No pages locked after fsync"
12779
12780         return 0
12781 }
12782 run_test 118j "Simulate unrecoverable OST side error =========="
12783
12784 test_118k()
12785 {
12786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12787         remote_ost_nodsh && skip "remote OSTs with nodsh"
12788
12789         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12790         set_nodes_failloc "$(osts_nodes)" 0x20e
12791         test_mkdir $DIR/$tdir
12792
12793         for ((i=0;i<10;i++)); do
12794                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12795                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12796                 SLEEPPID=$!
12797                 sleep 0.500s
12798                 kill $SLEEPPID
12799                 wait $SLEEPPID
12800         done
12801
12802         set_nodes_failloc "$(osts_nodes)" 0
12803         rm -rf $DIR/$tdir
12804 }
12805 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12806
12807 test_118l() # LU-646
12808 {
12809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12810
12811         test_mkdir $DIR/$tdir
12812         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12813         rm -rf $DIR/$tdir
12814 }
12815 run_test 118l "fsync dir"
12816
12817 test_118m() # LU-3066
12818 {
12819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12820
12821         test_mkdir $DIR/$tdir
12822         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12823         rm -rf $DIR/$tdir
12824 }
12825 run_test 118m "fdatasync dir ========="
12826
12827 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12828
12829 test_118n()
12830 {
12831         local begin
12832         local end
12833
12834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12835         remote_ost_nodsh && skip "remote OSTs with nodsh"
12836
12837         # Sleep to avoid a cached response.
12838         #define OBD_STATFS_CACHE_SECONDS 1
12839         sleep 2
12840
12841         # Inject a 10 second delay in the OST_STATFS handler.
12842         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12843         set_nodes_failloc "$(osts_nodes)" 0x242
12844
12845         begin=$SECONDS
12846         stat --file-system $MOUNT > /dev/null
12847         end=$SECONDS
12848
12849         set_nodes_failloc "$(osts_nodes)" 0
12850
12851         if ((end - begin > 20)); then
12852             error "statfs took $((end - begin)) seconds, expected 10"
12853         fi
12854 }
12855 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12856
12857 test_119a() # bug 11737
12858 {
12859         BSIZE=$((512 * 1024))
12860         directio write $DIR/$tfile 0 1 $BSIZE
12861         # We ask to read two blocks, which is more than a file size.
12862         # directio will indicate an error when requested and actual
12863         # sizes aren't equeal (a normal situation in this case) and
12864         # print actual read amount.
12865         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12866         if [ "$NOB" != "$BSIZE" ]; then
12867                 error "read $NOB bytes instead of $BSIZE"
12868         fi
12869         rm -f $DIR/$tfile
12870 }
12871 run_test 119a "Short directIO read must return actual read amount"
12872
12873 test_119b() # bug 11737
12874 {
12875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12876
12877         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12878         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12879         sync
12880         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12881                 error "direct read failed"
12882         rm -f $DIR/$tfile
12883 }
12884 run_test 119b "Sparse directIO read must return actual read amount"
12885
12886 test_119c() # bug 13099
12887 {
12888         BSIZE=1048576
12889         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12890         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12891         rm -f $DIR/$tfile
12892 }
12893 run_test 119c "Testing for direct read hitting hole"
12894
12895 test_119d() # bug 15950
12896 {
12897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12898
12899         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12900         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12901         BSIZE=1048576
12902         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12903         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12904         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12905         lctl set_param fail_loc=0x40d
12906         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12907         pid_dio=$!
12908         sleep 1
12909         cat $DIR/$tfile > /dev/null &
12910         lctl set_param fail_loc=0
12911         pid_reads=$!
12912         wait $pid_dio
12913         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12914         sleep 2
12915         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12916         error "the read rpcs have not completed in 2s"
12917         rm -f $DIR/$tfile
12918         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12919 }
12920 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12921
12922 test_120a() {
12923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12924         remote_mds_nodsh && skip "remote MDS with nodsh"
12925         test_mkdir -i0 -c1 $DIR/$tdir
12926         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12927                 skip_env "no early lock cancel on server"
12928
12929         lru_resize_disable mdc
12930         lru_resize_disable osc
12931         cancel_lru_locks mdc
12932         # asynchronous object destroy at MDT could cause bl ast to client
12933         cancel_lru_locks osc
12934
12935         stat $DIR/$tdir > /dev/null
12936         can1=$(do_facet mds1 \
12937                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12938                awk '/ldlm_cancel/ {print $2}')
12939         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12940                awk '/ldlm_bl_callback/ {print $2}')
12941         test_mkdir -i0 -c1 $DIR/$tdir/d1
12942         can2=$(do_facet mds1 \
12943                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12944                awk '/ldlm_cancel/ {print $2}')
12945         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12946                awk '/ldlm_bl_callback/ {print $2}')
12947         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12948         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12949         lru_resize_enable mdc
12950         lru_resize_enable osc
12951 }
12952 run_test 120a "Early Lock Cancel: mkdir test"
12953
12954 test_120b() {
12955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12956         remote_mds_nodsh && skip "remote MDS with nodsh"
12957         test_mkdir $DIR/$tdir
12958         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12959                 skip_env "no early lock cancel on server"
12960
12961         lru_resize_disable mdc
12962         lru_resize_disable osc
12963         cancel_lru_locks mdc
12964         stat $DIR/$tdir > /dev/null
12965         can1=$(do_facet $SINGLEMDS \
12966                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12967                awk '/ldlm_cancel/ {print $2}')
12968         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12969                awk '/ldlm_bl_callback/ {print $2}')
12970         touch $DIR/$tdir/f1
12971         can2=$(do_facet $SINGLEMDS \
12972                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12973                awk '/ldlm_cancel/ {print $2}')
12974         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12975                awk '/ldlm_bl_callback/ {print $2}')
12976         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12977         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12978         lru_resize_enable mdc
12979         lru_resize_enable osc
12980 }
12981 run_test 120b "Early Lock Cancel: create test"
12982
12983 test_120c() {
12984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12985         remote_mds_nodsh && skip "remote MDS with nodsh"
12986         test_mkdir -i0 -c1 $DIR/$tdir
12987         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12988                 skip "no early lock cancel on server"
12989
12990         lru_resize_disable mdc
12991         lru_resize_disable osc
12992         test_mkdir -i0 -c1 $DIR/$tdir/d1
12993         test_mkdir -i0 -c1 $DIR/$tdir/d2
12994         touch $DIR/$tdir/d1/f1
12995         cancel_lru_locks mdc
12996         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12997         can1=$(do_facet mds1 \
12998                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12999                awk '/ldlm_cancel/ {print $2}')
13000         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13001                awk '/ldlm_bl_callback/ {print $2}')
13002         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13003         can2=$(do_facet mds1 \
13004                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13005                awk '/ldlm_cancel/ {print $2}')
13006         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13007                awk '/ldlm_bl_callback/ {print $2}')
13008         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13009         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13010         lru_resize_enable mdc
13011         lru_resize_enable osc
13012 }
13013 run_test 120c "Early Lock Cancel: link test"
13014
13015 test_120d() {
13016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13017         remote_mds_nodsh && skip "remote MDS with nodsh"
13018         test_mkdir -i0 -c1 $DIR/$tdir
13019         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13020                 skip_env "no early lock cancel on server"
13021
13022         lru_resize_disable mdc
13023         lru_resize_disable osc
13024         touch $DIR/$tdir
13025         cancel_lru_locks mdc
13026         stat $DIR/$tdir > /dev/null
13027         can1=$(do_facet mds1 \
13028                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13029                awk '/ldlm_cancel/ {print $2}')
13030         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13031                awk '/ldlm_bl_callback/ {print $2}')
13032         chmod a+x $DIR/$tdir
13033         can2=$(do_facet mds1 \
13034                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13035                awk '/ldlm_cancel/ {print $2}')
13036         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13037                awk '/ldlm_bl_callback/ {print $2}')
13038         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13039         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13040         lru_resize_enable mdc
13041         lru_resize_enable osc
13042 }
13043 run_test 120d "Early Lock Cancel: setattr test"
13044
13045 test_120e() {
13046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13047         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13048                 skip_env "no early lock cancel on server"
13049         remote_mds_nodsh && skip "remote MDS with nodsh"
13050
13051         local dlmtrace_set=false
13052
13053         test_mkdir -i0 -c1 $DIR/$tdir
13054         lru_resize_disable mdc
13055         lru_resize_disable osc
13056         ! $LCTL get_param debug | grep -q dlmtrace &&
13057                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13058         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13059         cancel_lru_locks mdc
13060         cancel_lru_locks osc
13061         dd if=$DIR/$tdir/f1 of=/dev/null
13062         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13063         # XXX client can not do early lock cancel of OST lock
13064         # during unlink (LU-4206), so cancel osc lock now.
13065         sleep 2
13066         cancel_lru_locks osc
13067         can1=$(do_facet mds1 \
13068                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13069                awk '/ldlm_cancel/ {print $2}')
13070         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13071                awk '/ldlm_bl_callback/ {print $2}')
13072         unlink $DIR/$tdir/f1
13073         sleep 5
13074         can2=$(do_facet mds1 \
13075                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13076                awk '/ldlm_cancel/ {print $2}')
13077         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13078                awk '/ldlm_bl_callback/ {print $2}')
13079         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13080                 $LCTL dk $TMP/cancel.debug.txt
13081         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13082                 $LCTL dk $TMP/blocking.debug.txt
13083         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13084         lru_resize_enable mdc
13085         lru_resize_enable osc
13086 }
13087 run_test 120e "Early Lock Cancel: unlink test"
13088
13089 test_120f() {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13092                 skip_env "no early lock cancel on server"
13093         remote_mds_nodsh && skip "remote MDS with nodsh"
13094
13095         test_mkdir -i0 -c1 $DIR/$tdir
13096         lru_resize_disable mdc
13097         lru_resize_disable osc
13098         test_mkdir -i0 -c1 $DIR/$tdir/d1
13099         test_mkdir -i0 -c1 $DIR/$tdir/d2
13100         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13101         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13102         cancel_lru_locks mdc
13103         cancel_lru_locks osc
13104         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13105         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13106         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13107         # XXX client can not do early lock cancel of OST lock
13108         # during rename (LU-4206), so cancel osc lock now.
13109         sleep 2
13110         cancel_lru_locks osc
13111         can1=$(do_facet mds1 \
13112                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13113                awk '/ldlm_cancel/ {print $2}')
13114         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13115                awk '/ldlm_bl_callback/ {print $2}')
13116         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13117         sleep 5
13118         can2=$(do_facet mds1 \
13119                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13120                awk '/ldlm_cancel/ {print $2}')
13121         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13122                awk '/ldlm_bl_callback/ {print $2}')
13123         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13124         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13125         lru_resize_enable mdc
13126         lru_resize_enable osc
13127 }
13128 run_test 120f "Early Lock Cancel: rename test"
13129
13130 test_120g() {
13131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13133                 skip_env "no early lock cancel on server"
13134         remote_mds_nodsh && skip "remote MDS with nodsh"
13135
13136         lru_resize_disable mdc
13137         lru_resize_disable osc
13138         count=10000
13139         echo create $count files
13140         test_mkdir $DIR/$tdir
13141         cancel_lru_locks mdc
13142         cancel_lru_locks osc
13143         t0=$(date +%s)
13144
13145         can0=$(do_facet $SINGLEMDS \
13146                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13147                awk '/ldlm_cancel/ {print $2}')
13148         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13149                awk '/ldlm_bl_callback/ {print $2}')
13150         createmany -o $DIR/$tdir/f $count
13151         sync
13152         can1=$(do_facet $SINGLEMDS \
13153                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13154                awk '/ldlm_cancel/ {print $2}')
13155         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13156                awk '/ldlm_bl_callback/ {print $2}')
13157         t1=$(date +%s)
13158         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13159         echo rm $count files
13160         rm -r $DIR/$tdir
13161         sync
13162         can2=$(do_facet $SINGLEMDS \
13163                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13164                awk '/ldlm_cancel/ {print $2}')
13165         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13166                awk '/ldlm_bl_callback/ {print $2}')
13167         t2=$(date +%s)
13168         echo total: $count removes in $((t2-t1))
13169         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13170         sleep 2
13171         # wait for commitment of removal
13172         lru_resize_enable mdc
13173         lru_resize_enable osc
13174 }
13175 run_test 120g "Early Lock Cancel: performance test"
13176
13177 test_121() { #bug #10589
13178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13179
13180         rm -rf $DIR/$tfile
13181         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13182 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13183         lctl set_param fail_loc=0x310
13184         cancel_lru_locks osc > /dev/null
13185         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13186         lctl set_param fail_loc=0
13187         [[ $reads -eq $writes ]] ||
13188                 error "read $reads blocks, must be $writes blocks"
13189 }
13190 run_test 121 "read cancel race ========="
13191
13192 test_123a_base() { # was test 123, statahead(bug 11401)
13193         local lsx="$1"
13194
13195         SLOWOK=0
13196         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13197                 log "testing UP system. Performance may be lower than expected."
13198                 SLOWOK=1
13199         fi
13200         running_in_vm && SLOWOK=1
13201
13202         rm -rf $DIR/$tdir
13203         test_mkdir $DIR/$tdir
13204         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13205         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13206         MULT=10
13207         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13208                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13209
13210                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13211                 lctl set_param -n llite.*.statahead_max 0
13212                 lctl get_param llite.*.statahead_max
13213                 cancel_lru_locks mdc
13214                 cancel_lru_locks osc
13215                 stime=$(date +%s)
13216                 time $lsx $DIR/$tdir | wc -l
13217                 etime=$(date +%s)
13218                 delta=$((etime - stime))
13219                 log "$lsx $i files without statahead: $delta sec"
13220                 lctl set_param llite.*.statahead_max=$max
13221
13222                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13223                          awk '/statahead.wrong:/ { print $NF }')
13224                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13225                 cancel_lru_locks mdc
13226                 cancel_lru_locks osc
13227                 stime=$(date +%s)
13228                 time $lsx $DIR/$tdir | wc -l
13229                 etime=$(date +%s)
13230                 delta_sa=$((etime - stime))
13231                 log "$lsx $i files with statahead: $delta_sa sec"
13232                 lctl get_param -n llite.*.statahead_stats
13233                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13234                          awk '/statahead.wrong:/ { print $NF }')
13235
13236                 [[ $swrong -lt $ewrong ]] &&
13237                         log "statahead was stopped, maybe too many locks held!"
13238                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13239
13240                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13241                         max=$(lctl get_param -n llite.*.statahead_max |
13242                                 head -n 1)
13243                         lctl set_param -n llite.*.statahead_max 0
13244                         lctl get_param llite.*.statahead_max
13245                         cancel_lru_locks mdc
13246                         cancel_lru_locks osc
13247                         stime=$(date +%s)
13248                         time $lsx $DIR/$tdir | wc -l
13249                         etime=$(date +%s)
13250                         delta=$((etime - stime))
13251                         log "$lsx $i files again without statahead: $delta sec"
13252                         lctl set_param llite.*.statahead_max=$max
13253                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13254                                 if [ $SLOWOK -eq 0 ]; then
13255                                         error "$lsx $i files is slower with statahead!"
13256                                 else
13257                                         log "$lsx $i files is slower with statahead!"
13258                                 fi
13259                                 break
13260                         fi
13261                 fi
13262
13263                 [ $delta -gt 20 ] && break
13264                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13265                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13266         done
13267         log "$lsx done"
13268
13269         stime=$(date +%s)
13270         rm -r $DIR/$tdir
13271         sync
13272         etime=$(date +%s)
13273         delta=$((etime - stime))
13274         log "rm -r $DIR/$tdir/: $delta seconds"
13275         log "rm done"
13276         lctl get_param -n llite.*.statahead_stats
13277 }
13278
13279 test_123aa() {
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281
13282         test_123a_base "ls -l"
13283 }
13284 run_test 123aa "verify statahead work"
13285
13286 test_123ab() {
13287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13288
13289         statx_supported || skip_env "Test must be statx() syscall supported"
13290
13291         test_123a_base "$STATX -l"
13292 }
13293 run_test 123ab "verify statahead work by using statx"
13294
13295 test_123ac() {
13296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13297
13298         statx_supported || skip_env "Test must be statx() syscall supported"
13299
13300         local rpcs_before
13301         local rpcs_after
13302         local agl_before
13303         local agl_after
13304
13305         cancel_lru_locks $OSC
13306         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13307         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13308                      awk '/agl.total:/ { print $NF }')
13309         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13310         test_123a_base "$STATX --cached=always -D"
13311         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13312                     awk '/agl.total:/ { print $NF }')
13313         [ $agl_before -eq $agl_after ] ||
13314                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13315         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13316         [ $rpcs_after -eq $rpcs_before ] ||
13317                 error "$STATX should not send glimpse RPCs to $OSC"
13318 }
13319 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13320
13321 test_123b () { # statahead(bug 15027)
13322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13323
13324         test_mkdir $DIR/$tdir
13325         createmany -o $DIR/$tdir/$tfile-%d 1000
13326
13327         cancel_lru_locks mdc
13328         cancel_lru_locks osc
13329
13330 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13331         lctl set_param fail_loc=0x80000803
13332         ls -lR $DIR/$tdir > /dev/null
13333         log "ls done"
13334         lctl set_param fail_loc=0x0
13335         lctl get_param -n llite.*.statahead_stats
13336         rm -r $DIR/$tdir
13337         sync
13338
13339 }
13340 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13341
13342 test_123c() {
13343         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13344
13345         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13346         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13347         touch $DIR/$tdir.1/{1..3}
13348         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13349
13350         remount_client $MOUNT
13351
13352         $MULTIOP $DIR/$tdir.0 Q
13353
13354         # let statahead to complete
13355         ls -l $DIR/$tdir.0 > /dev/null
13356
13357         testid=$(echo $TESTNAME | tr '_' ' ')
13358         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13359                 error "statahead warning" || true
13360 }
13361 run_test 123c "Can not initialize inode warning on DNE statahead"
13362
13363 test_123d() {
13364         local num=100
13365         local swrong
13366         local ewrong
13367
13368         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13369         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13370                 error "setdirstripe $DIR/$tdir failed"
13371         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13372         remount_client $MOUNT
13373         $LCTL get_param llite.*.statahead_max
13374         $LCTL set_param llite.*.statahead_stats=0 ||
13375                 error "clear statahead_stats failed"
13376         swrong=$(lctl get_param -n llite.*.statahead_stats |
13377                  awk '/statahead.wrong:/ { print $NF }')
13378         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13379         # wait for statahead thread finished to update hit/miss stats.
13380         sleep 1
13381         $LCTL get_param -n llite.*.statahead_stats
13382         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13383                  awk '/statahead.wrong:/ { print $NF }')
13384         (( $swrong == $ewrong )) ||
13385                 log "statahead was stopped, maybe too many locks held!"
13386 }
13387 run_test 123d "Statahead on striped directories works correctly"
13388
13389 test_124a() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13392                 skip_env "no lru resize on server"
13393
13394         local NR=2000
13395
13396         test_mkdir $DIR/$tdir
13397
13398         log "create $NR files at $DIR/$tdir"
13399         createmany -o $DIR/$tdir/f $NR ||
13400                 error "failed to create $NR files in $DIR/$tdir"
13401
13402         cancel_lru_locks mdc
13403         ls -l $DIR/$tdir > /dev/null
13404
13405         local NSDIR=""
13406         local LRU_SIZE=0
13407         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13408                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13409                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13410                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13411                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13412                         log "NSDIR=$NSDIR"
13413                         log "NS=$(basename $NSDIR)"
13414                         break
13415                 fi
13416         done
13417
13418         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13419                 skip "Not enough cached locks created!"
13420         fi
13421         log "LRU=$LRU_SIZE"
13422
13423         local SLEEP=30
13424
13425         # We know that lru resize allows one client to hold $LIMIT locks
13426         # for 10h. After that locks begin to be killed by client.
13427         local MAX_HRS=10
13428         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13429         log "LIMIT=$LIMIT"
13430         if [ $LIMIT -lt $LRU_SIZE ]; then
13431                 skip "Limit is too small $LIMIT"
13432         fi
13433
13434         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13435         # killing locks. Some time was spent for creating locks. This means
13436         # that up to the moment of sleep finish we must have killed some of
13437         # them (10-100 locks). This depends on how fast ther were created.
13438         # Many of them were touched in almost the same moment and thus will
13439         # be killed in groups.
13440         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13441
13442         # Use $LRU_SIZE_B here to take into account real number of locks
13443         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13444         local LRU_SIZE_B=$LRU_SIZE
13445         log "LVF=$LVF"
13446         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13447         log "OLD_LVF=$OLD_LVF"
13448         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13449
13450         # Let's make sure that we really have some margin. Client checks
13451         # cached locks every 10 sec.
13452         SLEEP=$((SLEEP+20))
13453         log "Sleep ${SLEEP} sec"
13454         local SEC=0
13455         while ((SEC<$SLEEP)); do
13456                 echo -n "..."
13457                 sleep 5
13458                 SEC=$((SEC+5))
13459                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13460                 echo -n "$LRU_SIZE"
13461         done
13462         echo ""
13463         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13464         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13465
13466         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13467                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13468                 unlinkmany $DIR/$tdir/f $NR
13469                 return
13470         }
13471
13472         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13473         log "unlink $NR files at $DIR/$tdir"
13474         unlinkmany $DIR/$tdir/f $NR
13475 }
13476 run_test 124a "lru resize ======================================="
13477
13478 get_max_pool_limit()
13479 {
13480         local limit=$($LCTL get_param \
13481                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13482         local max=0
13483         for l in $limit; do
13484                 if [[ $l -gt $max ]]; then
13485                         max=$l
13486                 fi
13487         done
13488         echo $max
13489 }
13490
13491 test_124b() {
13492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13493         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13494                 skip_env "no lru resize on server"
13495
13496         LIMIT=$(get_max_pool_limit)
13497
13498         NR=$(($(default_lru_size)*20))
13499         if [[ $NR -gt $LIMIT ]]; then
13500                 log "Limit lock number by $LIMIT locks"
13501                 NR=$LIMIT
13502         fi
13503
13504         IFree=$(mdsrate_inodes_available)
13505         if [ $IFree -lt $NR ]; then
13506                 log "Limit lock number by $IFree inodes"
13507                 NR=$IFree
13508         fi
13509
13510         lru_resize_disable mdc
13511         test_mkdir -p $DIR/$tdir/disable_lru_resize
13512
13513         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13514         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13515         cancel_lru_locks mdc
13516         stime=`date +%s`
13517         PID=""
13518         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13519         PID="$PID $!"
13520         sleep 2
13521         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13522         PID="$PID $!"
13523         sleep 2
13524         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13525         PID="$PID $!"
13526         wait $PID
13527         etime=`date +%s`
13528         nolruresize_delta=$((etime-stime))
13529         log "ls -la time: $nolruresize_delta seconds"
13530         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13531         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13532
13533         lru_resize_enable mdc
13534         test_mkdir -p $DIR/$tdir/enable_lru_resize
13535
13536         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13537         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13538         cancel_lru_locks mdc
13539         stime=`date +%s`
13540         PID=""
13541         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13542         PID="$PID $!"
13543         sleep 2
13544         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13545         PID="$PID $!"
13546         sleep 2
13547         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13548         PID="$PID $!"
13549         wait $PID
13550         etime=`date +%s`
13551         lruresize_delta=$((etime-stime))
13552         log "ls -la time: $lruresize_delta seconds"
13553         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13554
13555         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13556                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13557         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13558                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13559         else
13560                 log "lru resize performs the same with no lru resize"
13561         fi
13562         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13563 }
13564 run_test 124b "lru resize (performance test) ======================="
13565
13566 test_124c() {
13567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13568         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13569                 skip_env "no lru resize on server"
13570
13571         # cache ununsed locks on client
13572         local nr=100
13573         cancel_lru_locks mdc
13574         test_mkdir $DIR/$tdir
13575         createmany -o $DIR/$tdir/f $nr ||
13576                 error "failed to create $nr files in $DIR/$tdir"
13577         ls -l $DIR/$tdir > /dev/null
13578
13579         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13580         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13581         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13582         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13583         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13584
13585         # set lru_max_age to 1 sec
13586         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13587         echo "sleep $((recalc_p * 2)) seconds..."
13588         sleep $((recalc_p * 2))
13589
13590         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13591         # restore lru_max_age
13592         $LCTL set_param -n $nsdir.lru_max_age $max_age
13593         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13594         unlinkmany $DIR/$tdir/f $nr
13595 }
13596 run_test 124c "LRUR cancel very aged locks"
13597
13598 test_124d() {
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13601                 skip_env "no lru resize on server"
13602
13603         # cache ununsed locks on client
13604         local nr=100
13605
13606         lru_resize_disable mdc
13607         stack_trap "lru_resize_enable mdc" EXIT
13608
13609         cancel_lru_locks mdc
13610
13611         # asynchronous object destroy at MDT could cause bl ast to client
13612         test_mkdir $DIR/$tdir
13613         createmany -o $DIR/$tdir/f $nr ||
13614                 error "failed to create $nr files in $DIR/$tdir"
13615         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13616
13617         ls -l $DIR/$tdir > /dev/null
13618
13619         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13620         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13621         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13622         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13623
13624         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13625
13626         # set lru_max_age to 1 sec
13627         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13628         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13629
13630         echo "sleep $((recalc_p * 2)) seconds..."
13631         sleep $((recalc_p * 2))
13632
13633         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13634
13635         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13636 }
13637 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13638
13639 test_125() { # 13358
13640         $LCTL get_param -n llite.*.client_type | grep -q local ||
13641                 skip "must run as local client"
13642         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13643                 skip_env "must have acl enabled"
13644         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13645
13646         test_mkdir $DIR/$tdir
13647         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13648         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13649                 error "setfacl $DIR/$tdir failed"
13650         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13651 }
13652 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13653
13654 test_126() { # bug 12829/13455
13655         $GSS && skip_env "must run as gss disabled"
13656         $LCTL get_param -n llite.*.client_type | grep -q local ||
13657                 skip "must run as local client"
13658         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13659
13660         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13661         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13662         rm -f $DIR/$tfile
13663         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13664 }
13665 run_test 126 "check that the fsgid provided by the client is taken into account"
13666
13667 test_127a() { # bug 15521
13668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13669         local name count samp unit min max sum sumsq
13670
13671         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13672         echo "stats before reset"
13673         $LCTL get_param osc.*.stats
13674         $LCTL set_param osc.*.stats=0
13675         local fsize=$((2048 * 1024))
13676
13677         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13678         cancel_lru_locks osc
13679         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13680
13681         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13682         stack_trap "rm -f $TMP/$tfile.tmp"
13683         while read name count samp unit min max sum sumsq; do
13684                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13685                 [ ! $min ] && error "Missing min value for $name proc entry"
13686                 eval $name=$count || error "Wrong proc format"
13687
13688                 case $name in
13689                 read_bytes|write_bytes)
13690                         [[ "$unit" =~ "bytes" ]] ||
13691                                 error "unit is not 'bytes': $unit"
13692                         (( $min >= 4096 )) || error "min is too small: $min"
13693                         (( $min <= $fsize )) || error "min is too big: $min"
13694                         (( $max >= 4096 )) || error "max is too small: $max"
13695                         (( $max <= $fsize )) || error "max is too big: $max"
13696                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13697                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13698                                 error "sumsquare is too small: $sumsq"
13699                         (( $sumsq <= $fsize * $fsize )) ||
13700                                 error "sumsquare is too big: $sumsq"
13701                         ;;
13702                 ost_read|ost_write)
13703                         [[ "$unit" =~ "usec" ]] ||
13704                                 error "unit is not 'usec': $unit"
13705                         ;;
13706                 *)      ;;
13707                 esac
13708         done < $DIR/$tfile.tmp
13709
13710         #check that we actually got some stats
13711         [ "$read_bytes" ] || error "Missing read_bytes stats"
13712         [ "$write_bytes" ] || error "Missing write_bytes stats"
13713         [ "$read_bytes" != 0 ] || error "no read done"
13714         [ "$write_bytes" != 0 ] || error "no write done"
13715 }
13716 run_test 127a "verify the client stats are sane"
13717
13718 test_127b() { # bug LU-333
13719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13720         local name count samp unit min max sum sumsq
13721
13722         echo "stats before reset"
13723         $LCTL get_param llite.*.stats
13724         $LCTL set_param llite.*.stats=0
13725
13726         # perform 2 reads and writes so MAX is different from SUM.
13727         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13728         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13729         cancel_lru_locks osc
13730         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13731         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13732
13733         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13734         stack_trap "rm -f $TMP/$tfile.tmp"
13735         while read name count samp unit min max sum sumsq; do
13736                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13737                 eval $name=$count || error "Wrong proc format"
13738
13739                 case $name in
13740                 read_bytes|write_bytes)
13741                         [[ "$unit" =~ "bytes" ]] ||
13742                                 error "unit is not 'bytes': $unit"
13743                         (( $count == 2 )) || error "count is not 2: $count"
13744                         (( $min == $PAGE_SIZE )) ||
13745                                 error "min is not $PAGE_SIZE: $min"
13746                         (( $max == $PAGE_SIZE )) ||
13747                                 error "max is not $PAGE_SIZE: $max"
13748                         (( $sum == $PAGE_SIZE * 2 )) ||
13749                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13750                         ;;
13751                 read|write)
13752                         [[ "$unit" =~ "usec" ]] ||
13753                                 error "unit is not 'usec': $unit"
13754                         ;;
13755                 *)      ;;
13756                 esac
13757         done < $TMP/$tfile.tmp
13758
13759         #check that we actually got some stats
13760         [ "$read_bytes" ] || error "Missing read_bytes stats"
13761         [ "$write_bytes" ] || error "Missing write_bytes stats"
13762         [ "$read_bytes" != 0 ] || error "no read done"
13763         [ "$write_bytes" != 0 ] || error "no write done"
13764 }
13765 run_test 127b "verify the llite client stats are sane"
13766
13767 test_127c() { # LU-12394
13768         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13769         local size
13770         local bsize
13771         local reads
13772         local writes
13773         local count
13774
13775         $LCTL set_param llite.*.extents_stats=1
13776         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13777
13778         # Use two stripes so there is enough space in default config
13779         $LFS setstripe -c 2 $DIR/$tfile
13780
13781         # Extent stats start at 0-4K and go in power of two buckets
13782         # LL_HIST_START = 12 --> 2^12 = 4K
13783         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13784         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13785         # small configs
13786         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13787                 do
13788                 # Write and read, 2x each, second time at a non-zero offset
13789                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13790                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13791                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13792                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13793                 rm -f $DIR/$tfile
13794         done
13795
13796         $LCTL get_param llite.*.extents_stats
13797
13798         count=2
13799         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13800                 do
13801                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13802                                 grep -m 1 $bsize)
13803                 reads=$(echo $bucket | awk '{print $5}')
13804                 writes=$(echo $bucket | awk '{print $9}')
13805                 [ "$reads" -eq $count ] ||
13806                         error "$reads reads in < $bsize bucket, expect $count"
13807                 [ "$writes" -eq $count ] ||
13808                         error "$writes writes in < $bsize bucket, expect $count"
13809         done
13810
13811         # Test mmap write and read
13812         $LCTL set_param llite.*.extents_stats=c
13813         size=512
13814         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13815         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13816         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13817
13818         $LCTL get_param llite.*.extents_stats
13819
13820         count=$(((size*1024) / PAGE_SIZE))
13821
13822         bsize=$((2 * PAGE_SIZE / 1024))K
13823
13824         bucket=$($LCTL get_param -n llite.*.extents_stats |
13825                         grep -m 1 $bsize)
13826         reads=$(echo $bucket | awk '{print $5}')
13827         writes=$(echo $bucket | awk '{print $9}')
13828         # mmap writes fault in the page first, creating an additonal read
13829         [ "$reads" -eq $((2 * count)) ] ||
13830                 error "$reads reads in < $bsize bucket, expect $count"
13831         [ "$writes" -eq $count ] ||
13832                 error "$writes writes in < $bsize bucket, expect $count"
13833 }
13834 run_test 127c "test llite extent stats with regular & mmap i/o"
13835
13836 test_128() { # bug 15212
13837         touch $DIR/$tfile
13838         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13839                 find $DIR/$tfile
13840                 find $DIR/$tfile
13841         EOF
13842
13843         result=$(grep error $TMP/$tfile.log)
13844         rm -f $DIR/$tfile $TMP/$tfile.log
13845         [ -z "$result" ] ||
13846                 error "consecutive find's under interactive lfs failed"
13847 }
13848 run_test 128 "interactive lfs for 2 consecutive find's"
13849
13850 set_dir_limits () {
13851         local mntdev
13852         local canondev
13853         local node
13854
13855         local ldproc=/proc/fs/ldiskfs
13856         local facets=$(get_facets MDS)
13857
13858         for facet in ${facets//,/ }; do
13859                 canondev=$(ldiskfs_canon \
13860                            *.$(convert_facet2label $facet).mntdev $facet)
13861                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13862                         ldproc=/sys/fs/ldiskfs
13863                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13864                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13865         done
13866 }
13867
13868 check_mds_dmesg() {
13869         local facets=$(get_facets MDS)
13870         for facet in ${facets//,/ }; do
13871                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13872         done
13873         return 1
13874 }
13875
13876 test_129() {
13877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13878         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13879                 skip "Need MDS version with at least 2.5.56"
13880         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13881                 skip_env "ldiskfs only test"
13882         fi
13883         remote_mds_nodsh && skip "remote MDS with nodsh"
13884
13885         local ENOSPC=28
13886         local has_warning=false
13887
13888         rm -rf $DIR/$tdir
13889         mkdir -p $DIR/$tdir
13890
13891         # block size of mds1
13892         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13893         set_dir_limits $maxsize $((maxsize * 6 / 8))
13894         stack_trap "set_dir_limits 0 0"
13895         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13896         local dirsize=$(stat -c%s "$DIR/$tdir")
13897         local nfiles=0
13898         while (( $dirsize <= $maxsize )); do
13899                 $MCREATE $DIR/$tdir/file_base_$nfiles
13900                 rc=$?
13901                 # check two errors:
13902                 # ENOSPC for ext4 max_dir_size, which has been used since
13903                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13904                 if (( rc == ENOSPC )); then
13905                         set_dir_limits 0 0
13906                         echo "rc=$rc returned as expected after $nfiles files"
13907
13908                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13909                                 error "create failed w/o dir size limit"
13910
13911                         # messages may be rate limited if test is run repeatedly
13912                         check_mds_dmesg '"is approaching max"' ||
13913                                 echo "warning message should be output"
13914                         check_mds_dmesg '"has reached max"' ||
13915                                 echo "reached message should be output"
13916
13917                         dirsize=$(stat -c%s "$DIR/$tdir")
13918
13919                         [[ $dirsize -ge $maxsize ]] && return 0
13920                         error "dirsize $dirsize < $maxsize after $nfiles files"
13921                 elif (( rc != 0 )); then
13922                         break
13923                 fi
13924                 nfiles=$((nfiles + 1))
13925                 dirsize=$(stat -c%s "$DIR/$tdir")
13926         done
13927
13928         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13929 }
13930 run_test 129 "test directory size limit ========================"
13931
13932 OLDIFS="$IFS"
13933 cleanup_130() {
13934         trap 0
13935         IFS="$OLDIFS"
13936 }
13937
13938 test_130a() {
13939         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13940         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13941
13942         trap cleanup_130 EXIT RETURN
13943
13944         local fm_file=$DIR/$tfile
13945         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13946         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13947                 error "dd failed for $fm_file"
13948
13949         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13950         filefrag -ves $fm_file
13951         local rc=$?
13952         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13953                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13954         (( $rc == 0 )) || error "filefrag $fm_file failed"
13955
13956         filefrag_op=$(filefrag -ve -k $fm_file |
13957                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13958         local lun=$($LFS getstripe -i $fm_file)
13959
13960         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13961         IFS=$'\n'
13962         local tot_len=0
13963         for line in $filefrag_op; do
13964                 local frag_lun=$(echo $line | cut -d: -f5)
13965                 local ext_len=$(echo $line | cut -d: -f4)
13966
13967                 if (( $frag_lun != $lun )); then
13968                         error "FIEMAP on 1-stripe file($fm_file) failed"
13969                         return
13970                 fi
13971                 (( tot_len += ext_len ))
13972         done
13973
13974         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13975                 error "FIEMAP on 1-stripe file($fm_file) failed"
13976                 return
13977         fi
13978
13979         echo "FIEMAP on single striped file succeeded"
13980 }
13981 run_test 130a "FIEMAP (1-stripe file)"
13982
13983 test_130b() {
13984         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13985
13986         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13987         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13988         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13989                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13990
13991         trap cleanup_130 EXIT RETURN
13992
13993         local fm_file=$DIR/$tfile
13994         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13995                 error "setstripe on $fm_file"
13996
13997         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13998                 error "dd failed on $fm_file"
13999
14000         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14001         filefrag_op=$(filefrag -ve -k $fm_file |
14002                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14003
14004         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14005                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14006
14007         IFS=$'\n'
14008         local tot_len=0
14009         local num_luns=1
14010
14011         for line in $filefrag_op; do
14012                 local frag_lun=$(echo $line | cut -d: -f5 |
14013                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14014                 local ext_len=$(echo $line | cut -d: -f4)
14015                 if (( $frag_lun != $last_lun )); then
14016                         if (( tot_len != 1024 )); then
14017                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14018                                 return
14019                         else
14020                                 (( num_luns += 1 ))
14021                                 tot_len=0
14022                         fi
14023                 fi
14024                 (( tot_len += ext_len ))
14025                 last_lun=$frag_lun
14026         done
14027         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14028                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14029                 return
14030         fi
14031
14032         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14033 }
14034 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14035
14036 test_130c() {
14037         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14038
14039         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14040         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14041         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14042                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14043
14044         trap cleanup_130 EXIT RETURN
14045
14046         local fm_file=$DIR/$tfile
14047         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14048
14049         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14050                 error "dd failed on $fm_file"
14051
14052         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14053         filefrag_op=$(filefrag -ve -k $fm_file |
14054                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14055
14056         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14057                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14058
14059         IFS=$'\n'
14060         local tot_len=0
14061         local num_luns=1
14062         for line in $filefrag_op; do
14063                 local frag_lun=$(echo $line | cut -d: -f5 |
14064                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14065                 local ext_len=$(echo $line | cut -d: -f4)
14066                 if (( $frag_lun != $last_lun )); then
14067                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14068                         if (( logical != 512 )); then
14069                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14070                                 return
14071                         fi
14072                         if (( tot_len != 512 )); then
14073                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14074                                 return
14075                         else
14076                                 (( num_luns += 1 ))
14077                                 tot_len=0
14078                         fi
14079                 fi
14080                 (( tot_len += ext_len ))
14081                 last_lun=$frag_lun
14082         done
14083         if (( num_luns != 2 || tot_len != 512 )); then
14084                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14085                 return
14086         fi
14087
14088         echo "FIEMAP on 2-stripe file with hole succeeded"
14089 }
14090 run_test 130c "FIEMAP (2-stripe file with hole)"
14091
14092 test_130d() {
14093         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14094
14095         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14096         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14097         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14098                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14099
14100         trap cleanup_130 EXIT RETURN
14101
14102         local fm_file=$DIR/$tfile
14103         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14104                         error "setstripe on $fm_file"
14105
14106         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14107         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14108                 error "dd failed on $fm_file"
14109
14110         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14111         filefrag_op=$(filefrag -ve -k $fm_file |
14112                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14113
14114         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14115                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14116
14117         IFS=$'\n'
14118         local tot_len=0
14119         local num_luns=1
14120         for line in $filefrag_op; do
14121                 local frag_lun=$(echo $line | cut -d: -f5 |
14122                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14123                 local ext_len=$(echo $line | cut -d: -f4)
14124                 if (( $frag_lun != $last_lun )); then
14125                         if (( tot_len != 1024 )); then
14126                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14127                                 return
14128                         else
14129                                 (( num_luns += 1 ))
14130                                 local tot_len=0
14131                         fi
14132                 fi
14133                 (( tot_len += ext_len ))
14134                 last_lun=$frag_lun
14135         done
14136         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14137                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14138                 return
14139         fi
14140
14141         echo "FIEMAP on N-stripe file succeeded"
14142 }
14143 run_test 130d "FIEMAP (N-stripe file)"
14144
14145 test_130e() {
14146         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14147
14148         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14149         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14150         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14151                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14152
14153         trap cleanup_130 EXIT RETURN
14154
14155         local fm_file=$DIR/$tfile
14156         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14157
14158         local num_blks=512
14159         local expected_len=$(( (num_blks / 2) * 64 ))
14160         for ((i = 0; i < $num_blks; i++)); do
14161                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14162                         conv=notrunc > /dev/null 2>&1
14163         done
14164
14165         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14166         filefrag_op=$(filefrag -ve -k $fm_file |
14167                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14168
14169         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14170
14171         IFS=$'\n'
14172         local tot_len=0
14173         local num_luns=1
14174         for line in $filefrag_op; do
14175                 local frag_lun=$(echo $line | cut -d: -f5)
14176                 local ext_len=$(echo $line | cut -d: -f4)
14177                 if (( $frag_lun != $last_lun )); then
14178                         if (( tot_len != $expected_len )); then
14179                                 error "OST$last_lun $tot_len != $expected_len"
14180                         else
14181                                 (( num_luns += 1 ))
14182                                 tot_len=0
14183                         fi
14184                 fi
14185                 (( tot_len += ext_len ))
14186                 last_lun=$frag_lun
14187         done
14188         if (( num_luns != 2 || tot_len != $expected_len )); then
14189                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14190         fi
14191
14192         echo "FIEMAP with continuation calls succeeded"
14193 }
14194 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14195
14196 test_130f() {
14197         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14198         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14199         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14200                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14201
14202         local fm_file=$DIR/$tfile
14203         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14204                 error "multiop create with lov_delay_create on $fm_file"
14205
14206         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14207         filefrag_extents=$(filefrag -vek $fm_file |
14208                            awk '/extents? found/ { print $2 }')
14209         if (( $filefrag_extents != 0 )); then
14210                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14211         fi
14212
14213         rm -f $fm_file
14214 }
14215 run_test 130f "FIEMAP (unstriped file)"
14216
14217 test_130g() {
14218         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14219                 skip "Need MDS version with at least 2.12.53 for overstriping"
14220         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14221         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14222         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14223                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14224
14225         local file=$DIR/$tfile
14226         local nr=$((OSTCOUNT * 100))
14227
14228         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14229
14230         stack_trap "rm -f $file"
14231         dd if=/dev/zero of=$file count=$nr bs=1M
14232         sync
14233         nr=$($LFS getstripe -c $file)
14234
14235         local extents=$(filefrag -v $file |
14236                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14237
14238         echo "filefrag list $extents extents in file with stripecount $nr"
14239         if (( extents < nr )); then
14240                 $LFS getstripe $file
14241                 filefrag -v $file
14242                 error "filefrag printed $extents < $nr extents"
14243         fi
14244 }
14245 run_test 130g "FIEMAP (overstripe file)"
14246
14247 # Test for writev/readv
14248 test_131a() {
14249         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14250                 error "writev test failed"
14251         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14252                 error "readv failed"
14253         rm -f $DIR/$tfile
14254 }
14255 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14256
14257 test_131b() {
14258         local fsize=$((524288 + 1048576 + 1572864))
14259         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14260                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14261                         error "append writev test failed"
14262
14263         ((fsize += 1572864 + 1048576))
14264         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14265                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14266                         error "append writev test failed"
14267         rm -f $DIR/$tfile
14268 }
14269 run_test 131b "test append writev"
14270
14271 test_131c() {
14272         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14273         error "NOT PASS"
14274 }
14275 run_test 131c "test read/write on file w/o objects"
14276
14277 test_131d() {
14278         rwv -f $DIR/$tfile -w -n 1 1572864
14279         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14280         if [ "$NOB" != 1572864 ]; then
14281                 error "Short read filed: read $NOB bytes instead of 1572864"
14282         fi
14283         rm -f $DIR/$tfile
14284 }
14285 run_test 131d "test short read"
14286
14287 test_131e() {
14288         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14289         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14290         error "read hitting hole failed"
14291         rm -f $DIR/$tfile
14292 }
14293 run_test 131e "test read hitting hole"
14294
14295 check_stats() {
14296         local facet=$1
14297         local op=$2
14298         local want=${3:-0}
14299         local res
14300
14301         # open             11 samples [usecs] 468 4793 13658 35791898
14302         case $facet in
14303         mds*) res=($(do_facet $facet \
14304                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14305                  ;;
14306         ost*) res=($(do_facet $facet \
14307                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14308                  ;;
14309         *) error "Wrong facet '$facet'" ;;
14310         esac
14311         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14312         # if $want is zero, it means any stat increment is ok.
14313         if (( $want > 0 )); then
14314                 local count=${res[1]}
14315
14316                 if (( $count != $want )); then
14317                         if [[ $facet =~ "mds" ]]; then
14318                                 do_nodes $(comma_list $(mdts_nodes)) \
14319                                         $LCTL get_param mdt.*.md_stats
14320                         else
14321                                 do_nodes $(comma_list $(osts-nodes)) \
14322                                         $LCTL get_param obdfilter.*.stats
14323                         fi
14324                         error "The $op counter on $facet is $count, not $want"
14325                 fi
14326         fi
14327 }
14328
14329 test_133a() {
14330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14331         remote_ost_nodsh && skip "remote OST with nodsh"
14332         remote_mds_nodsh && skip "remote MDS with nodsh"
14333         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14334                 skip_env "MDS doesn't support rename stats"
14335
14336         local testdir=$DIR/${tdir}/stats_testdir
14337
14338         mkdir -p $DIR/${tdir}
14339
14340         # clear stats.
14341         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14342         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14343
14344         # verify mdt stats first.
14345         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14346         check_stats $SINGLEMDS "mkdir" 1
14347
14348         # clear "open" from "lfs mkdir" above
14349         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14350         touch ${testdir}/${tfile} || error "touch failed"
14351         check_stats $SINGLEMDS "open" 1
14352         check_stats $SINGLEMDS "close" 1
14353         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14354                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14355                 check_stats $SINGLEMDS "mknod" 2
14356         }
14357         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14358         check_stats $SINGLEMDS "unlink" 1
14359         rm -f ${testdir}/${tfile} || error "file remove failed"
14360         check_stats $SINGLEMDS "unlink" 2
14361
14362         # remove working dir and check mdt stats again.
14363         rmdir ${testdir} || error "rmdir failed"
14364         check_stats $SINGLEMDS "rmdir" 1
14365
14366         local testdir1=$DIR/${tdir}/stats_testdir1
14367         mkdir -p ${testdir}
14368         mkdir -p ${testdir1}
14369         touch ${testdir1}/test1
14370         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14371         check_stats $SINGLEMDS "crossdir_rename" 1
14372
14373         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14374         check_stats $SINGLEMDS "samedir_rename" 1
14375
14376         rm -rf $DIR/${tdir}
14377 }
14378 run_test 133a "Verifying MDT stats ========================================"
14379
14380 test_133b() {
14381         local res
14382
14383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14384         remote_ost_nodsh && skip "remote OST with nodsh"
14385         remote_mds_nodsh && skip "remote MDS with nodsh"
14386
14387         local testdir=$DIR/${tdir}/stats_testdir
14388
14389         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14390         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14391         touch ${testdir}/${tfile} || error "touch failed"
14392         cancel_lru_locks mdc
14393
14394         # clear stats.
14395         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14396         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14397
14398         # extra mdt stats verification.
14399         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14400         check_stats $SINGLEMDS "setattr" 1
14401         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14402         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14403         then            # LU-1740
14404                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14405                 check_stats $SINGLEMDS "getattr" 1
14406         fi
14407         rm -rf $DIR/${tdir}
14408
14409         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14410         # so the check below is not reliable
14411         [ $MDSCOUNT -eq 1 ] || return 0
14412
14413         # Sleep to avoid a cached response.
14414         #define OBD_STATFS_CACHE_SECONDS 1
14415         sleep 2
14416         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14417         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14418         $LFS df || error "lfs failed"
14419         check_stats $SINGLEMDS "statfs" 1
14420
14421         # check aggregated statfs (LU-10018)
14422         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14423                 return 0
14424         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14425                 return 0
14426         sleep 2
14427         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14428         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14429         df $DIR
14430         check_stats $SINGLEMDS "statfs" 1
14431
14432         # We want to check that the client didn't send OST_STATFS to
14433         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14434         # extra care is needed here.
14435         if remote_mds; then
14436                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14437                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14438
14439                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14440                 [ "$res" ] && error "OST got STATFS"
14441         fi
14442
14443         return 0
14444 }
14445 run_test 133b "Verifying extra MDT stats =================================="
14446
14447 test_133c() {
14448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14449         remote_ost_nodsh && skip "remote OST with nodsh"
14450         remote_mds_nodsh && skip "remote MDS with nodsh"
14451
14452         local testdir=$DIR/$tdir/stats_testdir
14453
14454         test_mkdir -p $testdir
14455
14456         # verify obdfilter stats.
14457         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14458         sync
14459         cancel_lru_locks osc
14460         wait_delete_completed
14461
14462         # clear stats.
14463         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14464         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14465
14466         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14467                 error "dd failed"
14468         sync
14469         cancel_lru_locks osc
14470         check_stats ost1 "write" 1
14471
14472         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14473         check_stats ost1 "read" 1
14474
14475         > $testdir/$tfile || error "truncate failed"
14476         check_stats ost1 "punch" 1
14477
14478         rm -f $testdir/$tfile || error "file remove failed"
14479         wait_delete_completed
14480         check_stats ost1 "destroy" 1
14481
14482         rm -rf $DIR/$tdir
14483 }
14484 run_test 133c "Verifying OST stats ========================================"
14485
14486 order_2() {
14487         local value=$1
14488         local orig=$value
14489         local order=1
14490
14491         while [ $value -ge 2 ]; do
14492                 order=$((order*2))
14493                 value=$((value/2))
14494         done
14495
14496         if [ $orig -gt $order ]; then
14497                 order=$((order*2))
14498         fi
14499         echo $order
14500 }
14501
14502 size_in_KMGT() {
14503     local value=$1
14504     local size=('K' 'M' 'G' 'T');
14505     local i=0
14506     local size_string=$value
14507
14508     while [ $value -ge 1024 ]; do
14509         if [ $i -gt 3 ]; then
14510             #T is the biggest unit we get here, if that is bigger,
14511             #just return XXXT
14512             size_string=${value}T
14513             break
14514         fi
14515         value=$((value >> 10))
14516         if [ $value -lt 1024 ]; then
14517             size_string=${value}${size[$i]}
14518             break
14519         fi
14520         i=$((i + 1))
14521     done
14522
14523     echo $size_string
14524 }
14525
14526 get_rename_size() {
14527         local size=$1
14528         local context=${2:-.}
14529         local sample=$(do_facet $SINGLEMDS $LCTL \
14530                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14531                 grep -A1 $context |
14532                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14533         echo $sample
14534 }
14535
14536 test_133d() {
14537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14538         remote_ost_nodsh && skip "remote OST with nodsh"
14539         remote_mds_nodsh && skip "remote MDS with nodsh"
14540         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14541                 skip_env "MDS doesn't support rename stats"
14542
14543         local testdir1=$DIR/${tdir}/stats_testdir1
14544         local testdir2=$DIR/${tdir}/stats_testdir2
14545         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14546
14547         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14548
14549         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14550         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14551
14552         createmany -o $testdir1/test 512 || error "createmany failed"
14553
14554         # check samedir rename size
14555         mv ${testdir1}/test0 ${testdir1}/test_0
14556
14557         local testdir1_size=$(ls -l $DIR/${tdir} |
14558                 awk '/stats_testdir1/ {print $5}')
14559         local testdir2_size=$(ls -l $DIR/${tdir} |
14560                 awk '/stats_testdir2/ {print $5}')
14561
14562         testdir1_size=$(order_2 $testdir1_size)
14563         testdir2_size=$(order_2 $testdir2_size)
14564
14565         testdir1_size=$(size_in_KMGT $testdir1_size)
14566         testdir2_size=$(size_in_KMGT $testdir2_size)
14567
14568         echo "source rename dir size: ${testdir1_size}"
14569         echo "target rename dir size: ${testdir2_size}"
14570
14571         local cmd="do_facet $SINGLEMDS $LCTL "
14572         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14573
14574         eval $cmd || error "$cmd failed"
14575         local samedir=$($cmd | grep 'same_dir')
14576         local same_sample=$(get_rename_size $testdir1_size)
14577         [ -z "$samedir" ] && error "samedir_rename_size count error"
14578         [[ $same_sample -eq 1 ]] ||
14579                 error "samedir_rename_size error $same_sample"
14580         echo "Check same dir rename stats success"
14581
14582         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14583
14584         # check crossdir rename size
14585         mv ${testdir1}/test_0 ${testdir2}/test_0
14586
14587         testdir1_size=$(ls -l $DIR/${tdir} |
14588                 awk '/stats_testdir1/ {print $5}')
14589         testdir2_size=$(ls -l $DIR/${tdir} |
14590                 awk '/stats_testdir2/ {print $5}')
14591
14592         testdir1_size=$(order_2 $testdir1_size)
14593         testdir2_size=$(order_2 $testdir2_size)
14594
14595         testdir1_size=$(size_in_KMGT $testdir1_size)
14596         testdir2_size=$(size_in_KMGT $testdir2_size)
14597
14598         echo "source rename dir size: ${testdir1_size}"
14599         echo "target rename dir size: ${testdir2_size}"
14600
14601         eval $cmd || error "$cmd failed"
14602         local crossdir=$($cmd | grep 'crossdir')
14603         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14604         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14605         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14606         [[ $src_sample -eq 1 ]] ||
14607                 error "crossdir_rename_size error $src_sample"
14608         [[ $tgt_sample -eq 1 ]] ||
14609                 error "crossdir_rename_size error $tgt_sample"
14610         echo "Check cross dir rename stats success"
14611         rm -rf $DIR/${tdir}
14612 }
14613 run_test 133d "Verifying rename_stats ========================================"
14614
14615 test_133e() {
14616         remote_mds_nodsh && skip "remote MDS with nodsh"
14617         remote_ost_nodsh && skip "remote OST with nodsh"
14618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14619
14620         local testdir=$DIR/${tdir}/stats_testdir
14621         local ctr f0 f1 bs=32768 count=42 sum
14622
14623         mkdir -p ${testdir} || error "mkdir failed"
14624
14625         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14626
14627         for ctr in {write,read}_bytes; do
14628                 sync
14629                 cancel_lru_locks osc
14630
14631                 do_facet ost1 $LCTL set_param -n \
14632                         "obdfilter.*.exports.clear=clear"
14633
14634                 if [ $ctr = write_bytes ]; then
14635                         f0=/dev/zero
14636                         f1=${testdir}/${tfile}
14637                 else
14638                         f0=${testdir}/${tfile}
14639                         f1=/dev/null
14640                 fi
14641
14642                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14643                         error "dd failed"
14644                 sync
14645                 cancel_lru_locks osc
14646
14647                 sum=$(do_facet ost1 $LCTL get_param \
14648                         "obdfilter.*.exports.*.stats" |
14649                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14650                                 $1 == ctr { sum += $7 }
14651                                 END { printf("%0.0f", sum) }')
14652
14653                 if ((sum != bs * count)); then
14654                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14655                 fi
14656         done
14657
14658         rm -rf $DIR/${tdir}
14659 }
14660 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14661
14662 test_133f() {
14663         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14664                 skip "too old lustre for get_param -R ($facet_ver)"
14665
14666         # verifying readability.
14667         $LCTL get_param -R '*' &> /dev/null
14668
14669         # Verifing writability with badarea_io.
14670         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14671         local skipped_params='force_lbug|changelog_mask|daemon_file'
14672         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14673                 egrep -v "$skipped_params" |
14674                 xargs -n 1 find $proc_dirs -name |
14675                 xargs -n 1 badarea_io ||
14676                 error "client badarea_io failed"
14677
14678         # remount the FS in case writes/reads /proc break the FS
14679         cleanup || error "failed to unmount"
14680         setup || error "failed to setup"
14681 }
14682 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14683
14684 test_133g() {
14685         remote_mds_nodsh && skip "remote MDS with nodsh"
14686         remote_ost_nodsh && skip "remote OST with nodsh"
14687
14688         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14689         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14690         local facet
14691         for facet in mds1 ost1; do
14692                 local facet_ver=$(lustre_version_code $facet)
14693                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14694                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14695                 else
14696                         log "$facet: too old lustre for get_param -R"
14697                 fi
14698                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14699                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14700                                 tr -d = | egrep -v $skipped_params |
14701                                 xargs -n 1 find $proc_dirs -name |
14702                                 xargs -n 1 badarea_io" ||
14703                                         error "$facet badarea_io failed"
14704                 else
14705                         skip_noexit "$facet: too old lustre for get_param -R"
14706                 fi
14707         done
14708
14709         # remount the FS in case writes/reads /proc break the FS
14710         cleanup || error "failed to unmount"
14711         setup || error "failed to setup"
14712 }
14713 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14714
14715 test_133h() {
14716         remote_mds_nodsh && skip "remote MDS with nodsh"
14717         remote_ost_nodsh && skip "remote OST with nodsh"
14718         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14719                 skip "Need MDS version at least 2.9.54"
14720
14721         local facet
14722         for facet in client mds1 ost1; do
14723                 # Get the list of files that are missing the terminating newline
14724                 local plist=$(do_facet $facet
14725                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14726                 local ent
14727                 for ent in $plist; do
14728                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14729                                 awk -v FS='\v' -v RS='\v\v' \
14730                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14731                                         print FILENAME}'" 2>/dev/null)
14732                         [ -z $missing ] || {
14733                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14734                                 error "file does not end with newline: $facet-$ent"
14735                         }
14736                 done
14737         done
14738 }
14739 run_test 133h "Proc files should end with newlines"
14740
14741 test_134a() {
14742         remote_mds_nodsh && skip "remote MDS with nodsh"
14743         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14744                 skip "Need MDS version at least 2.7.54"
14745
14746         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14747         cancel_lru_locks mdc
14748
14749         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14750         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14751         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14752
14753         local nr=1000
14754         createmany -o $DIR/$tdir/f $nr ||
14755                 error "failed to create $nr files in $DIR/$tdir"
14756         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14757
14758         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14759         do_facet mds1 $LCTL set_param fail_loc=0x327
14760         do_facet mds1 $LCTL set_param fail_val=500
14761         touch $DIR/$tdir/m
14762
14763         echo "sleep 10 seconds ..."
14764         sleep 10
14765         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14766
14767         do_facet mds1 $LCTL set_param fail_loc=0
14768         do_facet mds1 $LCTL set_param fail_val=0
14769         [ $lck_cnt -lt $unused ] ||
14770                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14771
14772         rm $DIR/$tdir/m
14773         unlinkmany $DIR/$tdir/f $nr
14774 }
14775 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14776
14777 test_134b() {
14778         remote_mds_nodsh && skip "remote MDS with nodsh"
14779         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14780                 skip "Need MDS version at least 2.7.54"
14781
14782         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14783         cancel_lru_locks mdc
14784
14785         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14786                         ldlm.lock_reclaim_threshold_mb)
14787         # disable reclaim temporarily
14788         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14789
14790         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14791         do_facet mds1 $LCTL set_param fail_loc=0x328
14792         do_facet mds1 $LCTL set_param fail_val=500
14793
14794         $LCTL set_param debug=+trace
14795
14796         local nr=600
14797         createmany -o $DIR/$tdir/f $nr &
14798         local create_pid=$!
14799
14800         echo "Sleep $TIMEOUT seconds ..."
14801         sleep $TIMEOUT
14802         if ! ps -p $create_pid  > /dev/null 2>&1; then
14803                 do_facet mds1 $LCTL set_param fail_loc=0
14804                 do_facet mds1 $LCTL set_param fail_val=0
14805                 do_facet mds1 $LCTL set_param \
14806                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14807                 error "createmany finished incorrectly!"
14808         fi
14809         do_facet mds1 $LCTL set_param fail_loc=0
14810         do_facet mds1 $LCTL set_param fail_val=0
14811         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14812         wait $create_pid || return 1
14813
14814         unlinkmany $DIR/$tdir/f $nr
14815 }
14816 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14817
14818 test_135() {
14819         remote_mds_nodsh && skip "remote MDS with nodsh"
14820         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14821                 skip "Need MDS version at least 2.13.50"
14822         local fname
14823
14824         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14825
14826 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14827         #set only one record at plain llog
14828         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14829
14830         #fill already existed plain llog each 64767
14831         #wrapping whole catalog
14832         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14833
14834         createmany -o $DIR/$tdir/$tfile_ 64700
14835         for (( i = 0; i < 64700; i = i + 2 ))
14836         do
14837                 rm $DIR/$tdir/$tfile_$i &
14838                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14839                 local pid=$!
14840                 wait $pid
14841         done
14842
14843         #waiting osp synchronization
14844         wait_delete_completed
14845 }
14846 run_test 135 "Race catalog processing"
14847
14848 test_136() {
14849         remote_mds_nodsh && skip "remote MDS with nodsh"
14850         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14851                 skip "Need MDS version at least 2.13.50"
14852         local fname
14853
14854         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14855         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14856         #set only one record at plain llog
14857 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14858         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14859
14860         #fill already existed 2 plain llogs each 64767
14861         #wrapping whole catalog
14862         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14863         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14864         wait_delete_completed
14865
14866         createmany -o $DIR/$tdir/$tfile_ 10
14867         sleep 25
14868
14869         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14870         for (( i = 0; i < 10; i = i + 3 ))
14871         do
14872                 rm $DIR/$tdir/$tfile_$i &
14873                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14874                 local pid=$!
14875                 wait $pid
14876                 sleep 7
14877                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14878         done
14879
14880         #waiting osp synchronization
14881         wait_delete_completed
14882 }
14883 run_test 136 "Race catalog processing 2"
14884
14885 test_140() { #bug-17379
14886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14887
14888         test_mkdir $DIR/$tdir
14889         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14890         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14891
14892         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14893         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14894         local i=0
14895         while i=$((i + 1)); do
14896                 test_mkdir $i
14897                 cd $i || error "Changing to $i"
14898                 ln -s ../stat stat || error "Creating stat symlink"
14899                 # Read the symlink until ELOOP present,
14900                 # not LBUGing the system is considered success,
14901                 # we didn't overrun the stack.
14902                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14903                 if [ $ret -ne 0 ]; then
14904                         if [ $ret -eq 40 ]; then
14905                                 break  # -ELOOP
14906                         else
14907                                 error "Open stat symlink"
14908                                         return
14909                         fi
14910                 fi
14911         done
14912         i=$((i - 1))
14913         echo "The symlink depth = $i"
14914         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14915                 error "Invalid symlink depth"
14916
14917         # Test recursive symlink
14918         ln -s symlink_self symlink_self
14919         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14920         echo "open symlink_self returns $ret"
14921         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14922 }
14923 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14924
14925 test_150a() {
14926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14927
14928         local TF="$TMP/$tfile"
14929
14930         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14931         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14932         cp $TF $DIR/$tfile
14933         cancel_lru_locks $OSC
14934         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14935         remount_client $MOUNT
14936         df -P $MOUNT
14937         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14938
14939         $TRUNCATE $TF 6000
14940         $TRUNCATE $DIR/$tfile 6000
14941         cancel_lru_locks $OSC
14942         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14943
14944         echo "12345" >>$TF
14945         echo "12345" >>$DIR/$tfile
14946         cancel_lru_locks $OSC
14947         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14948
14949         echo "12345" >>$TF
14950         echo "12345" >>$DIR/$tfile
14951         cancel_lru_locks $OSC
14952         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14953 }
14954 run_test 150a "truncate/append tests"
14955
14956 test_150b() {
14957         check_set_fallocate_or_skip
14958
14959         touch $DIR/$tfile
14960         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14961         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14962 }
14963 run_test 150b "Verify fallocate (prealloc) functionality"
14964
14965 test_150bb() {
14966         check_set_fallocate_or_skip
14967
14968         touch $DIR/$tfile
14969         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14970         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14971         > $DIR/$tfile
14972         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14973         # precomputed md5sum for 20MB of zeroes
14974         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14975         local sum=($(md5sum $DIR/$tfile))
14976
14977         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14978
14979         check_set_fallocate 1
14980
14981         > $DIR/$tfile
14982         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14983         sum=($(md5sum $DIR/$tfile))
14984
14985         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14986 }
14987 run_test 150bb "Verify fallocate modes both zero space"
14988
14989 test_150c() {
14990         check_set_fallocate_or_skip
14991         local striping="-c2"
14992
14993         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14994         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14995         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14996         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14997         local want=$((OSTCOUNT * 1048576))
14998
14999         # Must allocate all requested space, not more than 5% extra
15000         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15001                 error "bytes $bytes is not $want"
15002
15003         rm -f $DIR/$tfile
15004
15005         echo "verify fallocate on PFL file"
15006
15007         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15008
15009         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15010                 error "Create $DIR/$tfile failed"
15011         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15012         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15013         want=$((512 * 1048576))
15014
15015         # Must allocate all requested space, not more than 5% extra
15016         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15017                 error "bytes $bytes is not $want"
15018 }
15019 run_test 150c "Verify fallocate Size and Blocks"
15020
15021 test_150d() {
15022         check_set_fallocate_or_skip
15023         local striping="-c2"
15024
15025         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15026
15027         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15028         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15029                 error "setstripe failed"
15030         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15031         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15032         local want=$((OSTCOUNT * 1048576))
15033
15034         # Must allocate all requested space, not more than 5% extra
15035         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15036                 error "bytes $bytes is not $want"
15037 }
15038 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15039
15040 test_150e() {
15041         check_set_fallocate_or_skip
15042
15043         echo "df before:"
15044         $LFS df
15045         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15046         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15047                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15048
15049         # Find OST with Minimum Size
15050         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15051                        sort -un | head -1)
15052
15053         # Get 100MB per OST of the available space to reduce run time
15054         # else 60% of the available space if we are running SLOW tests
15055         if [ $SLOW == "no" ]; then
15056                 local space=$((1024 * 100 * OSTCOUNT))
15057         else
15058                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15059         fi
15060
15061         fallocate -l${space}k $DIR/$tfile ||
15062                 error "fallocate ${space}k $DIR/$tfile failed"
15063         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15064
15065         # get size immediately after fallocate. This should be correctly
15066         # updated
15067         local size=$(stat -c '%s' $DIR/$tfile)
15068         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15069
15070         # Sleep for a while for statfs to get updated. And not pull from cache.
15071         sleep 2
15072
15073         echo "df after fallocate:"
15074         $LFS df
15075
15076         (( size / 1024 == space )) || error "size $size != requested $space"
15077         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15078                 error "used $used < space $space"
15079
15080         rm $DIR/$tfile || error "rm failed"
15081         sync
15082         wait_delete_completed
15083
15084         echo "df after unlink:"
15085         $LFS df
15086 }
15087 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15088
15089 test_150f() {
15090         local size
15091         local blocks
15092         local want_size_before=20480 # in bytes
15093         local want_blocks_before=40 # 512 sized blocks
15094         local want_blocks_after=24  # 512 sized blocks
15095         local length=$(((want_blocks_before - want_blocks_after) * 512))
15096
15097         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15098                 skip "need at least 2.14.0 for fallocate punch"
15099
15100         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15101                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15102         fi
15103
15104         check_set_fallocate_or_skip
15105         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15106
15107         [[ "x$DOM" == "xyes" ]] &&
15108                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15109
15110         echo "Verify fallocate punch: Range within the file range"
15111         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15112                 error "dd failed for bs 4096 and count 5"
15113
15114         # Call fallocate with punch range which is within the file range
15115         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15116                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15117         # client must see changes immediately after fallocate
15118         size=$(stat -c '%s' $DIR/$tfile)
15119         blocks=$(stat -c '%b' $DIR/$tfile)
15120
15121         # Verify punch worked.
15122         (( blocks == want_blocks_after )) ||
15123                 error "punch failed: blocks $blocks != $want_blocks_after"
15124
15125         (( size == want_size_before )) ||
15126                 error "punch failed: size $size != $want_size_before"
15127
15128         # Verify there is hole in file
15129         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15130         # precomputed md5sum
15131         local expect="4a9a834a2db02452929c0a348273b4aa"
15132
15133         cksum=($(md5sum $DIR/$tfile))
15134         [[ "${cksum[0]}" == "$expect" ]] ||
15135                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15136
15137         # Start second sub-case for fallocate punch.
15138         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15139         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15140                 error "dd failed for bs 4096 and count 5"
15141
15142         # Punch range less than block size will have no change in block count
15143         want_blocks_after=40  # 512 sized blocks
15144
15145         # Punch overlaps two blocks and less than blocksize
15146         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15147                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15148         size=$(stat -c '%s' $DIR/$tfile)
15149         blocks=$(stat -c '%b' $DIR/$tfile)
15150
15151         # Verify punch worked.
15152         (( blocks == want_blocks_after )) ||
15153                 error "punch failed: blocks $blocks != $want_blocks_after"
15154
15155         (( size == want_size_before )) ||
15156                 error "punch failed: size $size != $want_size_before"
15157
15158         # Verify if range is really zero'ed out. We expect Zeros.
15159         # precomputed md5sum
15160         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15161         cksum=($(md5sum $DIR/$tfile))
15162         [[ "${cksum[0]}" == "$expect" ]] ||
15163                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15164 }
15165 run_test 150f "Verify fallocate punch functionality"
15166
15167 test_150g() {
15168         local space
15169         local size
15170         local blocks
15171         local blocks_after
15172         local size_after
15173         local BS=4096 # Block size in bytes
15174
15175         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15176                 skip "need at least 2.14.0 for fallocate punch"
15177
15178         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15179                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15180         fi
15181
15182         check_set_fallocate_or_skip
15183         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15184
15185         if [[ "x$DOM" == "xyes" ]]; then
15186                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15187                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15188         else
15189                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15190                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15191         fi
15192
15193         # Get 100MB per OST of the available space to reduce run time
15194         # else 60% of the available space if we are running SLOW tests
15195         if [ $SLOW == "no" ]; then
15196                 space=$((1024 * 100 * OSTCOUNT))
15197         else
15198                 # Find OST with Minimum Size
15199                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15200                         sort -un | head -1)
15201                 echo "min size OST: $space"
15202                 space=$(((space * 60)/100 * OSTCOUNT))
15203         fi
15204         # space in 1k units, round to 4k blocks
15205         local blkcount=$((space * 1024 / $BS))
15206
15207         echo "Verify fallocate punch: Very large Range"
15208         fallocate -l${space}k $DIR/$tfile ||
15209                 error "fallocate ${space}k $DIR/$tfile failed"
15210         # write 1M at the end, start and in the middle
15211         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15212                 error "dd failed: bs $BS count 256"
15213         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15214                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15215         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15216                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15217
15218         # Gather stats.
15219         size=$(stat -c '%s' $DIR/$tfile)
15220
15221         # gather punch length.
15222         local punch_size=$((size - (BS * 2)))
15223
15224         echo "punch_size = $punch_size"
15225         echo "size - punch_size: $((size - punch_size))"
15226         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15227
15228         # Call fallocate to punch all except 2 blocks. We leave the
15229         # first and the last block
15230         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15231         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15232                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15233
15234         size_after=$(stat -c '%s' $DIR/$tfile)
15235         blocks_after=$(stat -c '%b' $DIR/$tfile)
15236
15237         # Verify punch worked.
15238         # Size should be kept
15239         (( size == size_after )) ||
15240                 error "punch failed: size $size != $size_after"
15241
15242         # two 4k data blocks to remain plus possible 1 extra extent block
15243         (( blocks_after <= ((BS / 512) * 3) )) ||
15244                 error "too many blocks remains: $blocks_after"
15245
15246         # Verify that file has hole between the first and the last blocks
15247         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15248         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15249
15250         echo "Hole at [$hole_start, $hole_end)"
15251         (( hole_start == BS )) ||
15252                 error "no hole at offset $BS after punch"
15253
15254         (( hole_end == BS + punch_size )) ||
15255                 error "data at offset $hole_end < $((BS + punch_size))"
15256 }
15257 run_test 150g "Verify fallocate punch on large range"
15258
15259 #LU-2902 roc_hit was not able to read all values from lproc
15260 function roc_hit_init() {
15261         local list=$(comma_list $(osts_nodes))
15262         local dir=$DIR/$tdir-check
15263         local file=$dir/$tfile
15264         local BEFORE
15265         local AFTER
15266         local idx
15267
15268         test_mkdir $dir
15269         #use setstripe to do a write to every ost
15270         for i in $(seq 0 $((OSTCOUNT-1))); do
15271                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15272                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15273                 idx=$(printf %04x $i)
15274                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15275                         awk '$1 == "cache_access" {sum += $7}
15276                                 END { printf("%0.0f", sum) }')
15277
15278                 cancel_lru_locks osc
15279                 cat $file >/dev/null
15280
15281                 AFTER=$(get_osd_param $list *OST*$idx stats |
15282                         awk '$1 == "cache_access" {sum += $7}
15283                                 END { printf("%0.0f", sum) }')
15284
15285                 echo BEFORE:$BEFORE AFTER:$AFTER
15286                 if ! let "AFTER - BEFORE == 4"; then
15287                         rm -rf $dir
15288                         error "roc_hit is not safe to use"
15289                 fi
15290                 rm $file
15291         done
15292
15293         rm -rf $dir
15294 }
15295
15296 function roc_hit() {
15297         local list=$(comma_list $(osts_nodes))
15298         echo $(get_osd_param $list '' stats |
15299                 awk '$1 == "cache_hit" {sum += $7}
15300                         END { printf("%0.0f", sum) }')
15301 }
15302
15303 function set_cache() {
15304         local on=1
15305
15306         if [ "$2" == "off" ]; then
15307                 on=0;
15308         fi
15309         local list=$(comma_list $(osts_nodes))
15310         set_osd_param $list '' $1_cache_enable $on
15311
15312         cancel_lru_locks osc
15313 }
15314
15315 test_151() {
15316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15317         remote_ost_nodsh && skip "remote OST with nodsh"
15318
15319         local CPAGES=3
15320         local list=$(comma_list $(osts_nodes))
15321
15322         # check whether obdfilter is cache capable at all
15323         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15324                 skip "not cache-capable obdfilter"
15325         fi
15326
15327         # check cache is enabled on all obdfilters
15328         if get_osd_param $list '' read_cache_enable | grep 0; then
15329                 skip "oss cache is disabled"
15330         fi
15331
15332         set_osd_param $list '' writethrough_cache_enable 1
15333
15334         # check write cache is enabled on all obdfilters
15335         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15336                 skip "oss write cache is NOT enabled"
15337         fi
15338
15339         roc_hit_init
15340
15341         #define OBD_FAIL_OBD_NO_LRU  0x609
15342         do_nodes $list $LCTL set_param fail_loc=0x609
15343
15344         # pages should be in the case right after write
15345         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15346                 error "dd failed"
15347
15348         local BEFORE=$(roc_hit)
15349         cancel_lru_locks osc
15350         cat $DIR/$tfile >/dev/null
15351         local AFTER=$(roc_hit)
15352
15353         do_nodes $list $LCTL set_param fail_loc=0
15354
15355         if ! let "AFTER - BEFORE == CPAGES"; then
15356                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15357         fi
15358
15359         cancel_lru_locks osc
15360         # invalidates OST cache
15361         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15362         set_osd_param $list '' read_cache_enable 0
15363         cat $DIR/$tfile >/dev/null
15364
15365         # now data shouldn't be found in the cache
15366         BEFORE=$(roc_hit)
15367         cancel_lru_locks osc
15368         cat $DIR/$tfile >/dev/null
15369         AFTER=$(roc_hit)
15370         if let "AFTER - BEFORE != 0"; then
15371                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15372         fi
15373
15374         set_osd_param $list '' read_cache_enable 1
15375         rm -f $DIR/$tfile
15376 }
15377 run_test 151 "test cache on oss and controls ==============================="
15378
15379 test_152() {
15380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15381
15382         local TF="$TMP/$tfile"
15383
15384         # simulate ENOMEM during write
15385 #define OBD_FAIL_OST_NOMEM      0x226
15386         lctl set_param fail_loc=0x80000226
15387         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15388         cp $TF $DIR/$tfile
15389         sync || error "sync failed"
15390         lctl set_param fail_loc=0
15391
15392         # discard client's cache
15393         cancel_lru_locks osc
15394
15395         # simulate ENOMEM during read
15396         lctl set_param fail_loc=0x80000226
15397         cmp $TF $DIR/$tfile || error "cmp failed"
15398         lctl set_param fail_loc=0
15399
15400         rm -f $TF
15401 }
15402 run_test 152 "test read/write with enomem ============================"
15403
15404 test_153() {
15405         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15406 }
15407 run_test 153 "test if fdatasync does not crash ======================="
15408
15409 dot_lustre_fid_permission_check() {
15410         local fid=$1
15411         local ffid=$MOUNT/.lustre/fid/$fid
15412         local test_dir=$2
15413
15414         echo "stat fid $fid"
15415         stat $ffid || error "stat $ffid failed."
15416         echo "touch fid $fid"
15417         touch $ffid || error "touch $ffid failed."
15418         echo "write to fid $fid"
15419         cat /etc/hosts > $ffid || error "write $ffid failed."
15420         echo "read fid $fid"
15421         diff /etc/hosts $ffid || error "read $ffid failed."
15422         echo "append write to fid $fid"
15423         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15424         echo "rename fid $fid"
15425         mv $ffid $test_dir/$tfile.1 &&
15426                 error "rename $ffid to $tfile.1 should fail."
15427         touch $test_dir/$tfile.1
15428         mv $test_dir/$tfile.1 $ffid &&
15429                 error "rename $tfile.1 to $ffid should fail."
15430         rm -f $test_dir/$tfile.1
15431         echo "truncate fid $fid"
15432         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15433         echo "link fid $fid"
15434         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15435         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15436                 echo "setfacl fid $fid"
15437                 setfacl -R -m u:$USER0:rwx $ffid ||
15438                         error "setfacl $ffid failed"
15439                 echo "getfacl fid $fid"
15440                 getfacl $ffid || error "getfacl $ffid failed."
15441         fi
15442         echo "unlink fid $fid"
15443         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15444         echo "mknod fid $fid"
15445         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15446
15447         fid=[0xf00000400:0x1:0x0]
15448         ffid=$MOUNT/.lustre/fid/$fid
15449
15450         echo "stat non-exist fid $fid"
15451         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15452         echo "write to non-exist fid $fid"
15453         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15454         echo "link new fid $fid"
15455         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15456
15457         mkdir -p $test_dir/$tdir
15458         touch $test_dir/$tdir/$tfile
15459         fid=$($LFS path2fid $test_dir/$tdir)
15460         rc=$?
15461         [ $rc -ne 0 ] &&
15462                 error "error: could not get fid for $test_dir/$dir/$tfile."
15463
15464         ffid=$MOUNT/.lustre/fid/$fid
15465
15466         echo "ls $fid"
15467         ls $ffid || error "ls $ffid failed."
15468         echo "touch $fid/$tfile.1"
15469         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15470
15471         echo "touch $MOUNT/.lustre/fid/$tfile"
15472         touch $MOUNT/.lustre/fid/$tfile && \
15473                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15474
15475         echo "setxattr to $MOUNT/.lustre/fid"
15476         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15477
15478         echo "listxattr for $MOUNT/.lustre/fid"
15479         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15480
15481         echo "delxattr from $MOUNT/.lustre/fid"
15482         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15483
15484         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15485         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15486                 error "touch invalid fid should fail."
15487
15488         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15489         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15490                 error "touch non-normal fid should fail."
15491
15492         echo "rename $tdir to $MOUNT/.lustre/fid"
15493         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15494                 error "rename to $MOUNT/.lustre/fid should fail."
15495
15496         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15497         then            # LU-3547
15498                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15499                 local new_obf_mode=777
15500
15501                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15502                 chmod $new_obf_mode $DIR/.lustre/fid ||
15503                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15504
15505                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15506                 [ $obf_mode -eq $new_obf_mode ] ||
15507                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15508
15509                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15510                 chmod $old_obf_mode $DIR/.lustre/fid ||
15511                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15512         fi
15513
15514         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15515         fid=$($LFS path2fid $test_dir/$tfile-2)
15516
15517         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15518         then # LU-5424
15519                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15520                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15521                         error "create lov data thru .lustre failed"
15522         fi
15523         echo "cp /etc/passwd $test_dir/$tfile-2"
15524         cp /etc/passwd $test_dir/$tfile-2 ||
15525                 error "copy to $test_dir/$tfile-2 failed."
15526         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15527         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15528                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15529
15530         rm -rf $test_dir/tfile.lnk
15531         rm -rf $test_dir/$tfile-2
15532 }
15533
15534 test_154A() {
15535         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15536                 skip "Need MDS version at least 2.4.1"
15537
15538         local tf=$DIR/$tfile
15539         touch $tf
15540
15541         local fid=$($LFS path2fid $tf)
15542         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15543
15544         # check that we get the same pathname back
15545         local rootpath
15546         local found
15547         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15548                 echo "$rootpath $fid"
15549                 found=$($LFS fid2path $rootpath "$fid")
15550                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15551                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15552         done
15553
15554         # check wrong root path format
15555         rootpath=$MOUNT"_wrong"
15556         found=$($LFS fid2path $rootpath "$fid")
15557         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15558 }
15559 run_test 154A "lfs path2fid and fid2path basic checks"
15560
15561 test_154B() {
15562         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15563                 skip "Need MDS version at least 2.4.1"
15564
15565         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15566         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15567         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15568         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15569
15570         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15571         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15572
15573         # check that we get the same pathname
15574         echo "PFID: $PFID, name: $name"
15575         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15576         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15577         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15578                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15579
15580         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15581 }
15582 run_test 154B "verify the ll_decode_linkea tool"
15583
15584 test_154a() {
15585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15586         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15587         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15588                 skip "Need MDS version at least 2.2.51"
15589         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15590
15591         cp /etc/hosts $DIR/$tfile
15592
15593         fid=$($LFS path2fid $DIR/$tfile)
15594         rc=$?
15595         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15596
15597         dot_lustre_fid_permission_check "$fid" $DIR ||
15598                 error "dot lustre permission check $fid failed"
15599
15600         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15601
15602         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15603
15604         touch $MOUNT/.lustre/file &&
15605                 error "creation is not allowed under .lustre"
15606
15607         mkdir $MOUNT/.lustre/dir &&
15608                 error "mkdir is not allowed under .lustre"
15609
15610         rm -rf $DIR/$tfile
15611 }
15612 run_test 154a "Open-by-FID"
15613
15614 test_154b() {
15615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15617         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15618         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15619                 skip "Need MDS version at least 2.2.51"
15620
15621         local remote_dir=$DIR/$tdir/remote_dir
15622         local MDTIDX=1
15623         local rc=0
15624
15625         mkdir -p $DIR/$tdir
15626         $LFS mkdir -i $MDTIDX $remote_dir ||
15627                 error "create remote directory failed"
15628
15629         cp /etc/hosts $remote_dir/$tfile
15630
15631         fid=$($LFS path2fid $remote_dir/$tfile)
15632         rc=$?
15633         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15634
15635         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15636                 error "dot lustre permission check $fid failed"
15637         rm -rf $DIR/$tdir
15638 }
15639 run_test 154b "Open-by-FID for remote directory"
15640
15641 test_154c() {
15642         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15643                 skip "Need MDS version at least 2.4.1"
15644
15645         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15646         local FID1=$($LFS path2fid $DIR/$tfile.1)
15647         local FID2=$($LFS path2fid $DIR/$tfile.2)
15648         local FID3=$($LFS path2fid $DIR/$tfile.3)
15649
15650         local N=1
15651         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15652                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15653                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15654                 local want=FID$N
15655                 [ "$FID" = "${!want}" ] ||
15656                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15657                 N=$((N + 1))
15658         done
15659
15660         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15661         do
15662                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15663                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15664                 N=$((N + 1))
15665         done
15666 }
15667 run_test 154c "lfs path2fid and fid2path multiple arguments"
15668
15669 test_154d() {
15670         remote_mds_nodsh && skip "remote MDS with nodsh"
15671         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15672                 skip "Need MDS version at least 2.5.53"
15673
15674         if remote_mds; then
15675                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15676         else
15677                 nid="0@lo"
15678         fi
15679         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15680         local fd
15681         local cmd
15682
15683         rm -f $DIR/$tfile
15684         touch $DIR/$tfile
15685
15686         local fid=$($LFS path2fid $DIR/$tfile)
15687         # Open the file
15688         fd=$(free_fd)
15689         cmd="exec $fd<$DIR/$tfile"
15690         eval $cmd
15691         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15692         echo "$fid_list" | grep "$fid"
15693         rc=$?
15694
15695         cmd="exec $fd>/dev/null"
15696         eval $cmd
15697         if [ $rc -ne 0 ]; then
15698                 error "FID $fid not found in open files list $fid_list"
15699         fi
15700 }
15701 run_test 154d "Verify open file fid"
15702
15703 test_154e()
15704 {
15705         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15706                 skip "Need MDS version at least 2.6.50"
15707
15708         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15709                 error ".lustre returned by readdir"
15710         fi
15711 }
15712 run_test 154e ".lustre is not returned by readdir"
15713
15714 test_154f() {
15715         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15716
15717         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15718         mkdir_on_mdt0 $DIR/$tdir
15719         # test dirs inherit from its stripe
15720         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15721         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15722         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15723         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15724         touch $DIR/f
15725
15726         # get fid of parents
15727         local FID0=$($LFS path2fid $DIR/$tdir)
15728         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15729         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15730         local FID3=$($LFS path2fid $DIR)
15731
15732         # check that path2fid --parents returns expected <parent_fid>/name
15733         # 1) test for a directory (single parent)
15734         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15735         [ "$parent" == "$FID0/foo1" ] ||
15736                 error "expected parent: $FID0/foo1, got: $parent"
15737
15738         # 2) test for a file with nlink > 1 (multiple parents)
15739         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15740         echo "$parent" | grep -F "$FID1/$tfile" ||
15741                 error "$FID1/$tfile not returned in parent list"
15742         echo "$parent" | grep -F "$FID2/link" ||
15743                 error "$FID2/link not returned in parent list"
15744
15745         # 3) get parent by fid
15746         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15747         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15748         echo "$parent" | grep -F "$FID1/$tfile" ||
15749                 error "$FID1/$tfile not returned in parent list (by fid)"
15750         echo "$parent" | grep -F "$FID2/link" ||
15751                 error "$FID2/link not returned in parent list (by fid)"
15752
15753         # 4) test for entry in root directory
15754         parent=$($LFS path2fid --parents $DIR/f)
15755         echo "$parent" | grep -F "$FID3/f" ||
15756                 error "$FID3/f not returned in parent list"
15757
15758         # 5) test it on root directory
15759         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15760                 error "$MOUNT should not have parents"
15761
15762         # enable xattr caching and check that linkea is correctly updated
15763         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15764         save_lustre_params client "llite.*.xattr_cache" > $save
15765         lctl set_param llite.*.xattr_cache 1
15766
15767         # 6.1) linkea update on rename
15768         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15769
15770         # get parents by fid
15771         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15772         # foo1 should no longer be returned in parent list
15773         echo "$parent" | grep -F "$FID1" &&
15774                 error "$FID1 should no longer be in parent list"
15775         # the new path should appear
15776         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15777                 error "$FID2/$tfile.moved is not in parent list"
15778
15779         # 6.2) linkea update on unlink
15780         rm -f $DIR/$tdir/foo2/link
15781         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15782         # foo2/link should no longer be returned in parent list
15783         echo "$parent" | grep -F "$FID2/link" &&
15784                 error "$FID2/link should no longer be in parent list"
15785         true
15786
15787         rm -f $DIR/f
15788         restore_lustre_params < $save
15789         rm -f $save
15790 }
15791 run_test 154f "get parent fids by reading link ea"
15792
15793 test_154g()
15794 {
15795         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15796         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15797            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15798                 skip "Need MDS version at least 2.6.92"
15799
15800         mkdir_on_mdt0 $DIR/$tdir
15801         llapi_fid_test -d $DIR/$tdir
15802 }
15803 run_test 154g "various llapi FID tests"
15804
15805 test_155_small_load() {
15806     local temp=$TMP/$tfile
15807     local file=$DIR/$tfile
15808
15809     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15810         error "dd of=$temp bs=6096 count=1 failed"
15811     cp $temp $file
15812     cancel_lru_locks $OSC
15813     cmp $temp $file || error "$temp $file differ"
15814
15815     $TRUNCATE $temp 6000
15816     $TRUNCATE $file 6000
15817     cmp $temp $file || error "$temp $file differ (truncate1)"
15818
15819     echo "12345" >>$temp
15820     echo "12345" >>$file
15821     cmp $temp $file || error "$temp $file differ (append1)"
15822
15823     echo "12345" >>$temp
15824     echo "12345" >>$file
15825     cmp $temp $file || error "$temp $file differ (append2)"
15826
15827     rm -f $temp $file
15828     true
15829 }
15830
15831 test_155_big_load() {
15832         remote_ost_nodsh && skip "remote OST with nodsh"
15833
15834         local temp=$TMP/$tfile
15835         local file=$DIR/$tfile
15836
15837         free_min_max
15838         local cache_size=$(do_facet ost$((MAXI+1)) \
15839                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15840
15841         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15842         # pre-set value
15843         if [ -z "$cache_size" ]; then
15844                 cache_size=256
15845         fi
15846         local large_file_size=$((cache_size * 2))
15847
15848         echo "OSS cache size: $cache_size KB"
15849         echo "Large file size: $large_file_size KB"
15850
15851         [ $MAXV -le $large_file_size ] &&
15852                 skip_env "max available OST size needs > $large_file_size KB"
15853
15854         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15855
15856         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15857                 error "dd of=$temp bs=$large_file_size count=1k failed"
15858         cp $temp $file
15859         ls -lh $temp $file
15860         cancel_lru_locks osc
15861         cmp $temp $file || error "$temp $file differ"
15862
15863         rm -f $temp $file
15864         true
15865 }
15866
15867 save_writethrough() {
15868         local facets=$(get_facets OST)
15869
15870         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15871 }
15872
15873 test_155a() {
15874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15875
15876         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15877
15878         save_writethrough $p
15879
15880         set_cache read on
15881         set_cache writethrough on
15882         test_155_small_load
15883         restore_lustre_params < $p
15884         rm -f $p
15885 }
15886 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15887
15888 test_155b() {
15889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15890
15891         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15892
15893         save_writethrough $p
15894
15895         set_cache read on
15896         set_cache writethrough off
15897         test_155_small_load
15898         restore_lustre_params < $p
15899         rm -f $p
15900 }
15901 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15902
15903 test_155c() {
15904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15905
15906         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15907
15908         save_writethrough $p
15909
15910         set_cache read off
15911         set_cache writethrough on
15912         test_155_small_load
15913         restore_lustre_params < $p
15914         rm -f $p
15915 }
15916 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15917
15918 test_155d() {
15919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15920
15921         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15922
15923         save_writethrough $p
15924
15925         set_cache read off
15926         set_cache writethrough off
15927         test_155_small_load
15928         restore_lustre_params < $p
15929         rm -f $p
15930 }
15931 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15932
15933 test_155e() {
15934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15935
15936         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15937
15938         save_writethrough $p
15939
15940         set_cache read on
15941         set_cache writethrough on
15942         test_155_big_load
15943         restore_lustre_params < $p
15944         rm -f $p
15945 }
15946 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15947
15948 test_155f() {
15949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15950
15951         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15952
15953         save_writethrough $p
15954
15955         set_cache read on
15956         set_cache writethrough off
15957         test_155_big_load
15958         restore_lustre_params < $p
15959         rm -f $p
15960 }
15961 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15962
15963 test_155g() {
15964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15965
15966         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15967
15968         save_writethrough $p
15969
15970         set_cache read off
15971         set_cache writethrough on
15972         test_155_big_load
15973         restore_lustre_params < $p
15974         rm -f $p
15975 }
15976 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15977
15978 test_155h() {
15979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15980
15981         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15982
15983         save_writethrough $p
15984
15985         set_cache read off
15986         set_cache writethrough off
15987         test_155_big_load
15988         restore_lustre_params < $p
15989         rm -f $p
15990 }
15991 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15992
15993 test_156() {
15994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15995         remote_ost_nodsh && skip "remote OST with nodsh"
15996         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15997                 skip "stats not implemented on old servers"
15998         [ "$ost1_FSTYPE" = "zfs" ] &&
15999                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16000
16001         local CPAGES=3
16002         local BEFORE
16003         local AFTER
16004         local file="$DIR/$tfile"
16005         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16006
16007         save_writethrough $p
16008         roc_hit_init
16009
16010         log "Turn on read and write cache"
16011         set_cache read on
16012         set_cache writethrough on
16013
16014         log "Write data and read it back."
16015         log "Read should be satisfied from the cache."
16016         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16017         BEFORE=$(roc_hit)
16018         cancel_lru_locks osc
16019         cat $file >/dev/null
16020         AFTER=$(roc_hit)
16021         if ! let "AFTER - BEFORE == CPAGES"; then
16022                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16023         else
16024                 log "cache hits: before: $BEFORE, after: $AFTER"
16025         fi
16026
16027         log "Read again; it should be satisfied from the cache."
16028         BEFORE=$AFTER
16029         cancel_lru_locks osc
16030         cat $file >/dev/null
16031         AFTER=$(roc_hit)
16032         if ! let "AFTER - BEFORE == CPAGES"; then
16033                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16034         else
16035                 log "cache hits:: before: $BEFORE, after: $AFTER"
16036         fi
16037
16038         log "Turn off the read cache and turn on the write cache"
16039         set_cache read off
16040         set_cache writethrough on
16041
16042         log "Read again; it should be satisfied from the cache."
16043         BEFORE=$(roc_hit)
16044         cancel_lru_locks osc
16045         cat $file >/dev/null
16046         AFTER=$(roc_hit)
16047         if ! let "AFTER - BEFORE == CPAGES"; then
16048                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16049         else
16050                 log "cache hits:: before: $BEFORE, after: $AFTER"
16051         fi
16052
16053         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16054                 # > 2.12.56 uses pagecache if cached
16055                 log "Read again; it should not be satisfied from the cache."
16056                 BEFORE=$AFTER
16057                 cancel_lru_locks osc
16058                 cat $file >/dev/null
16059                 AFTER=$(roc_hit)
16060                 if ! let "AFTER - BEFORE == 0"; then
16061                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16062                 else
16063                         log "cache hits:: before: $BEFORE, after: $AFTER"
16064                 fi
16065         fi
16066
16067         log "Write data and read it back."
16068         log "Read should be satisfied from the cache."
16069         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16070         BEFORE=$(roc_hit)
16071         cancel_lru_locks osc
16072         cat $file >/dev/null
16073         AFTER=$(roc_hit)
16074         if ! let "AFTER - BEFORE == CPAGES"; then
16075                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16076         else
16077                 log "cache hits:: before: $BEFORE, after: $AFTER"
16078         fi
16079
16080         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16081                 # > 2.12.56 uses pagecache if cached
16082                 log "Read again; it should not be satisfied from the cache."
16083                 BEFORE=$AFTER
16084                 cancel_lru_locks osc
16085                 cat $file >/dev/null
16086                 AFTER=$(roc_hit)
16087                 if ! let "AFTER - BEFORE == 0"; then
16088                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16089                 else
16090                         log "cache hits:: before: $BEFORE, after: $AFTER"
16091                 fi
16092         fi
16093
16094         log "Turn off read and write cache"
16095         set_cache read off
16096         set_cache writethrough off
16097
16098         log "Write data and read it back"
16099         log "It should not be satisfied from the cache."
16100         rm -f $file
16101         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16102         cancel_lru_locks osc
16103         BEFORE=$(roc_hit)
16104         cat $file >/dev/null
16105         AFTER=$(roc_hit)
16106         if ! let "AFTER - BEFORE == 0"; then
16107                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16108         else
16109                 log "cache hits:: before: $BEFORE, after: $AFTER"
16110         fi
16111
16112         log "Turn on the read cache and turn off the write cache"
16113         set_cache read on
16114         set_cache writethrough off
16115
16116         log "Write data and read it back"
16117         log "It should not be satisfied from the cache."
16118         rm -f $file
16119         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16120         BEFORE=$(roc_hit)
16121         cancel_lru_locks osc
16122         cat $file >/dev/null
16123         AFTER=$(roc_hit)
16124         if ! let "AFTER - BEFORE == 0"; then
16125                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16126         else
16127                 log "cache hits:: before: $BEFORE, after: $AFTER"
16128         fi
16129
16130         log "Read again; it should be satisfied from the cache."
16131         BEFORE=$(roc_hit)
16132         cancel_lru_locks osc
16133         cat $file >/dev/null
16134         AFTER=$(roc_hit)
16135         if ! let "AFTER - BEFORE == CPAGES"; then
16136                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16137         else
16138                 log "cache hits:: before: $BEFORE, after: $AFTER"
16139         fi
16140
16141         restore_lustre_params < $p
16142         rm -f $p $file
16143 }
16144 run_test 156 "Verification of tunables"
16145
16146 test_160a() {
16147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16148         remote_mds_nodsh && skip "remote MDS with nodsh"
16149         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16150                 skip "Need MDS version at least 2.2.0"
16151
16152         changelog_register || error "changelog_register failed"
16153         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16154         changelog_users $SINGLEMDS | grep -q $cl_user ||
16155                 error "User $cl_user not found in changelog_users"
16156
16157         mkdir_on_mdt0 $DIR/$tdir
16158
16159         # change something
16160         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16161         changelog_clear 0 || error "changelog_clear failed"
16162         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16163         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16164         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16165         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16166         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16167         rm $DIR/$tdir/pics/desktop.jpg
16168
16169         echo "verifying changelog mask"
16170         changelog_chmask "-MKDIR"
16171         changelog_chmask "-CLOSE"
16172
16173         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16174         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16175
16176         changelog_chmask "+MKDIR"
16177         changelog_chmask "+CLOSE"
16178
16179         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16180         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16181
16182         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16183         CLOSES=$(changelog_dump | grep -c "CLOSE")
16184         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16185         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16186
16187         # verify contents
16188         echo "verifying target fid"
16189         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16190         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16191         [ "$fidc" == "$fidf" ] ||
16192                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16193         echo "verifying parent fid"
16194         # The FID returned from the Changelog may be the directory shard on
16195         # a different MDT, and not the FID returned by path2fid on the parent.
16196         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16197         # since this is what will matter when recreating this file in the tree.
16198         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16199         local pathp=$($LFS fid2path $MOUNT "$fidp")
16200         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16201                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16202
16203         echo "getting records for $cl_user"
16204         changelog_users $SINGLEMDS
16205         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16206         local nclr=3
16207         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16208                 error "changelog_clear failed"
16209         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16210         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16211         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16212                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16213
16214         local min0_rec=$(changelog_users $SINGLEMDS |
16215                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16216         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16217                           awk '{ print $1; exit; }')
16218
16219         changelog_dump | tail -n 5
16220         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16221         [ $first_rec == $((min0_rec + 1)) ] ||
16222                 error "first index should be $min0_rec + 1 not $first_rec"
16223
16224         # LU-3446 changelog index reset on MDT restart
16225         local cur_rec1=$(changelog_users $SINGLEMDS |
16226                          awk '/^current.index:/ { print $NF }')
16227         changelog_clear 0 ||
16228                 error "clear all changelog records for $cl_user failed"
16229         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16230         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16231                 error "Fail to start $SINGLEMDS"
16232         local cur_rec2=$(changelog_users $SINGLEMDS |
16233                          awk '/^current.index:/ { print $NF }')
16234         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16235         [ $cur_rec1 == $cur_rec2 ] ||
16236                 error "current index should be $cur_rec1 not $cur_rec2"
16237
16238         echo "verifying users from this test are deregistered"
16239         changelog_deregister || error "changelog_deregister failed"
16240         changelog_users $SINGLEMDS | grep -q $cl_user &&
16241                 error "User '$cl_user' still in changelog_users"
16242
16243         # lctl get_param -n mdd.*.changelog_users
16244         # current_index: 144
16245         # ID    index (idle seconds)
16246         # cl3   144   (2) mask=<list>
16247         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16248                 # this is the normal case where all users were deregistered
16249                 # make sure no new records are added when no users are present
16250                 local last_rec1=$(changelog_users $SINGLEMDS |
16251                                   awk '/^current.index:/ { print $NF }')
16252                 touch $DIR/$tdir/chloe
16253                 local last_rec2=$(changelog_users $SINGLEMDS |
16254                                   awk '/^current.index:/ { print $NF }')
16255                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16256                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16257         else
16258                 # any changelog users must be leftovers from a previous test
16259                 changelog_users $SINGLEMDS
16260                 echo "other changelog users; can't verify off"
16261         fi
16262 }
16263 run_test 160a "changelog sanity"
16264
16265 test_160b() { # LU-3587
16266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16267         remote_mds_nodsh && skip "remote MDS with nodsh"
16268         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16269                 skip "Need MDS version at least 2.2.0"
16270
16271         changelog_register || error "changelog_register failed"
16272         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16273         changelog_users $SINGLEMDS | grep -q $cl_user ||
16274                 error "User '$cl_user' not found in changelog_users"
16275
16276         local longname1=$(str_repeat a 255)
16277         local longname2=$(str_repeat b 255)
16278
16279         cd $DIR
16280         echo "creating very long named file"
16281         touch $longname1 || error "create of '$longname1' failed"
16282         echo "renaming very long named file"
16283         mv $longname1 $longname2
16284
16285         changelog_dump | grep RENME | tail -n 5
16286         rm -f $longname2
16287 }
16288 run_test 160b "Verify that very long rename doesn't crash in changelog"
16289
16290 test_160c() {
16291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16292         remote_mds_nodsh && skip "remote MDS with nodsh"
16293
16294         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16295                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16296                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16297                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16298
16299         local rc=0
16300
16301         # Registration step
16302         changelog_register || error "changelog_register failed"
16303
16304         rm -rf $DIR/$tdir
16305         mkdir -p $DIR/$tdir
16306         $MCREATE $DIR/$tdir/foo_160c
16307         changelog_chmask "-TRUNC"
16308         $TRUNCATE $DIR/$tdir/foo_160c 200
16309         changelog_chmask "+TRUNC"
16310         $TRUNCATE $DIR/$tdir/foo_160c 199
16311         changelog_dump | tail -n 5
16312         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16313         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16314 }
16315 run_test 160c "verify that changelog log catch the truncate event"
16316
16317 test_160d() {
16318         remote_mds_nodsh && skip "remote MDS with nodsh"
16319         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16321         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16322                 skip "Need MDS version at least 2.7.60"
16323
16324         # Registration step
16325         changelog_register || error "changelog_register failed"
16326
16327         mkdir -p $DIR/$tdir/migrate_dir
16328         changelog_clear 0 || error "changelog_clear failed"
16329
16330         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16331         changelog_dump | tail -n 5
16332         local migrates=$(changelog_dump | grep -c "MIGRT")
16333         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16334 }
16335 run_test 160d "verify that changelog log catch the migrate event"
16336
16337 test_160e() {
16338         remote_mds_nodsh && skip "remote MDS with nodsh"
16339
16340         # Create a user
16341         changelog_register || error "changelog_register failed"
16342
16343         local MDT0=$(facet_svc $SINGLEMDS)
16344         local rc
16345
16346         # No user (expect fail)
16347         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16348         rc=$?
16349         if [ $rc -eq 0 ]; then
16350                 error "Should fail without user"
16351         elif [ $rc -ne 4 ]; then
16352                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16353         fi
16354
16355         # Delete a future user (expect fail)
16356         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16357         rc=$?
16358         if [ $rc -eq 0 ]; then
16359                 error "Deleted non-existant user cl77"
16360         elif [ $rc -ne 2 ]; then
16361                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16362         fi
16363
16364         # Clear to a bad index (1 billion should be safe)
16365         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16366         rc=$?
16367
16368         if [ $rc -eq 0 ]; then
16369                 error "Successfully cleared to invalid CL index"
16370         elif [ $rc -ne 22 ]; then
16371                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16372         fi
16373 }
16374 run_test 160e "changelog negative testing (should return errors)"
16375
16376 test_160f() {
16377         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16378         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16379                 skip "Need MDS version at least 2.10.56"
16380
16381         local mdts=$(comma_list $(mdts_nodes))
16382
16383         # Create a user
16384         changelog_register || error "first changelog_register failed"
16385         changelog_register || error "second changelog_register failed"
16386         local cl_users
16387         declare -A cl_user1
16388         declare -A cl_user2
16389         local user_rec1
16390         local user_rec2
16391         local i
16392
16393         # generate some changelog records to accumulate on each MDT
16394         # use all_char because created files should be evenly distributed
16395         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16396                 error "test_mkdir $tdir failed"
16397         log "$(date +%s): creating first files"
16398         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16399                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16400                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16401         done
16402
16403         # check changelogs have been generated
16404         local start=$SECONDS
16405         local idle_time=$((MDSCOUNT * 5 + 5))
16406         local nbcl=$(changelog_dump | wc -l)
16407         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16408
16409         for param in "changelog_max_idle_time=$idle_time" \
16410                      "changelog_gc=1" \
16411                      "changelog_min_gc_interval=2" \
16412                      "changelog_min_free_cat_entries=3"; do
16413                 local MDT0=$(facet_svc $SINGLEMDS)
16414                 local var="${param%=*}"
16415                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16416
16417                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16418                 do_nodes $mdts $LCTL set_param mdd.*.$param
16419         done
16420
16421         # force cl_user2 to be idle (1st part), but also cancel the
16422         # cl_user1 records so that it is not evicted later in the test.
16423         local sleep1=$((idle_time / 2))
16424         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16425         sleep $sleep1
16426
16427         # simulate changelog catalog almost full
16428         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16429         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16430
16431         for i in $(seq $MDSCOUNT); do
16432                 cl_users=(${CL_USERS[mds$i]})
16433                 cl_user1[mds$i]="${cl_users[0]}"
16434                 cl_user2[mds$i]="${cl_users[1]}"
16435
16436                 [ -n "${cl_user1[mds$i]}" ] ||
16437                         error "mds$i: no user registered"
16438                 [ -n "${cl_user2[mds$i]}" ] ||
16439                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16440
16441                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16442                 [ -n "$user_rec1" ] ||
16443                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16444                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16445                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16446                 [ -n "$user_rec2" ] ||
16447                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16448                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16449                      "$user_rec1 + 2 == $user_rec2"
16450                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16451                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16452                               "$user_rec1 + 2, but is $user_rec2"
16453                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16454                 [ -n "$user_rec2" ] ||
16455                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16456                 [ $user_rec1 == $user_rec2 ] ||
16457                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16458                               "$user_rec1, but is $user_rec2"
16459         done
16460
16461         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16462         local sleep2=$((idle_time - (SECONDS - start) + 1))
16463         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16464         sleep $sleep2
16465
16466         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16467         # cl_user1 should be OK because it recently processed records.
16468         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16469         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16470                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16471                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16472         done
16473
16474         # ensure gc thread is done
16475         for i in $(mdts_nodes); do
16476                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16477                         error "$i: GC-thread not done"
16478         done
16479
16480         local first_rec
16481         for (( i = 1; i <= MDSCOUNT; i++ )); do
16482                 # check cl_user1 still registered
16483                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16484                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16485                 # check cl_user2 unregistered
16486                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16487                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16488
16489                 # check changelogs are present and starting at $user_rec1 + 1
16490                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16491                 [ -n "$user_rec1" ] ||
16492                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16493                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16494                             awk '{ print $1; exit; }')
16495
16496                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16497                 [ $((user_rec1 + 1)) == $first_rec ] ||
16498                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16499         done
16500 }
16501 run_test 160f "changelog garbage collect (timestamped users)"
16502
16503 test_160g() {
16504         remote_mds_nodsh && skip "remote MDS with nodsh"
16505         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16506                 skip "Need MDS version at least 2.14.55"
16507
16508         local mdts=$(comma_list $(mdts_nodes))
16509
16510         # Create a user
16511         changelog_register || error "first changelog_register failed"
16512         changelog_register || error "second changelog_register failed"
16513         local cl_users
16514         declare -A cl_user1
16515         declare -A cl_user2
16516         local user_rec1
16517         local user_rec2
16518         local i
16519
16520         # generate some changelog records to accumulate on each MDT
16521         # use all_char because created files should be evenly distributed
16522         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16523                 error "test_mkdir $tdir failed"
16524         for ((i = 0; i < MDSCOUNT; i++)); do
16525                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16526                         error "create $DIR/$tdir/d$i.1 failed"
16527         done
16528
16529         # check changelogs have been generated
16530         local nbcl=$(changelog_dump | wc -l)
16531         (( $nbcl > 0 )) || error "no changelogs found"
16532
16533         # reduce the max_idle_indexes value to make sure we exceed it
16534         for param in "changelog_max_idle_indexes=2" \
16535                      "changelog_gc=1" \
16536                      "changelog_min_gc_interval=2"; do
16537                 local MDT0=$(facet_svc $SINGLEMDS)
16538                 local var="${param%=*}"
16539                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16540
16541                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16542                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16543                         error "unable to set mdd.*.$param"
16544         done
16545
16546         local start=$SECONDS
16547         for i in $(seq $MDSCOUNT); do
16548                 cl_users=(${CL_USERS[mds$i]})
16549                 cl_user1[mds$i]="${cl_users[0]}"
16550                 cl_user2[mds$i]="${cl_users[1]}"
16551
16552                 [ -n "${cl_user1[mds$i]}" ] ||
16553                         error "mds$i: user1 is not registered"
16554                 [ -n "${cl_user2[mds$i]}" ] ||
16555                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16556
16557                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16558                 [ -n "$user_rec1" ] ||
16559                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16560                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16561                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16562                 [ -n "$user_rec2" ] ||
16563                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16564                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16565                      "$user_rec1 + 2 == $user_rec2"
16566                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16567                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16568                               "expected $user_rec1 + 2, but is $user_rec2"
16569                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16570                 [ -n "$user_rec2" ] ||
16571                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16572                 [ $user_rec1 == $user_rec2 ] ||
16573                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16574                               "expected $user_rec1, but is $user_rec2"
16575         done
16576
16577         # ensure we are past the previous changelog_min_gc_interval set above
16578         local sleep2=$((start + 2 - SECONDS))
16579         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16580         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16581         # cl_user1 should be OK because it recently processed records.
16582         for ((i = 0; i < MDSCOUNT; i++)); do
16583                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16584                         error "create $DIR/$tdir/d$i.3 failed"
16585         done
16586
16587         # ensure gc thread is done
16588         for i in $(mdts_nodes); do
16589                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16590                         error "$i: GC-thread not done"
16591         done
16592
16593         local first_rec
16594         for (( i = 1; i <= MDSCOUNT; i++ )); do
16595                 # check cl_user1 still registered
16596                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16597                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16598                 # check cl_user2 unregistered
16599                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16600                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16601
16602                 # check changelogs are present and starting at $user_rec1 + 1
16603                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16604                 [ -n "$user_rec1" ] ||
16605                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16606                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16607                             awk '{ print $1; exit; }')
16608
16609                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16610                 [ $((user_rec1 + 1)) == $first_rec ] ||
16611                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16612         done
16613 }
16614 run_test 160g "changelog garbage collect on idle records"
16615
16616 test_160h() {
16617         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16618         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16619                 skip "Need MDS version at least 2.10.56"
16620
16621         local mdts=$(comma_list $(mdts_nodes))
16622
16623         # Create a user
16624         changelog_register || error "first changelog_register failed"
16625         changelog_register || error "second changelog_register failed"
16626         local cl_users
16627         declare -A cl_user1
16628         declare -A cl_user2
16629         local user_rec1
16630         local user_rec2
16631         local i
16632
16633         # generate some changelog records to accumulate on each MDT
16634         # use all_char because created files should be evenly distributed
16635         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16636                 error "test_mkdir $tdir failed"
16637         for ((i = 0; i < MDSCOUNT; i++)); do
16638                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16639                         error "create $DIR/$tdir/d$i.1 failed"
16640         done
16641
16642         # check changelogs have been generated
16643         local nbcl=$(changelog_dump | wc -l)
16644         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16645
16646         for param in "changelog_max_idle_time=10" \
16647                      "changelog_gc=1" \
16648                      "changelog_min_gc_interval=2"; do
16649                 local MDT0=$(facet_svc $SINGLEMDS)
16650                 local var="${param%=*}"
16651                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16652
16653                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16654                 do_nodes $mdts $LCTL set_param mdd.*.$param
16655         done
16656
16657         # force cl_user2 to be idle (1st part)
16658         sleep 9
16659
16660         for i in $(seq $MDSCOUNT); do
16661                 cl_users=(${CL_USERS[mds$i]})
16662                 cl_user1[mds$i]="${cl_users[0]}"
16663                 cl_user2[mds$i]="${cl_users[1]}"
16664
16665                 [ -n "${cl_user1[mds$i]}" ] ||
16666                         error "mds$i: no user registered"
16667                 [ -n "${cl_user2[mds$i]}" ] ||
16668                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16669
16670                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16671                 [ -n "$user_rec1" ] ||
16672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16673                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16674                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16675                 [ -n "$user_rec2" ] ||
16676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16677                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16678                      "$user_rec1 + 2 == $user_rec2"
16679                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16680                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16681                               "$user_rec1 + 2, but is $user_rec2"
16682                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16683                 [ -n "$user_rec2" ] ||
16684                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16685                 [ $user_rec1 == $user_rec2 ] ||
16686                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16687                               "$user_rec1, but is $user_rec2"
16688         done
16689
16690         # force cl_user2 to be idle (2nd part) and to reach
16691         # changelog_max_idle_time
16692         sleep 2
16693
16694         # force each GC-thread start and block then
16695         # one per MDT/MDD, set fail_val accordingly
16696         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16697         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16698
16699         # generate more changelogs to trigger fail_loc
16700         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16701                 error "create $DIR/$tdir/${tfile}bis failed"
16702
16703         # stop MDT to stop GC-thread, should be done in back-ground as it will
16704         # block waiting for the thread to be released and exit
16705         declare -A stop_pids
16706         for i in $(seq $MDSCOUNT); do
16707                 stop mds$i &
16708                 stop_pids[mds$i]=$!
16709         done
16710
16711         for i in $(mdts_nodes); do
16712                 local facet
16713                 local nb=0
16714                 local facets=$(facets_up_on_host $i)
16715
16716                 for facet in ${facets//,/ }; do
16717                         if [[ $facet == mds* ]]; then
16718                                 nb=$((nb + 1))
16719                         fi
16720                 done
16721                 # ensure each MDS's gc threads are still present and all in "R"
16722                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16723                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16724                         error "$i: expected $nb GC-thread"
16725                 wait_update $i \
16726                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16727                         "R" 20 ||
16728                         error "$i: GC-thread not found in R-state"
16729                 # check umounts of each MDT on MDS have reached kthread_stop()
16730                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16731                         error "$i: expected $nb umount"
16732                 wait_update $i \
16733                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16734                         error "$i: umount not found in D-state"
16735         done
16736
16737         # release all GC-threads
16738         do_nodes $mdts $LCTL set_param fail_loc=0
16739
16740         # wait for MDT stop to complete
16741         for i in $(seq $MDSCOUNT); do
16742                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16743         done
16744
16745         # XXX
16746         # may try to check if any orphan changelog records are present
16747         # via ldiskfs/zfs and llog_reader...
16748
16749         # re-start/mount MDTs
16750         for i in $(seq $MDSCOUNT); do
16751                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16752                         error "Fail to start mds$i"
16753         done
16754
16755         local first_rec
16756         for i in $(seq $MDSCOUNT); do
16757                 # check cl_user1 still registered
16758                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16759                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16760                 # check cl_user2 unregistered
16761                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16762                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16763
16764                 # check changelogs are present and starting at $user_rec1 + 1
16765                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16766                 [ -n "$user_rec1" ] ||
16767                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16768                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16769                             awk '{ print $1; exit; }')
16770
16771                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16772                 [ $((user_rec1 + 1)) == $first_rec ] ||
16773                         error "mds$i: first index should be $user_rec1 + 1, " \
16774                               "but is $first_rec"
16775         done
16776 }
16777 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16778               "during mount"
16779
16780 test_160i() {
16781
16782         local mdts=$(comma_list $(mdts_nodes))
16783
16784         changelog_register || error "first changelog_register failed"
16785
16786         # generate some changelog records to accumulate on each MDT
16787         # use all_char because created files should be evenly distributed
16788         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16789                 error "test_mkdir $tdir failed"
16790         for ((i = 0; i < MDSCOUNT; i++)); do
16791                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16792                         error "create $DIR/$tdir/d$i.1 failed"
16793         done
16794
16795         # check changelogs have been generated
16796         local nbcl=$(changelog_dump | wc -l)
16797         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16798
16799         # simulate race between register and unregister
16800         # XXX as fail_loc is set per-MDS, with DNE configs the race
16801         # simulation will only occur for one MDT per MDS and for the
16802         # others the normal race scenario will take place
16803         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16804         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16805         do_nodes $mdts $LCTL set_param fail_val=1
16806
16807         # unregister 1st user
16808         changelog_deregister &
16809         local pid1=$!
16810         # wait some time for deregister work to reach race rdv
16811         sleep 2
16812         # register 2nd user
16813         changelog_register || error "2nd user register failed"
16814
16815         wait $pid1 || error "1st user deregister failed"
16816
16817         local i
16818         local last_rec
16819         declare -A LAST_REC
16820         for i in $(seq $MDSCOUNT); do
16821                 if changelog_users mds$i | grep "^cl"; then
16822                         # make sure new records are added with one user present
16823                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16824                                           awk '/^current.index:/ { print $NF }')
16825                 else
16826                         error "mds$i has no user registered"
16827                 fi
16828         done
16829
16830         # generate more changelog records to accumulate on each MDT
16831         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16832                 error "create $DIR/$tdir/${tfile}bis failed"
16833
16834         for i in $(seq $MDSCOUNT); do
16835                 last_rec=$(changelog_users $SINGLEMDS |
16836                            awk '/^current.index:/ { print $NF }')
16837                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16838                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16839                         error "changelogs are off on mds$i"
16840         done
16841 }
16842 run_test 160i "changelog user register/unregister race"
16843
16844 test_160j() {
16845         remote_mds_nodsh && skip "remote MDS with nodsh"
16846         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16847                 skip "Need MDS version at least 2.12.56"
16848
16849         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16850         stack_trap "umount $MOUNT2" EXIT
16851
16852         changelog_register || error "first changelog_register failed"
16853         stack_trap "changelog_deregister" EXIT
16854
16855         # generate some changelog
16856         # use all_char because created files should be evenly distributed
16857         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16858                 error "mkdir $tdir failed"
16859         for ((i = 0; i < MDSCOUNT; i++)); do
16860                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16861                         error "create $DIR/$tdir/d$i.1 failed"
16862         done
16863
16864         # open the changelog device
16865         exec 3>/dev/changelog-$FSNAME-MDT0000
16866         stack_trap "exec 3>&-" EXIT
16867         exec 4</dev/changelog-$FSNAME-MDT0000
16868         stack_trap "exec 4<&-" EXIT
16869
16870         # umount the first lustre mount
16871         umount $MOUNT
16872         stack_trap "mount_client $MOUNT" EXIT
16873
16874         # read changelog, which may or may not fail, but should not crash
16875         cat <&4 >/dev/null
16876
16877         # clear changelog
16878         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16879         changelog_users $SINGLEMDS | grep -q $cl_user ||
16880                 error "User $cl_user not found in changelog_users"
16881
16882         printf 'clear:'$cl_user':0' >&3
16883 }
16884 run_test 160j "client can be umounted while its chanangelog is being used"
16885
16886 test_160k() {
16887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16888         remote_mds_nodsh && skip "remote MDS with nodsh"
16889
16890         mkdir -p $DIR/$tdir/1/1
16891
16892         changelog_register || error "changelog_register failed"
16893         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16894
16895         changelog_users $SINGLEMDS | grep -q $cl_user ||
16896                 error "User '$cl_user' not found in changelog_users"
16897 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16898         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16899         rmdir $DIR/$tdir/1/1 & sleep 1
16900         mkdir $DIR/$tdir/2
16901         touch $DIR/$tdir/2/2
16902         rm -rf $DIR/$tdir/2
16903
16904         wait
16905         sleep 4
16906
16907         changelog_dump | grep rmdir || error "rmdir not recorded"
16908 }
16909 run_test 160k "Verify that changelog records are not lost"
16910
16911 # Verifies that a file passed as a parameter has recently had an operation
16912 # performed on it that has generated an MTIME changelog which contains the
16913 # correct parent FID. As files might reside on a different MDT from the
16914 # parent directory in DNE configurations, the FIDs are translated to paths
16915 # before being compared, which should be identical
16916 compare_mtime_changelog() {
16917         local file="${1}"
16918         local mdtidx
16919         local mtime
16920         local cl_fid
16921         local pdir
16922         local dir
16923
16924         mdtidx=$($LFS getstripe --mdt-index $file)
16925         mdtidx=$(printf "%04x" $mdtidx)
16926
16927         # Obtain the parent FID from the MTIME changelog
16928         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16929         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16930
16931         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16932         [ -z "$cl_fid" ] && error "parent FID not present"
16933
16934         # Verify that the path for the parent FID is the same as the path for
16935         # the test directory
16936         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16937
16938         dir=$(dirname $1)
16939
16940         [[ "${pdir%/}" == "$dir" ]] ||
16941                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16942 }
16943
16944 test_160l() {
16945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16946
16947         remote_mds_nodsh && skip "remote MDS with nodsh"
16948         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16949                 skip "Need MDS version at least 2.13.55"
16950
16951         local cl_user
16952
16953         changelog_register || error "changelog_register failed"
16954         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16955
16956         changelog_users $SINGLEMDS | grep -q $cl_user ||
16957                 error "User '$cl_user' not found in changelog_users"
16958
16959         # Clear some types so that MTIME changelogs are generated
16960         changelog_chmask "-CREAT"
16961         changelog_chmask "-CLOSE"
16962
16963         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16964
16965         # Test CL_MTIME during setattr
16966         touch $DIR/$tdir/$tfile
16967         compare_mtime_changelog $DIR/$tdir/$tfile
16968
16969         # Test CL_MTIME during close
16970         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16971         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16972 }
16973 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16974
16975 test_160m() {
16976         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16977         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16978                 skip "Need MDS version at least 2.14.51"
16979         local cl_users
16980         local cl_user1
16981         local cl_user2
16982         local pid1
16983
16984         # Create a user
16985         changelog_register || error "first changelog_register failed"
16986         changelog_register || error "second changelog_register failed"
16987
16988         cl_users=(${CL_USERS[mds1]})
16989         cl_user1="${cl_users[0]}"
16990         cl_user2="${cl_users[1]}"
16991         # generate some changelog records to accumulate on MDT0
16992         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16993         createmany -m $DIR/$tdir/$tfile 50 ||
16994                 error "create $DIR/$tdir/$tfile failed"
16995         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16996         rm -f $DIR/$tdir
16997
16998         # check changelogs have been generated
16999         local nbcl=$(changelog_dump | wc -l)
17000         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17001
17002 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17003         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17004
17005         __changelog_clear mds1 $cl_user1 +10
17006         __changelog_clear mds1 $cl_user2 0 &
17007         pid1=$!
17008         sleep 2
17009         __changelog_clear mds1 $cl_user1 0 ||
17010                 error "fail to cancel record for $cl_user1"
17011         wait $pid1
17012         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17013 }
17014 run_test 160m "Changelog clear race"
17015
17016 test_160n() {
17017         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17018         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17019                 skip "Need MDS version at least 2.14.51"
17020         local cl_users
17021         local cl_user1
17022         local cl_user2
17023         local pid1
17024         local first_rec
17025         local last_rec=0
17026
17027         # Create a user
17028         changelog_register || error "first changelog_register failed"
17029
17030         cl_users=(${CL_USERS[mds1]})
17031         cl_user1="${cl_users[0]}"
17032
17033         # generate some changelog records to accumulate on MDT0
17034         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17035         first_rec=$(changelog_users $SINGLEMDS |
17036                         awk '/^current.index:/ { print $NF }')
17037         while (( last_rec < (( first_rec + 65000)) )); do
17038                 createmany -m $DIR/$tdir/$tfile 10000 ||
17039                         error "create $DIR/$tdir/$tfile failed"
17040
17041                 for i in $(seq 0 10000); do
17042                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17043                                 > /dev/null
17044                 done
17045
17046                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17047                         error "unlinkmany failed unlink"
17048                 last_rec=$(changelog_users $SINGLEMDS |
17049                         awk '/^current.index:/ { print $NF }')
17050                 echo last record $last_rec
17051                 (( last_rec == 0 )) && error "no changelog found"
17052         done
17053
17054 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17055         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17056
17057         __changelog_clear mds1 $cl_user1 0 &
17058         pid1=$!
17059         sleep 2
17060         __changelog_clear mds1 $cl_user1 0 ||
17061                 error "fail to cancel record for $cl_user1"
17062         wait $pid1
17063         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17064 }
17065 run_test 160n "Changelog destroy race"
17066
17067 test_160o() {
17068         local mdt="$(facet_svc $SINGLEMDS)"
17069
17070         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17071         remote_mds_nodsh && skip "remote MDS with nodsh"
17072         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17073                 skip "Need MDS version at least 2.14.52"
17074
17075         changelog_register --user test_160o -m unlnk+close+open ||
17076                 error "changelog_register failed"
17077
17078         do_facet $SINGLEMDS $LCTL --device $mdt \
17079                                 changelog_register -u "Tt3_-#" &&
17080                 error "bad symbols in name should fail"
17081
17082         do_facet $SINGLEMDS $LCTL --device $mdt \
17083                                 changelog_register -u test_160o &&
17084                 error "the same name registration should fail"
17085
17086         do_facet $SINGLEMDS $LCTL --device $mdt \
17087                         changelog_register -u test_160toolongname &&
17088                 error "too long name registration should fail"
17089
17090         changelog_chmask "MARK+HSM"
17091         lctl get_param mdd.*.changelog*mask
17092         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17093         changelog_users $SINGLEMDS | grep -q $cl_user ||
17094                 error "User $cl_user not found in changelog_users"
17095         #verify username
17096         echo $cl_user | grep -q test_160o ||
17097                 error "User $cl_user has no specific name 'test160o'"
17098
17099         # change something
17100         changelog_clear 0 || error "changelog_clear failed"
17101         # generate some changelog records to accumulate on MDT0
17102         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17103         touch $DIR/$tdir/$tfile                 # open 1
17104
17105         OPENS=$(changelog_dump | grep -c "OPEN")
17106         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17107
17108         # must be no MKDIR it wasn't set as user mask
17109         MKDIR=$(changelog_dump | grep -c "MKDIR")
17110         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17111
17112         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17113                                 mdd.$mdt.changelog_current_mask -n)
17114         # register maskless user
17115         changelog_register || error "changelog_register failed"
17116         # effective mask should be not changed because it is not minimal
17117         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17118                                 mdd.$mdt.changelog_current_mask -n)
17119         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17120         # set server mask to minimal value
17121         changelog_chmask "MARK"
17122         # check effective mask again, should be treated as DEFMASK now
17123         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17124                                 mdd.$mdt.changelog_current_mask -n)
17125         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17126
17127         do_facet $SINGLEMDS $LCTL --device $mdt \
17128                                 changelog_deregister -u test_160o ||
17129                 error "cannot deregister by name"
17130 }
17131 run_test 160o "changelog user name and mask"
17132
17133 test_160p() {
17134         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17135         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17136                 skip "Need MDS version at least 2.14.51"
17137         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17138         local cl_users
17139         local cl_user1
17140         local entry_count
17141
17142         # Create a user
17143         changelog_register || error "first changelog_register failed"
17144
17145         cl_users=(${CL_USERS[mds1]})
17146         cl_user1="${cl_users[0]}"
17147
17148         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17149         createmany -m $DIR/$tdir/$tfile 50 ||
17150                 error "create $DIR/$tdir/$tfile failed"
17151         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17152         rm -rf $DIR/$tdir
17153
17154         # check changelogs have been generated
17155         entry_count=$(changelog_dump | wc -l)
17156         ((entry_count != 0)) || error "no changelog entries found"
17157
17158         # remove changelog_users and check that orphan entries are removed
17159         stop mds1
17160         local dev=$(mdsdevname 1)
17161         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17162         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17163         entry_count=$(changelog_dump | wc -l)
17164         ((entry_count == 0)) ||
17165                 error "found $entry_count changelog entries, expected none"
17166 }
17167 run_test 160p "Changelog orphan cleanup with no users"
17168
17169 test_160q() {
17170         local mdt="$(facet_svc $SINGLEMDS)"
17171         local clu
17172
17173         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17174         remote_mds_nodsh && skip "remote MDS with nodsh"
17175         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17176                 skip "Need MDS version at least 2.14.54"
17177
17178         # set server mask to minimal value like server init does
17179         changelog_chmask "MARK"
17180         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17181                 error "changelog_register failed"
17182         # check effective mask again, should be treated as DEFMASK now
17183         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17184                                 mdd.$mdt.changelog_current_mask -n)
17185         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17186                 error "changelog_deregister failed"
17187         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17188 }
17189 run_test 160q "changelog effective mask is DEFMASK if not set"
17190
17191 test_160s() {
17192         remote_mds_nodsh && skip "remote MDS with nodsh"
17193         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17194                 skip "Need MDS version at least 2.14.55"
17195
17196         local mdts=$(comma_list $(mdts_nodes))
17197
17198         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17199         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17200                                        fail_val=$((24 * 3600 * 10))
17201
17202         # Create a user which is 10 days old
17203         changelog_register || error "first changelog_register failed"
17204         local cl_users
17205         declare -A cl_user1
17206         local i
17207
17208         # generate some changelog records to accumulate on each MDT
17209         # use all_char because created files should be evenly distributed
17210         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17211                 error "test_mkdir $tdir failed"
17212         for ((i = 0; i < MDSCOUNT; i++)); do
17213                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17214                         error "create $DIR/$tdir/d$i.1 failed"
17215         done
17216
17217         # check changelogs have been generated
17218         local nbcl=$(changelog_dump | wc -l)
17219         (( nbcl > 0 )) || error "no changelogs found"
17220
17221         # reduce the max_idle_indexes value to make sure we exceed it
17222         for param in "changelog_max_idle_indexes=2097446912" \
17223                      "changelog_max_idle_time=2592000" \
17224                      "changelog_gc=1" \
17225                      "changelog_min_gc_interval=2"; do
17226                 local MDT0=$(facet_svc $SINGLEMDS)
17227                 local var="${param%=*}"
17228                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17229
17230                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17231                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17232                         error "unable to set mdd.*.$param"
17233         done
17234
17235         local start=$SECONDS
17236         for i in $(seq $MDSCOUNT); do
17237                 cl_users=(${CL_USERS[mds$i]})
17238                 cl_user1[mds$i]="${cl_users[0]}"
17239
17240                 [[ -n "${cl_user1[mds$i]}" ]] ||
17241                         error "mds$i: no user registered"
17242         done
17243
17244         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17245         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17246
17247         # ensure we are past the previous changelog_min_gc_interval set above
17248         local sleep2=$((start + 2 - SECONDS))
17249         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17250
17251         # Generate one more changelog to trigger GC
17252         for ((i = 0; i < MDSCOUNT; i++)); do
17253                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17254                         error "create $DIR/$tdir/d$i.3 failed"
17255         done
17256
17257         # ensure gc thread is done
17258         for node in $(mdts_nodes); do
17259                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17260                         error "$node: GC-thread not done"
17261         done
17262
17263         do_nodes $mdts $LCTL set_param fail_loc=0
17264
17265         for (( i = 1; i <= MDSCOUNT; i++ )); do
17266                 # check cl_user1 is purged
17267                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17268                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17269         done
17270         return 0
17271 }
17272 run_test 160s "changelog garbage collect on idle records * time"
17273
17274 test_160t() {
17275         remote_mds_nodsh && skip "remote MDS with nodsh"
17276         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17277                 skip "Need MDS version at least 2.15.50"
17278
17279         local MDT0=$(facet_svc $SINGLEMDS)
17280         local cl_users
17281         local cl_user1
17282         local cl_user2
17283         local start
17284
17285         changelog_register --user user1 -m all ||
17286                 error "user1 failed to register"
17287
17288         mkdir_on_mdt0 $DIR/$tdir
17289         # create default overstripe to maximize changelog size
17290         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17291         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17292         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17293
17294         # user2 consumes less records so less space
17295         changelog_register --user user2 || error "user2 failed to register"
17296         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17297         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17298
17299         # check changelogs have been generated
17300         local nbcl=$(changelog_dump | wc -l)
17301         (( nbcl > 0 )) || error "no changelogs found"
17302
17303         # reduce the changelog_min_gc_interval to force check
17304         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17305                 local var="${param%=*}"
17306                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17307
17308                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17309                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17310                         error "unable to set mdd.*.$param"
17311         done
17312
17313         start=$SECONDS
17314         cl_users=(${CL_USERS[mds1]})
17315         cl_user1="${cl_users[0]}"
17316         cl_user2="${cl_users[1]}"
17317
17318         [[ -n $cl_user1 ]] ||
17319                 error "mds1: user #1 isn't registered"
17320         [[ -n $cl_user2 ]] ||
17321                 error "mds1: user #2 isn't registered"
17322
17323         # ensure we are past the previous changelog_min_gc_interval set above
17324         local sleep2=$((start + 2 - SECONDS))
17325         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17326
17327         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17328         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17329                         fail_val=$(((llog_size1 + llog_size2) / 2))
17330
17331         # Generate more changelog to trigger GC
17332         createmany -o $DIR/$tdir/u3_ 4 ||
17333                 error "create failed for more files"
17334
17335         # ensure gc thread is done
17336         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17337                 error "mds1: GC-thread not done"
17338
17339         do_facet mds1 $LCTL set_param fail_loc=0
17340
17341         # check cl_user1 is purged
17342         changelog_users mds1 | grep -q "$cl_user1" &&
17343                 error "User $cl_user1 is registered"
17344         # check cl_user2 is not purged
17345         changelog_users mds1 | grep -q "$cl_user2" ||
17346                 error "User $cl_user2 is not registered"
17347 }
17348 run_test 160t "changelog garbage collect on lack of space"
17349
17350 test_161a() {
17351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17352
17353         test_mkdir -c1 $DIR/$tdir
17354         cp /etc/hosts $DIR/$tdir/$tfile
17355         test_mkdir -c1 $DIR/$tdir/foo1
17356         test_mkdir -c1 $DIR/$tdir/foo2
17357         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17358         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17359         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17360         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17361         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17362         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17363                 $LFS fid2path $DIR $FID
17364                 error "bad link ea"
17365         fi
17366         # middle
17367         rm $DIR/$tdir/foo2/zachary
17368         # last
17369         rm $DIR/$tdir/foo2/thor
17370         # first
17371         rm $DIR/$tdir/$tfile
17372         # rename
17373         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17374         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17375                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17376         rm $DIR/$tdir/foo2/maggie
17377
17378         # overflow the EA
17379         local longname=$tfile.avg_len_is_thirty_two_
17380         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17381                 error_noexit 'failed to unlink many hardlinks'" EXIT
17382         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17383                 error "failed to hardlink many files"
17384         links=$($LFS fid2path $DIR $FID | wc -l)
17385         echo -n "${links}/1000 links in link EA"
17386         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17387 }
17388 run_test 161a "link ea sanity"
17389
17390 test_161b() {
17391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17392         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17393
17394         local MDTIDX=1
17395         local remote_dir=$DIR/$tdir/remote_dir
17396
17397         mkdir -p $DIR/$tdir
17398         $LFS mkdir -i $MDTIDX $remote_dir ||
17399                 error "create remote directory failed"
17400
17401         cp /etc/hosts $remote_dir/$tfile
17402         mkdir -p $remote_dir/foo1
17403         mkdir -p $remote_dir/foo2
17404         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17405         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17406         ln $remote_dir/$tfile $remote_dir/foo1/luna
17407         ln $remote_dir/$tfile $remote_dir/foo2/thor
17408
17409         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17410                      tr -d ']')
17411         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17412                 $LFS fid2path $DIR $FID
17413                 error "bad link ea"
17414         fi
17415         # middle
17416         rm $remote_dir/foo2/zachary
17417         # last
17418         rm $remote_dir/foo2/thor
17419         # first
17420         rm $remote_dir/$tfile
17421         # rename
17422         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17423         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17424         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17425                 $LFS fid2path $DIR $FID
17426                 error "bad link rename"
17427         fi
17428         rm $remote_dir/foo2/maggie
17429
17430         # overflow the EA
17431         local longname=filename_avg_len_is_thirty_two_
17432         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17433                 error "failed to hardlink many files"
17434         links=$($LFS fid2path $DIR $FID | wc -l)
17435         echo -n "${links}/1000 links in link EA"
17436         [[ ${links} -gt 60 ]] ||
17437                 error "expected at least 60 links in link EA"
17438         unlinkmany $remote_dir/foo2/$longname 1000 ||
17439         error "failed to unlink many hardlinks"
17440 }
17441 run_test 161b "link ea sanity under remote directory"
17442
17443 test_161c() {
17444         remote_mds_nodsh && skip "remote MDS with nodsh"
17445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17446         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17447                 skip "Need MDS version at least 2.1.5"
17448
17449         # define CLF_RENAME_LAST 0x0001
17450         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17451         changelog_register || error "changelog_register failed"
17452
17453         rm -rf $DIR/$tdir
17454         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17455         touch $DIR/$tdir/foo_161c
17456         touch $DIR/$tdir/bar_161c
17457         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17458         changelog_dump | grep RENME | tail -n 5
17459         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17460         changelog_clear 0 || error "changelog_clear failed"
17461         if [ x$flags != "x0x1" ]; then
17462                 error "flag $flags is not 0x1"
17463         fi
17464
17465         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17466         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17467         touch $DIR/$tdir/foo_161c
17468         touch $DIR/$tdir/bar_161c
17469         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17470         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17471         changelog_dump | grep RENME | tail -n 5
17472         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17473         changelog_clear 0 || error "changelog_clear failed"
17474         if [ x$flags != "x0x0" ]; then
17475                 error "flag $flags is not 0x0"
17476         fi
17477         echo "rename overwrite a target having nlink > 1," \
17478                 "changelog record has flags of $flags"
17479
17480         # rename doesn't overwrite a target (changelog flag 0x0)
17481         touch $DIR/$tdir/foo_161c
17482         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17483         changelog_dump | grep RENME | tail -n 5
17484         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17485         changelog_clear 0 || error "changelog_clear failed"
17486         if [ x$flags != "x0x0" ]; then
17487                 error "flag $flags is not 0x0"
17488         fi
17489         echo "rename doesn't overwrite a target," \
17490                 "changelog record has flags of $flags"
17491
17492         # define CLF_UNLINK_LAST 0x0001
17493         # unlink a file having nlink = 1 (changelog flag 0x1)
17494         rm -f $DIR/$tdir/foo2_161c
17495         changelog_dump | grep UNLNK | tail -n 5
17496         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17497         changelog_clear 0 || error "changelog_clear failed"
17498         if [ x$flags != "x0x1" ]; then
17499                 error "flag $flags is not 0x1"
17500         fi
17501         echo "unlink a file having nlink = 1," \
17502                 "changelog record has flags of $flags"
17503
17504         # unlink a file having nlink > 1 (changelog flag 0x0)
17505         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17506         rm -f $DIR/$tdir/foobar_161c
17507         changelog_dump | grep UNLNK | tail -n 5
17508         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17509         changelog_clear 0 || error "changelog_clear failed"
17510         if [ x$flags != "x0x0" ]; then
17511                 error "flag $flags is not 0x0"
17512         fi
17513         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17514 }
17515 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17516
17517 test_161d() {
17518         remote_mds_nodsh && skip "remote MDS with nodsh"
17519         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17520
17521         local pid
17522         local fid
17523
17524         changelog_register || error "changelog_register failed"
17525
17526         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17527         # interfer with $MOUNT/.lustre/fid/ access
17528         mkdir $DIR/$tdir
17529         [[ $? -eq 0 ]] || error "mkdir failed"
17530
17531         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17532         $LCTL set_param fail_loc=0x8000140c
17533         # 5s pause
17534         $LCTL set_param fail_val=5
17535
17536         # create file
17537         echo foofoo > $DIR/$tdir/$tfile &
17538         pid=$!
17539
17540         # wait for create to be delayed
17541         sleep 2
17542
17543         ps -p $pid
17544         [[ $? -eq 0 ]] || error "create should be blocked"
17545
17546         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17547         stack_trap "rm -f $tempfile"
17548         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17549         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17550         # some delay may occur during ChangeLog publishing and file read just
17551         # above, that could allow file write to happen finally
17552         [[ -s $tempfile ]] && echo "file should be empty"
17553
17554         $LCTL set_param fail_loc=0
17555
17556         wait $pid
17557         [[ $? -eq 0 ]] || error "create failed"
17558 }
17559 run_test 161d "create with concurrent .lustre/fid access"
17560
17561 check_path() {
17562         local expected="$1"
17563         shift
17564         local fid="$2"
17565
17566         local path
17567         path=$($LFS fid2path "$@")
17568         local rc=$?
17569
17570         if [ $rc -ne 0 ]; then
17571                 error "path looked up of '$expected' failed: rc=$rc"
17572         elif [ "$path" != "$expected" ]; then
17573                 error "path looked up '$path' instead of '$expected'"
17574         else
17575                 echo "FID '$fid' resolves to path '$path' as expected"
17576         fi
17577 }
17578
17579 test_162a() { # was test_162
17580         test_mkdir -p -c1 $DIR/$tdir/d2
17581         touch $DIR/$tdir/d2/$tfile
17582         touch $DIR/$tdir/d2/x1
17583         touch $DIR/$tdir/d2/x2
17584         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17585         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17586         # regular file
17587         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17588         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17589
17590         # softlink
17591         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17592         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17593         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17594
17595         # softlink to wrong file
17596         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17597         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17598         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17599
17600         # hardlink
17601         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17602         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17603         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17604         # fid2path dir/fsname should both work
17605         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17606         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17607
17608         # hardlink count: check that there are 2 links
17609         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17610         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17611
17612         # hardlink indexing: remove the first link
17613         rm $DIR/$tdir/d2/p/q/r/hlink
17614         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17615 }
17616 run_test 162a "path lookup sanity"
17617
17618 test_162b() {
17619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17621
17622         mkdir $DIR/$tdir
17623         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17624                                 error "create striped dir failed"
17625
17626         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17627                                         tail -n 1 | awk '{print $2}')
17628         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17629
17630         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17631         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17632
17633         # regular file
17634         for ((i=0;i<5;i++)); do
17635                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17636                         error "get fid for f$i failed"
17637                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17638
17639                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17640                         error "get fid for d$i failed"
17641                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17642         done
17643
17644         return 0
17645 }
17646 run_test 162b "striped directory path lookup sanity"
17647
17648 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17649 test_162c() {
17650         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17651                 skip "Need MDS version at least 2.7.51"
17652
17653         local lpath=$tdir.local
17654         local rpath=$tdir.remote
17655
17656         test_mkdir $DIR/$lpath
17657         test_mkdir $DIR/$rpath
17658
17659         for ((i = 0; i <= 101; i++)); do
17660                 lpath="$lpath/$i"
17661                 mkdir $DIR/$lpath
17662                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17663                         error "get fid for local directory $DIR/$lpath failed"
17664                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17665
17666                 rpath="$rpath/$i"
17667                 test_mkdir $DIR/$rpath
17668                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17669                         error "get fid for remote directory $DIR/$rpath failed"
17670                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17671         done
17672
17673         return 0
17674 }
17675 run_test 162c "fid2path works with paths 100 or more directories deep"
17676
17677 oalr_event_count() {
17678         local event="${1}"
17679         local trace="${2}"
17680
17681         awk -v name="${FSNAME}-OST0000" \
17682             -v event="${event}" \
17683             '$1 == "TRACE" && $2 == event && $3 == name' \
17684             "${trace}" |
17685         wc -l
17686 }
17687
17688 oalr_expect_event_count() {
17689         local event="${1}"
17690         local trace="${2}"
17691         local expect="${3}"
17692         local count
17693
17694         count=$(oalr_event_count "${event}" "${trace}")
17695         if ((count == expect)); then
17696                 return 0
17697         fi
17698
17699         error_noexit "${event} event count was '${count}', expected ${expect}"
17700         cat "${trace}" >&2
17701         exit 1
17702 }
17703
17704 cleanup_165() {
17705         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17706         stop ost1
17707         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17708 }
17709
17710 setup_165() {
17711         sync # Flush previous IOs so we can count log entries.
17712         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17713         stack_trap cleanup_165 EXIT
17714 }
17715
17716 test_165a() {
17717         local trace="/tmp/${tfile}.trace"
17718         local rc
17719         local count
17720
17721         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17722                 skip "OFD access log unsupported"
17723
17724         setup_165
17725         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17726         sleep 5
17727
17728         do_facet ost1 ofd_access_log_reader --list
17729         stop ost1
17730
17731         do_facet ost1 killall -TERM ofd_access_log_reader
17732         wait
17733         rc=$?
17734
17735         if ((rc != 0)); then
17736                 error "ofd_access_log_reader exited with rc = '${rc}'"
17737         fi
17738
17739         # Parse trace file for discovery events:
17740         oalr_expect_event_count alr_log_add "${trace}" 1
17741         oalr_expect_event_count alr_log_eof "${trace}" 1
17742         oalr_expect_event_count alr_log_free "${trace}" 1
17743 }
17744 run_test 165a "ofd access log discovery"
17745
17746 test_165b() {
17747         local trace="/tmp/${tfile}.trace"
17748         local file="${DIR}/${tfile}"
17749         local pfid1
17750         local pfid2
17751         local -a entry
17752         local rc
17753         local count
17754         local size
17755         local flags
17756
17757         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17758                 skip "OFD access log unsupported"
17759
17760         setup_165
17761         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17762         sleep 5
17763
17764         do_facet ost1 ofd_access_log_reader --list
17765
17766         lfs setstripe -c 1 -i 0 "${file}"
17767         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17768                 error "cannot create '${file}'"
17769
17770         sleep 5
17771         do_facet ost1 killall -TERM ofd_access_log_reader
17772         wait
17773         rc=$?
17774
17775         if ((rc != 0)); then
17776                 error "ofd_access_log_reader exited with rc = '${rc}'"
17777         fi
17778
17779         oalr_expect_event_count alr_log_entry "${trace}" 1
17780
17781         pfid1=$($LFS path2fid "${file}")
17782
17783         # 1     2             3   4    5     6   7    8    9     10
17784         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17785         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17786
17787         echo "entry = '${entry[*]}'" >&2
17788
17789         pfid2=${entry[4]}
17790         if [[ "${pfid1}" != "${pfid2}" ]]; then
17791                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17792         fi
17793
17794         size=${entry[8]}
17795         if ((size != 1048576)); then
17796                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17797         fi
17798
17799         flags=${entry[10]}
17800         if [[ "${flags}" != "w" ]]; then
17801                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17802         fi
17803
17804         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17805         sleep 5
17806
17807         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17808                 error "cannot read '${file}'"
17809         sleep 5
17810
17811         do_facet ost1 killall -TERM ofd_access_log_reader
17812         wait
17813         rc=$?
17814
17815         if ((rc != 0)); then
17816                 error "ofd_access_log_reader exited with rc = '${rc}'"
17817         fi
17818
17819         oalr_expect_event_count alr_log_entry "${trace}" 1
17820
17821         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17822         echo "entry = '${entry[*]}'" >&2
17823
17824         pfid2=${entry[4]}
17825         if [[ "${pfid1}" != "${pfid2}" ]]; then
17826                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17827         fi
17828
17829         size=${entry[8]}
17830         if ((size != 524288)); then
17831                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17832         fi
17833
17834         flags=${entry[10]}
17835         if [[ "${flags}" != "r" ]]; then
17836                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17837         fi
17838 }
17839 run_test 165b "ofd access log entries are produced and consumed"
17840
17841 test_165c() {
17842         local trace="/tmp/${tfile}.trace"
17843         local file="${DIR}/${tdir}/${tfile}"
17844
17845         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17846                 skip "OFD access log unsupported"
17847
17848         test_mkdir "${DIR}/${tdir}"
17849
17850         setup_165
17851         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17852         sleep 5
17853
17854         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17855
17856         # 4096 / 64 = 64. Create twice as many entries.
17857         for ((i = 0; i < 128; i++)); do
17858                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17859                         error "cannot create file"
17860         done
17861
17862         sync
17863
17864         do_facet ost1 killall -TERM ofd_access_log_reader
17865         wait
17866         rc=$?
17867         if ((rc != 0)); then
17868                 error "ofd_access_log_reader exited with rc = '${rc}'"
17869         fi
17870
17871         unlinkmany  "${file}-%d" 128
17872 }
17873 run_test 165c "full ofd access logs do not block IOs"
17874
17875 oal_get_read_count() {
17876         local stats="$1"
17877
17878         # STATS lustre-OST0001 alr_read_count 1
17879
17880         do_facet ost1 cat "${stats}" |
17881         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17882              END { print count; }'
17883 }
17884
17885 oal_expect_read_count() {
17886         local stats="$1"
17887         local count
17888         local expect="$2"
17889
17890         # Ask ofd_access_log_reader to write stats.
17891         do_facet ost1 killall -USR1 ofd_access_log_reader
17892
17893         # Allow some time for things to happen.
17894         sleep 1
17895
17896         count=$(oal_get_read_count "${stats}")
17897         if ((count == expect)); then
17898                 return 0
17899         fi
17900
17901         error_noexit "bad read count, got ${count}, expected ${expect}"
17902         do_facet ost1 cat "${stats}" >&2
17903         exit 1
17904 }
17905
17906 test_165d() {
17907         local stats="/tmp/${tfile}.stats"
17908         local file="${DIR}/${tdir}/${tfile}"
17909         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17910
17911         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17912                 skip "OFD access log unsupported"
17913
17914         test_mkdir "${DIR}/${tdir}"
17915
17916         setup_165
17917         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17918         sleep 5
17919
17920         lfs setstripe -c 1 -i 0 "${file}"
17921
17922         do_facet ost1 lctl set_param "${param}=rw"
17923         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17924                 error "cannot create '${file}'"
17925         oal_expect_read_count "${stats}" 1
17926
17927         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17928                 error "cannot read '${file}'"
17929         oal_expect_read_count "${stats}" 2
17930
17931         do_facet ost1 lctl set_param "${param}=r"
17932         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17933                 error "cannot create '${file}'"
17934         oal_expect_read_count "${stats}" 2
17935
17936         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17937                 error "cannot read '${file}'"
17938         oal_expect_read_count "${stats}" 3
17939
17940         do_facet ost1 lctl set_param "${param}=w"
17941         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17942                 error "cannot create '${file}'"
17943         oal_expect_read_count "${stats}" 4
17944
17945         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17946                 error "cannot read '${file}'"
17947         oal_expect_read_count "${stats}" 4
17948
17949         do_facet ost1 lctl set_param "${param}=0"
17950         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17951                 error "cannot create '${file}'"
17952         oal_expect_read_count "${stats}" 4
17953
17954         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17955                 error "cannot read '${file}'"
17956         oal_expect_read_count "${stats}" 4
17957
17958         do_facet ost1 killall -TERM ofd_access_log_reader
17959         wait
17960         rc=$?
17961         if ((rc != 0)); then
17962                 error "ofd_access_log_reader exited with rc = '${rc}'"
17963         fi
17964 }
17965 run_test 165d "ofd_access_log mask works"
17966
17967 test_165e() {
17968         local stats="/tmp/${tfile}.stats"
17969         local file0="${DIR}/${tdir}-0/${tfile}"
17970         local file1="${DIR}/${tdir}-1/${tfile}"
17971
17972         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17973                 skip "OFD access log unsupported"
17974
17975         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17976
17977         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17978         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17979
17980         lfs setstripe -c 1 -i 0 "${file0}"
17981         lfs setstripe -c 1 -i 0 "${file1}"
17982
17983         setup_165
17984         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17985         sleep 5
17986
17987         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17988                 error "cannot create '${file0}'"
17989         sync
17990         oal_expect_read_count "${stats}" 0
17991
17992         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17993                 error "cannot create '${file1}'"
17994         sync
17995         oal_expect_read_count "${stats}" 1
17996
17997         do_facet ost1 killall -TERM ofd_access_log_reader
17998         wait
17999         rc=$?
18000         if ((rc != 0)); then
18001                 error "ofd_access_log_reader exited with rc = '${rc}'"
18002         fi
18003 }
18004 run_test 165e "ofd_access_log MDT index filter works"
18005
18006 test_165f() {
18007         local trace="/tmp/${tfile}.trace"
18008         local rc
18009         local count
18010
18011         setup_165
18012         do_facet ost1 timeout 60 ofd_access_log_reader \
18013                 --exit-on-close --debug=- --trace=- > "${trace}" &
18014         sleep 5
18015         stop ost1
18016
18017         wait
18018         rc=$?
18019
18020         if ((rc != 0)); then
18021                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18022                 cat "${trace}"
18023                 exit 1
18024         fi
18025 }
18026 run_test 165f "ofd_access_log_reader --exit-on-close works"
18027
18028 test_169() {
18029         # do directio so as not to populate the page cache
18030         log "creating a 10 Mb file"
18031         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18032                 error "multiop failed while creating a file"
18033         log "starting reads"
18034         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18035         log "truncating the file"
18036         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18037                 error "multiop failed while truncating the file"
18038         log "killing dd"
18039         kill %+ || true # reads might have finished
18040         echo "wait until dd is finished"
18041         wait
18042         log "removing the temporary file"
18043         rm -rf $DIR/$tfile || error "tmp file removal failed"
18044 }
18045 run_test 169 "parallel read and truncate should not deadlock"
18046
18047 test_170() {
18048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18049
18050         $LCTL clear     # bug 18514
18051         $LCTL debug_daemon start $TMP/${tfile}_log_good
18052         touch $DIR/$tfile
18053         $LCTL debug_daemon stop
18054         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18055                 error "sed failed to read log_good"
18056
18057         $LCTL debug_daemon start $TMP/${tfile}_log_good
18058         rm -rf $DIR/$tfile
18059         $LCTL debug_daemon stop
18060
18061         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18062                error "lctl df log_bad failed"
18063
18064         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18065         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18066
18067         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18068         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18069
18070         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18071                 error "bad_line good_line1 good_line2 are empty"
18072
18073         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18074         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18075         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18076
18077         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18078         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18079         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18080
18081         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18082                 error "bad_line_new good_line_new are empty"
18083
18084         local expected_good=$((good_line1 + good_line2*2))
18085
18086         rm -f $TMP/${tfile}*
18087         # LU-231, short malformed line may not be counted into bad lines
18088         if [ $bad_line -ne $bad_line_new ] &&
18089                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18090                 error "expected $bad_line bad lines, but got $bad_line_new"
18091                 return 1
18092         fi
18093
18094         if [ $expected_good -ne $good_line_new ]; then
18095                 error "expected $expected_good good lines, but got $good_line_new"
18096                 return 2
18097         fi
18098         true
18099 }
18100 run_test 170 "test lctl df to handle corrupted log ====================="
18101
18102 test_171() { # bug20592
18103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18104
18105         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18106         $LCTL set_param fail_loc=0x50e
18107         $LCTL set_param fail_val=3000
18108         multiop_bg_pause $DIR/$tfile O_s || true
18109         local MULTIPID=$!
18110         kill -USR1 $MULTIPID
18111         # cause log dump
18112         sleep 3
18113         wait $MULTIPID
18114         if dmesg | grep "recursive fault"; then
18115                 error "caught a recursive fault"
18116         fi
18117         $LCTL set_param fail_loc=0
18118         true
18119 }
18120 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18121
18122 test_172() {
18123
18124         #define OBD_FAIL_OBD_CLEANUP  0x60e
18125         $LCTL set_param fail_loc=0x60e
18126         umount $MOUNT || error "umount $MOUNT failed"
18127         stack_trap "mount_client $MOUNT"
18128
18129         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18130                 error "no client OBDs are remained"
18131
18132         $LCTL dl | while read devno state type name foo; do
18133                 case $type in
18134                 lov|osc|lmv|mdc)
18135                         $LCTL --device $name cleanup
18136                         $LCTL --device $name detach
18137                         ;;
18138                 *)
18139                         # skip server devices
18140                         ;;
18141                 esac
18142         done
18143
18144         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18145                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18146                 error "some client OBDs are still remained"
18147         fi
18148
18149 }
18150 run_test 172 "manual device removal with lctl cleanup/detach ======"
18151
18152 # it would be good to share it with obdfilter-survey/iokit-libecho code
18153 setup_obdecho_osc () {
18154         local rc=0
18155         local ost_nid=$1
18156         local obdfilter_name=$2
18157         echo "Creating new osc for $obdfilter_name on $ost_nid"
18158         # make sure we can find loopback nid
18159         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18160
18161         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18162                            ${obdfilter_name}_osc_UUID || rc=2; }
18163         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18164                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18165         return $rc
18166 }
18167
18168 cleanup_obdecho_osc () {
18169         local obdfilter_name=$1
18170         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18171         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18172         return 0
18173 }
18174
18175 obdecho_test() {
18176         local OBD=$1
18177         local node=$2
18178         local pages=${3:-64}
18179         local rc=0
18180         local id
18181
18182         local count=10
18183         local obd_size=$(get_obd_size $node $OBD)
18184         local page_size=$(get_page_size $node)
18185         if [[ -n "$obd_size" ]]; then
18186                 local new_count=$((obd_size / (pages * page_size / 1024)))
18187                 [[ $new_count -ge $count ]] || count=$new_count
18188         fi
18189
18190         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18191         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18192                            rc=2; }
18193         if [ $rc -eq 0 ]; then
18194             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18195             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18196         fi
18197         echo "New object id is $id"
18198         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18199                            rc=4; }
18200         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18201                            "test_brw $count w v $pages $id" || rc=4; }
18202         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18203                            rc=4; }
18204         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18205                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18206         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18207                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18208         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18209         return $rc
18210 }
18211
18212 test_180a() {
18213         skip "obdecho on osc is no longer supported"
18214 }
18215 run_test 180a "test obdecho on osc"
18216
18217 test_180b() {
18218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18219         remote_ost_nodsh && skip "remote OST with nodsh"
18220
18221         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18222                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18223                 error "failed to load module obdecho"
18224
18225         local target=$(do_facet ost1 $LCTL dl |
18226                        awk '/obdfilter/ { print $4; exit; }')
18227
18228         if [ -n "$target" ]; then
18229                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18230         else
18231                 do_facet ost1 $LCTL dl
18232                 error "there is no obdfilter target on ost1"
18233         fi
18234 }
18235 run_test 180b "test obdecho directly on obdfilter"
18236
18237 test_180c() { # LU-2598
18238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18239         remote_ost_nodsh && skip "remote OST with nodsh"
18240         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18241                 skip "Need MDS version at least 2.4.0"
18242
18243         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18244                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18245                 error "failed to load module obdecho"
18246
18247         local target=$(do_facet ost1 $LCTL dl |
18248                        awk '/obdfilter/ { print $4; exit; }')
18249
18250         if [ -n "$target" ]; then
18251                 local pages=16384 # 64MB bulk I/O RPC size
18252
18253                 obdecho_test "$target" ost1 "$pages" ||
18254                         error "obdecho_test with pages=$pages failed with $?"
18255         else
18256                 do_facet ost1 $LCTL dl
18257                 error "there is no obdfilter target on ost1"
18258         fi
18259 }
18260 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18261
18262 test_181() { # bug 22177
18263         test_mkdir $DIR/$tdir
18264         # create enough files to index the directory
18265         createmany -o $DIR/$tdir/foobar 4000
18266         # print attributes for debug purpose
18267         lsattr -d .
18268         # open dir
18269         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18270         MULTIPID=$!
18271         # remove the files & current working dir
18272         unlinkmany $DIR/$tdir/foobar 4000
18273         rmdir $DIR/$tdir
18274         kill -USR1 $MULTIPID
18275         wait $MULTIPID
18276         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18277         return 0
18278 }
18279 run_test 181 "Test open-unlinked dir ========================"
18280
18281 test_182a() {
18282         local fcount=1000
18283         local tcount=10
18284
18285         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18286
18287         $LCTL set_param mdc.*.rpc_stats=clear
18288
18289         for (( i = 0; i < $tcount; i++ )) ; do
18290                 mkdir $DIR/$tdir/$i
18291         done
18292
18293         for (( i = 0; i < $tcount; i++ )) ; do
18294                 createmany -o $DIR/$tdir/$i/f- $fcount &
18295         done
18296         wait
18297
18298         for (( i = 0; i < $tcount; i++ )) ; do
18299                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18300         done
18301         wait
18302
18303         $LCTL get_param mdc.*.rpc_stats
18304
18305         rm -rf $DIR/$tdir
18306 }
18307 run_test 182a "Test parallel modify metadata operations from mdc"
18308
18309 test_182b() {
18310         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18311         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18312         local dcount=1000
18313         local tcount=10
18314         local stime
18315         local etime
18316         local delta
18317
18318         do_facet mds1 $LCTL list_param \
18319                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18320                 skip "MDS lacks parallel RPC handling"
18321
18322         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18323
18324         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18325                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18326
18327         stime=$(date +%s)
18328         createmany -i 0 -d $DIR/$tdir/t- $tcount
18329
18330         for (( i = 0; i < $tcount; i++ )) ; do
18331                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18332         done
18333         wait
18334         etime=$(date +%s)
18335         delta=$((etime - stime))
18336         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18337
18338         stime=$(date +%s)
18339         for (( i = 0; i < $tcount; i++ )) ; do
18340                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18341         done
18342         wait
18343         etime=$(date +%s)
18344         delta=$((etime - stime))
18345         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18346
18347         rm -rf $DIR/$tdir
18348
18349         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18350
18351         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18352
18353         stime=$(date +%s)
18354         createmany -i 0 -d $DIR/$tdir/t- $tcount
18355
18356         for (( i = 0; i < $tcount; i++ )) ; do
18357                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18358         done
18359         wait
18360         etime=$(date +%s)
18361         delta=$((etime - stime))
18362         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18363
18364         stime=$(date +%s)
18365         for (( i = 0; i < $tcount; i++ )) ; do
18366                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18367         done
18368         wait
18369         etime=$(date +%s)
18370         delta=$((etime - stime))
18371         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18372
18373         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18374 }
18375 run_test 182b "Test parallel modify metadata operations from osp"
18376
18377 test_183() { # LU-2275
18378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18379         remote_mds_nodsh && skip "remote MDS with nodsh"
18380         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18381                 skip "Need MDS version at least 2.3.56"
18382
18383         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18384         echo aaa > $DIR/$tdir/$tfile
18385
18386 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18387         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18388
18389         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18390         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18391
18392         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18393
18394         # Flush negative dentry cache
18395         touch $DIR/$tdir/$tfile
18396
18397         # We are not checking for any leaked references here, they'll
18398         # become evident next time we do cleanup with module unload.
18399         rm -rf $DIR/$tdir
18400 }
18401 run_test 183 "No crash or request leak in case of strange dispositions ========"
18402
18403 # test suite 184 is for LU-2016, LU-2017
18404 test_184a() {
18405         check_swap_layouts_support
18406
18407         dir0=$DIR/$tdir/$testnum
18408         test_mkdir -p -c1 $dir0
18409         ref1=/etc/passwd
18410         ref2=/etc/group
18411         file1=$dir0/f1
18412         file2=$dir0/f2
18413         $LFS setstripe -c1 $file1
18414         cp $ref1 $file1
18415         $LFS setstripe -c2 $file2
18416         cp $ref2 $file2
18417         gen1=$($LFS getstripe -g $file1)
18418         gen2=$($LFS getstripe -g $file2)
18419
18420         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18421         gen=$($LFS getstripe -g $file1)
18422         [[ $gen1 != $gen ]] ||
18423                 error "Layout generation on $file1 does not change"
18424         gen=$($LFS getstripe -g $file2)
18425         [[ $gen2 != $gen ]] ||
18426                 error "Layout generation on $file2 does not change"
18427
18428         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18429         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18430
18431         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18432 }
18433 run_test 184a "Basic layout swap"
18434
18435 test_184b() {
18436         check_swap_layouts_support
18437
18438         dir0=$DIR/$tdir/$testnum
18439         mkdir -p $dir0 || error "creating dir $dir0"
18440         file1=$dir0/f1
18441         file2=$dir0/f2
18442         file3=$dir0/f3
18443         dir1=$dir0/d1
18444         dir2=$dir0/d2
18445         mkdir $dir1 $dir2
18446         $LFS setstripe -c1 $file1
18447         $LFS setstripe -c2 $file2
18448         $LFS setstripe -c1 $file3
18449         chown $RUNAS_ID $file3
18450         gen1=$($LFS getstripe -g $file1)
18451         gen2=$($LFS getstripe -g $file2)
18452
18453         $LFS swap_layouts $dir1 $dir2 &&
18454                 error "swap of directories layouts should fail"
18455         $LFS swap_layouts $dir1 $file1 &&
18456                 error "swap of directory and file layouts should fail"
18457         $RUNAS $LFS swap_layouts $file1 $file2 &&
18458                 error "swap of file we cannot write should fail"
18459         $LFS swap_layouts $file1 $file3 &&
18460                 error "swap of file with different owner should fail"
18461         /bin/true # to clear error code
18462 }
18463 run_test 184b "Forbidden layout swap (will generate errors)"
18464
18465 test_184c() {
18466         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18467         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18468         check_swap_layouts_support
18469         check_swap_layout_no_dom $DIR
18470
18471         local dir0=$DIR/$tdir/$testnum
18472         mkdir -p $dir0 || error "creating dir $dir0"
18473
18474         local ref1=$dir0/ref1
18475         local ref2=$dir0/ref2
18476         local file1=$dir0/file1
18477         local file2=$dir0/file2
18478         # create a file large enough for the concurrent test
18479         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18480         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18481         echo "ref file size: ref1($(stat -c %s $ref1))," \
18482              "ref2($(stat -c %s $ref2))"
18483
18484         cp $ref2 $file2
18485         dd if=$ref1 of=$file1 bs=16k &
18486         local DD_PID=$!
18487
18488         # Make sure dd starts to copy file, but wait at most 5 seconds
18489         local loops=0
18490         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18491
18492         $LFS swap_layouts $file1 $file2
18493         local rc=$?
18494         wait $DD_PID
18495         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18496         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18497
18498         # how many bytes copied before swapping layout
18499         local copied=$(stat -c %s $file2)
18500         local remaining=$(stat -c %s $ref1)
18501         remaining=$((remaining - copied))
18502         echo "Copied $copied bytes before swapping layout..."
18503
18504         cmp -n $copied $file1 $ref2 | grep differ &&
18505                 error "Content mismatch [0, $copied) of ref2 and file1"
18506         cmp -n $copied $file2 $ref1 ||
18507                 error "Content mismatch [0, $copied) of ref1 and file2"
18508         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18509                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18510
18511         # clean up
18512         rm -f $ref1 $ref2 $file1 $file2
18513 }
18514 run_test 184c "Concurrent write and layout swap"
18515
18516 test_184d() {
18517         check_swap_layouts_support
18518         check_swap_layout_no_dom $DIR
18519         [ -z "$(which getfattr 2>/dev/null)" ] &&
18520                 skip_env "no getfattr command"
18521
18522         local file1=$DIR/$tdir/$tfile-1
18523         local file2=$DIR/$tdir/$tfile-2
18524         local file3=$DIR/$tdir/$tfile-3
18525         local lovea1
18526         local lovea2
18527
18528         mkdir -p $DIR/$tdir
18529         touch $file1 || error "create $file1 failed"
18530         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18531                 error "create $file2 failed"
18532         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18533                 error "create $file3 failed"
18534         lovea1=$(get_layout_param $file1)
18535
18536         $LFS swap_layouts $file2 $file3 ||
18537                 error "swap $file2 $file3 layouts failed"
18538         $LFS swap_layouts $file1 $file2 ||
18539                 error "swap $file1 $file2 layouts failed"
18540
18541         lovea2=$(get_layout_param $file2)
18542         echo "$lovea1"
18543         echo "$lovea2"
18544         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18545
18546         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18547         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18548 }
18549 run_test 184d "allow stripeless layouts swap"
18550
18551 test_184e() {
18552         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18553                 skip "Need MDS version at least 2.6.94"
18554         check_swap_layouts_support
18555         check_swap_layout_no_dom $DIR
18556         [ -z "$(which getfattr 2>/dev/null)" ] &&
18557                 skip_env "no getfattr command"
18558
18559         local file1=$DIR/$tdir/$tfile-1
18560         local file2=$DIR/$tdir/$tfile-2
18561         local file3=$DIR/$tdir/$tfile-3
18562         local lovea
18563
18564         mkdir -p $DIR/$tdir
18565         touch $file1 || error "create $file1 failed"
18566         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18567                 error "create $file2 failed"
18568         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18569                 error "create $file3 failed"
18570
18571         $LFS swap_layouts $file1 $file2 ||
18572                 error "swap $file1 $file2 layouts failed"
18573
18574         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18575         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18576
18577         echo 123 > $file1 || error "Should be able to write into $file1"
18578
18579         $LFS swap_layouts $file1 $file3 ||
18580                 error "swap $file1 $file3 layouts failed"
18581
18582         echo 123 > $file1 || error "Should be able to write into $file1"
18583
18584         rm -rf $file1 $file2 $file3
18585 }
18586 run_test 184e "Recreate layout after stripeless layout swaps"
18587
18588 test_184f() {
18589         # Create a file with name longer than sizeof(struct stat) ==
18590         # 144 to see if we can get chars from the file name to appear
18591         # in the returned striping. Note that 'f' == 0x66.
18592         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18593
18594         mkdir -p $DIR/$tdir
18595         mcreate $DIR/$tdir/$file
18596         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18597                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18598         fi
18599 }
18600 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18601
18602 test_185() { # LU-2441
18603         # LU-3553 - no volatile file support in old servers
18604         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18605                 skip "Need MDS version at least 2.3.60"
18606
18607         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18608         touch $DIR/$tdir/spoo
18609         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18610         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18611                 error "cannot create/write a volatile file"
18612         [ "$FILESET" == "" ] &&
18613         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18614                 error "FID is still valid after close"
18615
18616         multiop_bg_pause $DIR/$tdir vVw4096_c
18617         local multi_pid=$!
18618
18619         local OLD_IFS=$IFS
18620         IFS=":"
18621         local fidv=($fid)
18622         IFS=$OLD_IFS
18623         # assume that the next FID for this client is sequential, since stdout
18624         # is unfortunately eaten by multiop_bg_pause
18625         local n=$((${fidv[1]} + 1))
18626         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18627         if [ "$FILESET" == "" ]; then
18628                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18629                         error "FID is missing before close"
18630         fi
18631         kill -USR1 $multi_pid
18632         # 1 second delay, so if mtime change we will see it
18633         sleep 1
18634         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18635         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18636 }
18637 run_test 185 "Volatile file support"
18638
18639 function create_check_volatile() {
18640         local idx=$1
18641         local tgt
18642
18643         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18644         local PID=$!
18645         sleep 1
18646         local FID=$(cat /tmp/${tfile}.fid)
18647         [ "$FID" == "" ] && error "can't get FID for volatile"
18648         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18649         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18650         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18651         kill -USR1 $PID
18652         wait
18653         sleep 1
18654         cancel_lru_locks mdc # flush opencache
18655         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18656         return 0
18657 }
18658
18659 test_185a(){
18660         # LU-12516 - volatile creation via .lustre
18661         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18662                 skip "Need MDS version at least 2.3.55"
18663
18664         create_check_volatile 0
18665         [ $MDSCOUNT -lt 2 ] && return 0
18666
18667         # DNE case
18668         create_check_volatile 1
18669
18670         return 0
18671 }
18672 run_test 185a "Volatile file creation in .lustre/fid/"
18673
18674 test_187a() {
18675         remote_mds_nodsh && skip "remote MDS with nodsh"
18676         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18677                 skip "Need MDS version at least 2.3.0"
18678
18679         local dir0=$DIR/$tdir/$testnum
18680         mkdir -p $dir0 || error "creating dir $dir0"
18681
18682         local file=$dir0/file1
18683         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18684         local dv1=$($LFS data_version $file)
18685         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18686         local dv2=$($LFS data_version $file)
18687         [[ $dv1 != $dv2 ]] ||
18688                 error "data version did not change on write $dv1 == $dv2"
18689
18690         # clean up
18691         rm -f $file1
18692 }
18693 run_test 187a "Test data version change"
18694
18695 test_187b() {
18696         remote_mds_nodsh && skip "remote MDS with nodsh"
18697         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18698                 skip "Need MDS version at least 2.3.0"
18699
18700         local dir0=$DIR/$tdir/$testnum
18701         mkdir -p $dir0 || error "creating dir $dir0"
18702
18703         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18704         [[ ${DV[0]} != ${DV[1]} ]] ||
18705                 error "data version did not change on write"\
18706                       " ${DV[0]} == ${DV[1]}"
18707
18708         # clean up
18709         rm -f $file1
18710 }
18711 run_test 187b "Test data version change on volatile file"
18712
18713 test_200() {
18714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18715         remote_mgs_nodsh && skip "remote MGS with nodsh"
18716         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18717
18718         local POOL=${POOL:-cea1}
18719         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18720         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18721         # Pool OST targets
18722         local first_ost=0
18723         local last_ost=$(($OSTCOUNT - 1))
18724         local ost_step=2
18725         local ost_list=$(seq $first_ost $ost_step $last_ost)
18726         local ost_range="$first_ost $last_ost $ost_step"
18727         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18728         local file_dir=$POOL_ROOT/file_tst
18729         local subdir=$test_path/subdir
18730         local rc=0
18731
18732         while : ; do
18733                 # former test_200a test_200b
18734                 pool_add $POOL                          || { rc=$? ; break; }
18735                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18736                 # former test_200c test_200d
18737                 mkdir -p $test_path
18738                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18739                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18740                 mkdir -p $subdir
18741                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18742                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18743                                                         || { rc=$? ; break; }
18744                 # former test_200e test_200f
18745                 local files=$((OSTCOUNT*3))
18746                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18747                                                         || { rc=$? ; break; }
18748                 pool_create_files $POOL $file_dir $files "$ost_list" \
18749                                                         || { rc=$? ; break; }
18750                 # former test_200g test_200h
18751                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18752                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18753
18754                 # former test_201a test_201b test_201c
18755                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18756
18757                 local f=$test_path/$tfile
18758                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18759                 pool_remove $POOL $f                    || { rc=$? ; break; }
18760                 break
18761         done
18762
18763         destroy_test_pools
18764
18765         return $rc
18766 }
18767 run_test 200 "OST pools"
18768
18769 # usage: default_attr <count | size | offset>
18770 default_attr() {
18771         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18772 }
18773
18774 # usage: check_default_stripe_attr
18775 check_default_stripe_attr() {
18776         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18777         case $1 in
18778         --stripe-count|-c)
18779                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18780         --stripe-size|-S)
18781                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18782         --stripe-index|-i)
18783                 EXPECTED=-1;;
18784         *)
18785                 error "unknown getstripe attr '$1'"
18786         esac
18787
18788         [ $ACTUAL == $EXPECTED ] ||
18789                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18790 }
18791
18792 test_204a() {
18793         test_mkdir $DIR/$tdir
18794         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18795
18796         check_default_stripe_attr --stripe-count
18797         check_default_stripe_attr --stripe-size
18798         check_default_stripe_attr --stripe-index
18799 }
18800 run_test 204a "Print default stripe attributes"
18801
18802 test_204b() {
18803         test_mkdir $DIR/$tdir
18804         $LFS setstripe --stripe-count 1 $DIR/$tdir
18805
18806         check_default_stripe_attr --stripe-size
18807         check_default_stripe_attr --stripe-index
18808 }
18809 run_test 204b "Print default stripe size and offset"
18810
18811 test_204c() {
18812         test_mkdir $DIR/$tdir
18813         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18814
18815         check_default_stripe_attr --stripe-count
18816         check_default_stripe_attr --stripe-index
18817 }
18818 run_test 204c "Print default stripe count and offset"
18819
18820 test_204d() {
18821         test_mkdir $DIR/$tdir
18822         $LFS setstripe --stripe-index 0 $DIR/$tdir
18823
18824         check_default_stripe_attr --stripe-count
18825         check_default_stripe_attr --stripe-size
18826 }
18827 run_test 204d "Print default stripe count and size"
18828
18829 test_204e() {
18830         test_mkdir $DIR/$tdir
18831         $LFS setstripe -d $DIR/$tdir
18832
18833         check_default_stripe_attr --stripe-count --raw
18834         check_default_stripe_attr --stripe-size --raw
18835         check_default_stripe_attr --stripe-index --raw
18836 }
18837 run_test 204e "Print raw stripe attributes"
18838
18839 test_204f() {
18840         test_mkdir $DIR/$tdir
18841         $LFS setstripe --stripe-count 1 $DIR/$tdir
18842
18843         check_default_stripe_attr --stripe-size --raw
18844         check_default_stripe_attr --stripe-index --raw
18845 }
18846 run_test 204f "Print raw stripe size and offset"
18847
18848 test_204g() {
18849         test_mkdir $DIR/$tdir
18850         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18851
18852         check_default_stripe_attr --stripe-count --raw
18853         check_default_stripe_attr --stripe-index --raw
18854 }
18855 run_test 204g "Print raw stripe count and offset"
18856
18857 test_204h() {
18858         test_mkdir $DIR/$tdir
18859         $LFS setstripe --stripe-index 0 $DIR/$tdir
18860
18861         check_default_stripe_attr --stripe-count --raw
18862         check_default_stripe_attr --stripe-size --raw
18863 }
18864 run_test 204h "Print raw stripe count and size"
18865
18866 # Figure out which job scheduler is being used, if any,
18867 # or use a fake one
18868 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18869         JOBENV=SLURM_JOB_ID
18870 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18871         JOBENV=LSB_JOBID
18872 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18873         JOBENV=PBS_JOBID
18874 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18875         JOBENV=LOADL_STEP_ID
18876 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18877         JOBENV=JOB_ID
18878 else
18879         $LCTL list_param jobid_name > /dev/null 2>&1
18880         if [ $? -eq 0 ]; then
18881                 JOBENV=nodelocal
18882         else
18883                 JOBENV=FAKE_JOBID
18884         fi
18885 fi
18886 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18887
18888 verify_jobstats() {
18889         local cmd=($1)
18890         shift
18891         local facets="$@"
18892
18893 # we don't really need to clear the stats for this test to work, since each
18894 # command has a unique jobid, but it makes debugging easier if needed.
18895 #       for facet in $facets; do
18896 #               local dev=$(convert_facet2label $facet)
18897 #               # clear old jobstats
18898 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18899 #       done
18900
18901         # use a new JobID for each test, or we might see an old one
18902         [ "$JOBENV" = "FAKE_JOBID" ] &&
18903                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18904
18905         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18906
18907         [ "$JOBENV" = "nodelocal" ] && {
18908                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18909                 $LCTL set_param jobid_name=$FAKE_JOBID
18910                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18911         }
18912
18913         log "Test: ${cmd[*]}"
18914         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18915
18916         if [ $JOBENV = "FAKE_JOBID" ]; then
18917                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18918         else
18919                 ${cmd[*]}
18920         fi
18921
18922         # all files are created on OST0000
18923         for facet in $facets; do
18924                 local stats="*.$(convert_facet2label $facet).job_stats"
18925
18926                 # strip out libtool wrappers for in-tree executables
18927                 if (( $(do_facet $facet lctl get_param $stats |
18928                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18929                         do_facet $facet lctl get_param $stats
18930                         error "No jobstats for $JOBVAL found on $facet::$stats"
18931                 fi
18932         done
18933 }
18934
18935 jobstats_set() {
18936         local new_jobenv=$1
18937
18938         set_persistent_param_and_check client "jobid_var" \
18939                 "$FSNAME.sys.jobid_var" $new_jobenv
18940 }
18941
18942 test_205a() { # Job stats
18943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18944         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18945                 skip "Need MDS version with at least 2.7.1"
18946         remote_mgs_nodsh && skip "remote MGS with nodsh"
18947         remote_mds_nodsh && skip "remote MDS with nodsh"
18948         remote_ost_nodsh && skip "remote OST with nodsh"
18949         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18950                 skip "Server doesn't support jobstats"
18951         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18952
18953         local old_jobenv=$($LCTL get_param -n jobid_var)
18954         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18955
18956         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18957                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18958         else
18959                 stack_trap "do_facet mgs $PERM_CMD \
18960                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18961         fi
18962         changelog_register
18963
18964         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18965                                 mdt.*.job_cleanup_interval | head -n 1)
18966         local new_interval=5
18967         do_facet $SINGLEMDS \
18968                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18969         stack_trap "do_facet $SINGLEMDS \
18970                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18971         local start=$SECONDS
18972
18973         local cmd
18974         # mkdir
18975         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18976         verify_jobstats "$cmd" "$SINGLEMDS"
18977         # rmdir
18978         cmd="rmdir $DIR/$tdir"
18979         verify_jobstats "$cmd" "$SINGLEMDS"
18980         # mkdir on secondary MDT
18981         if [ $MDSCOUNT -gt 1 ]; then
18982                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18983                 verify_jobstats "$cmd" "mds2"
18984         fi
18985         # mknod
18986         cmd="mknod $DIR/$tfile c 1 3"
18987         verify_jobstats "$cmd" "$SINGLEMDS"
18988         # unlink
18989         cmd="rm -f $DIR/$tfile"
18990         verify_jobstats "$cmd" "$SINGLEMDS"
18991         # create all files on OST0000 so verify_jobstats can find OST stats
18992         # open & close
18993         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18994         verify_jobstats "$cmd" "$SINGLEMDS"
18995         # setattr
18996         cmd="touch $DIR/$tfile"
18997         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18998         # write
18999         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19000         verify_jobstats "$cmd" "ost1"
19001         # read
19002         cancel_lru_locks osc
19003         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19004         verify_jobstats "$cmd" "ost1"
19005         # truncate
19006         cmd="$TRUNCATE $DIR/$tfile 0"
19007         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19008         # rename
19009         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19010         verify_jobstats "$cmd" "$SINGLEMDS"
19011         # jobstats expiry - sleep until old stats should be expired
19012         local left=$((new_interval + 5 - (SECONDS - start)))
19013         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19014                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19015                         "0" $left
19016         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19017         verify_jobstats "$cmd" "$SINGLEMDS"
19018         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19019             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19020
19021         # Ensure that jobid are present in changelog (if supported by MDS)
19022         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19023                 changelog_dump | tail -10
19024                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19025                 [ $jobids -eq 9 ] ||
19026                         error "Wrong changelog jobid count $jobids != 9"
19027
19028                 # LU-5862
19029                 JOBENV="disable"
19030                 jobstats_set $JOBENV
19031                 touch $DIR/$tfile
19032                 changelog_dump | grep $tfile
19033                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19034                 [ $jobids -eq 0 ] ||
19035                         error "Unexpected jobids when jobid_var=$JOBENV"
19036         fi
19037
19038         # test '%j' access to environment variable - if supported
19039         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19040                 JOBENV="JOBCOMPLEX"
19041                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19042
19043                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19044         fi
19045
19046         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19047                 JOBENV="JOBCOMPLEX"
19048                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19049
19050                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19051         fi
19052
19053         # test '%j' access to per-session jobid - if supported
19054         if lctl list_param jobid_this_session > /dev/null 2>&1
19055         then
19056                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19057                 lctl set_param jobid_this_session=$USER
19058
19059                 JOBENV="JOBCOMPLEX"
19060                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19061
19062                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19063         fi
19064 }
19065 run_test 205a "Verify job stats"
19066
19067 # LU-13117, LU-13597
19068 test_205b() {
19069         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19070                 skip "Need MDS version at least 2.13.54.91"
19071
19072         local job_stats="mdt.*.job_stats"
19073         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19074
19075         do_facet mds1 $LCTL set_param $job_stats=clear
19076
19077         # Setting jobid_var to USER might not be supported
19078         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19079         $LCTL set_param jobid_var=USER || true
19080         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19081         $LCTL set_param jobid_name="%j.%e.%u"
19082
19083         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19084         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19085                 { do_facet mds1 $LCTL get_param $job_stats;
19086                   error "Unexpected jobid found"; }
19087         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19088                 { do_facet mds1 $LCTL get_param $job_stats;
19089                   error "wrong job_stats format found"; }
19090
19091         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19092                 echo "MDS does not yet escape jobid" && return 0
19093         $LCTL set_param jobid_var=TEST205b
19094         env -i TEST205b="has sp" touch $DIR/$tfile.2
19095         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19096                 { do_facet mds1 $LCTL get_param $job_stats;
19097                   error "jobid not escaped"; }
19098 }
19099 run_test 205b "Verify job stats jobid and output format"
19100
19101 # LU-13733
19102 test_205c() {
19103         $LCTL set_param llite.*.stats=0
19104         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19105         $LCTL get_param llite.*.stats
19106         $LCTL get_param llite.*.stats | grep \
19107                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19108                         error "wrong client stats format found"
19109 }
19110 run_test 205c "Verify client stats format"
19111
19112 # LU-1480, LU-1773 and LU-1657
19113 test_206() {
19114         mkdir -p $DIR/$tdir
19115         $LFS setstripe -c -1 $DIR/$tdir
19116 #define OBD_FAIL_LOV_INIT 0x1403
19117         $LCTL set_param fail_loc=0xa0001403
19118         $LCTL set_param fail_val=1
19119         touch $DIR/$tdir/$tfile || true
19120 }
19121 run_test 206 "fail lov_init_raid0() doesn't lbug"
19122
19123 test_207a() {
19124         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19125         local fsz=`stat -c %s $DIR/$tfile`
19126         cancel_lru_locks mdc
19127
19128         # do not return layout in getattr intent
19129 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19130         $LCTL set_param fail_loc=0x170
19131         local sz=`stat -c %s $DIR/$tfile`
19132
19133         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19134
19135         rm -rf $DIR/$tfile
19136 }
19137 run_test 207a "can refresh layout at glimpse"
19138
19139 test_207b() {
19140         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19141         local cksum=`md5sum $DIR/$tfile`
19142         local fsz=`stat -c %s $DIR/$tfile`
19143         cancel_lru_locks mdc
19144         cancel_lru_locks osc
19145
19146         # do not return layout in getattr intent
19147 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19148         $LCTL set_param fail_loc=0x171
19149
19150         # it will refresh layout after the file is opened but before read issues
19151         echo checksum is "$cksum"
19152         echo "$cksum" |md5sum -c --quiet || error "file differs"
19153
19154         rm -rf $DIR/$tfile
19155 }
19156 run_test 207b "can refresh layout at open"
19157
19158 test_208() {
19159         # FIXME: in this test suite, only RD lease is used. This is okay
19160         # for now as only exclusive open is supported. After generic lease
19161         # is done, this test suite should be revised. - Jinshan
19162
19163         remote_mds_nodsh && skip "remote MDS with nodsh"
19164         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19165                 skip "Need MDS version at least 2.4.52"
19166
19167         echo "==== test 1: verify get lease work"
19168         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19169
19170         echo "==== test 2: verify lease can be broken by upcoming open"
19171         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19172         local PID=$!
19173         sleep 2
19174
19175         $MULTIOP $DIR/$tfile oO_RDWR:c
19176         kill -USR1 $PID && wait $PID || error "break lease error"
19177
19178         echo "==== test 3: verify lease can't be granted if an open already exists"
19179         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19180         local PID=$!
19181         sleep 2
19182
19183         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19184         kill -USR1 $PID && wait $PID || error "open file error"
19185
19186         echo "==== test 4: lease can sustain over recovery"
19187         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19188         PID=$!
19189         sleep 2
19190
19191         fail mds1
19192
19193         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19194
19195         echo "==== test 5: lease broken can't be regained by replay"
19196         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19197         PID=$!
19198         sleep 2
19199
19200         # open file to break lease and then recovery
19201         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19202         fail mds1
19203
19204         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19205
19206         rm -f $DIR/$tfile
19207 }
19208 run_test 208 "Exclusive open"
19209
19210 test_209() {
19211         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19212                 skip_env "must have disp_stripe"
19213
19214         touch $DIR/$tfile
19215         sync; sleep 5; sync;
19216
19217         echo 3 > /proc/sys/vm/drop_caches
19218         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19219                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19220         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19221
19222         # open/close 500 times
19223         for i in $(seq 500); do
19224                 cat $DIR/$tfile
19225         done
19226
19227         echo 3 > /proc/sys/vm/drop_caches
19228         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19229                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19230         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19231
19232         echo "before: $req_before, after: $req_after"
19233         [ $((req_after - req_before)) -ge 300 ] &&
19234                 error "open/close requests are not freed"
19235         return 0
19236 }
19237 run_test 209 "read-only open/close requests should be freed promptly"
19238
19239 test_210() {
19240         local pid
19241
19242         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19243         pid=$!
19244         sleep 1
19245
19246         $LFS getstripe $DIR/$tfile
19247         kill -USR1 $pid
19248         wait $pid || error "multiop failed"
19249
19250         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19251         pid=$!
19252         sleep 1
19253
19254         $LFS getstripe $DIR/$tfile
19255         kill -USR1 $pid
19256         wait $pid || error "multiop failed"
19257 }
19258 run_test 210 "lfs getstripe does not break leases"
19259
19260 test_212() {
19261         size=`date +%s`
19262         size=$((size % 8192 + 1))
19263         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19264         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19265         rm -f $DIR/f212 $DIR/f212.xyz
19266 }
19267 run_test 212 "Sendfile test ============================================"
19268
19269 test_213() {
19270         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19271         cancel_lru_locks osc
19272         lctl set_param fail_loc=0x8000040f
19273         # generate a read lock
19274         cat $DIR/$tfile > /dev/null
19275         # write to the file, it will try to cancel the above read lock.
19276         cat /etc/hosts >> $DIR/$tfile
19277 }
19278 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19279
19280 test_214() { # for bug 20133
19281         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19282         for (( i=0; i < 340; i++ )) ; do
19283                 touch $DIR/$tdir/d214c/a$i
19284         done
19285
19286         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19287         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19288         ls $DIR/d214c || error "ls $DIR/d214c failed"
19289         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19290         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19291 }
19292 run_test 214 "hash-indexed directory test - bug 20133"
19293
19294 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19295 create_lnet_proc_files() {
19296         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19297 }
19298
19299 # counterpart of create_lnet_proc_files
19300 remove_lnet_proc_files() {
19301         rm -f $TMP/lnet_$1.sys
19302 }
19303
19304 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19305 # 3rd arg as regexp for body
19306 check_lnet_proc_stats() {
19307         local l=$(cat "$TMP/lnet_$1" |wc -l)
19308         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19309
19310         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19311 }
19312
19313 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19314 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19315 # optional and can be regexp for 2nd line (lnet.routes case)
19316 check_lnet_proc_entry() {
19317         local blp=2          # blp stands for 'position of 1st line of body'
19318         [ -z "$5" ] || blp=3 # lnet.routes case
19319
19320         local l=$(cat "$TMP/lnet_$1" |wc -l)
19321         # subtracting one from $blp because the body can be empty
19322         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19323
19324         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19325                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19326
19327         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19328                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19329
19330         # bail out if any unexpected line happened
19331         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19332         [ "$?" != 0 ] || error "$2 misformatted"
19333 }
19334
19335 test_215() { # for bugs 18102, 21079, 21517
19336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19337
19338         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19339         local P='[1-9][0-9]*'           # positive numeric
19340         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19341         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19342         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19343         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19344
19345         local L1 # regexp for 1st line
19346         local L2 # regexp for 2nd line (optional)
19347         local BR # regexp for the rest (body)
19348
19349         # lnet.stats should look as 11 space-separated non-negative numerics
19350         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19351         create_lnet_proc_files "stats"
19352         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19353         remove_lnet_proc_files "stats"
19354
19355         # lnet.routes should look like this:
19356         # Routing disabled/enabled
19357         # net hops priority state router
19358         # where net is a string like tcp0, hops > 0, priority >= 0,
19359         # state is up/down,
19360         # router is a string like 192.168.1.1@tcp2
19361         L1="^Routing (disabled|enabled)$"
19362         L2="^net +hops +priority +state +router$"
19363         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19364         create_lnet_proc_files "routes"
19365         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19366         remove_lnet_proc_files "routes"
19367
19368         # lnet.routers should look like this:
19369         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19370         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19371         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19372         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19373         L1="^ref +rtr_ref +alive +router$"
19374         BR="^$P +$P +(up|down) +$NID$"
19375         create_lnet_proc_files "routers"
19376         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19377         remove_lnet_proc_files "routers"
19378
19379         # lnet.peers should look like this:
19380         # nid refs state last max rtr min tx min queue
19381         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19382         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19383         # numeric (0 or >0 or <0), queue >= 0.
19384         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19385         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19386         create_lnet_proc_files "peers"
19387         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19388         remove_lnet_proc_files "peers"
19389
19390         # lnet.buffers  should look like this:
19391         # pages count credits min
19392         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19393         L1="^pages +count +credits +min$"
19394         BR="^ +$N +$N +$I +$I$"
19395         create_lnet_proc_files "buffers"
19396         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19397         remove_lnet_proc_files "buffers"
19398
19399         # lnet.nis should look like this:
19400         # nid status alive refs peer rtr max tx min
19401         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19402         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19403         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19404         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19405         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19406         create_lnet_proc_files "nis"
19407         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19408         remove_lnet_proc_files "nis"
19409
19410         # can we successfully write to lnet.stats?
19411         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19412 }
19413 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19414
19415 test_216() { # bug 20317
19416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19417         remote_ost_nodsh && skip "remote OST with nodsh"
19418
19419         local node
19420         local facets=$(get_facets OST)
19421         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19422
19423         save_lustre_params client "osc.*.contention_seconds" > $p
19424         save_lustre_params $facets \
19425                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19426         save_lustre_params $facets \
19427                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19428         save_lustre_params $facets \
19429                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19430         clear_stats osc.*.osc_stats
19431
19432         # agressive lockless i/o settings
19433         do_nodes $(comma_list $(osts_nodes)) \
19434                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19435                         ldlm.namespaces.filter-*.contended_locks=0 \
19436                         ldlm.namespaces.filter-*.contention_seconds=60"
19437         lctl set_param -n osc.*.contention_seconds=60
19438
19439         $DIRECTIO write $DIR/$tfile 0 10 4096
19440         $CHECKSTAT -s 40960 $DIR/$tfile
19441
19442         # disable lockless i/o
19443         do_nodes $(comma_list $(osts_nodes)) \
19444                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19445                         ldlm.namespaces.filter-*.contended_locks=32 \
19446                         ldlm.namespaces.filter-*.contention_seconds=0"
19447         lctl set_param -n osc.*.contention_seconds=0
19448         clear_stats osc.*.osc_stats
19449
19450         dd if=/dev/zero of=$DIR/$tfile count=0
19451         $CHECKSTAT -s 0 $DIR/$tfile
19452
19453         restore_lustre_params <$p
19454         rm -f $p
19455         rm $DIR/$tfile
19456 }
19457 run_test 216 "check lockless direct write updates file size and kms correctly"
19458
19459 test_217() { # bug 22430
19460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19461
19462         local node
19463         local nid
19464
19465         for node in $(nodes_list); do
19466                 nid=$(host_nids_address $node $NETTYPE)
19467                 if [[ $nid = *-* ]] ; then
19468                         echo "lctl ping $(h2nettype $nid)"
19469                         lctl ping $(h2nettype $nid)
19470                 else
19471                         echo "skipping $node (no hyphen detected)"
19472                 fi
19473         done
19474 }
19475 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19476
19477 test_218() {
19478        # do directio so as not to populate the page cache
19479        log "creating a 10 Mb file"
19480        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19481        log "starting reads"
19482        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19483        log "truncating the file"
19484        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19485        log "killing dd"
19486        kill %+ || true # reads might have finished
19487        echo "wait until dd is finished"
19488        wait
19489        log "removing the temporary file"
19490        rm -rf $DIR/$tfile || error "tmp file removal failed"
19491 }
19492 run_test 218 "parallel read and truncate should not deadlock"
19493
19494 test_219() {
19495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19496
19497         # write one partial page
19498         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19499         # set no grant so vvp_io_commit_write will do sync write
19500         $LCTL set_param fail_loc=0x411
19501         # write a full page at the end of file
19502         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19503
19504         $LCTL set_param fail_loc=0
19505         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19506         $LCTL set_param fail_loc=0x411
19507         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19508
19509         # LU-4201
19510         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19511         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19512 }
19513 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19514
19515 test_220() { #LU-325
19516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19517         remote_ost_nodsh && skip "remote OST with nodsh"
19518         remote_mds_nodsh && skip "remote MDS with nodsh"
19519         remote_mgs_nodsh && skip "remote MGS with nodsh"
19520
19521         local OSTIDX=0
19522
19523         # create on MDT0000 so the last_id and next_id are correct
19524         mkdir_on_mdt0 $DIR/$tdir
19525         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19526         OST=${OST%_UUID}
19527
19528         # on the mdt's osc
19529         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19530         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19531                         osp.$mdtosc_proc1.prealloc_last_id)
19532         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19533                         osp.$mdtosc_proc1.prealloc_next_id)
19534
19535         $LFS df -i
19536
19537         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19538         #define OBD_FAIL_OST_ENOINO              0x229
19539         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19540         create_pool $FSNAME.$TESTNAME || return 1
19541         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19542
19543         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19544
19545         MDSOBJS=$((last_id - next_id))
19546         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19547
19548         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19549         echo "OST still has $count kbytes free"
19550
19551         echo "create $MDSOBJS files @next_id..."
19552         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19553
19554         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19555                         osp.$mdtosc_proc1.prealloc_last_id)
19556         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19557                         osp.$mdtosc_proc1.prealloc_next_id)
19558
19559         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19560         $LFS df -i
19561
19562         echo "cleanup..."
19563
19564         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19565         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19566
19567         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19568                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19569         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19570                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19571         echo "unlink $MDSOBJS files @$next_id..."
19572         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19573 }
19574 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19575
19576 test_221() {
19577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19578
19579         dd if=`which date` of=$MOUNT/date oflag=sync
19580         chmod +x $MOUNT/date
19581
19582         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19583         $LCTL set_param fail_loc=0x80001401
19584
19585         $MOUNT/date > /dev/null
19586         rm -f $MOUNT/date
19587 }
19588 run_test 221 "make sure fault and truncate race to not cause OOM"
19589
19590 test_222a () {
19591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19592
19593         rm -rf $DIR/$tdir
19594         test_mkdir $DIR/$tdir
19595         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19596         createmany -o $DIR/$tdir/$tfile 10
19597         cancel_lru_locks mdc
19598         cancel_lru_locks osc
19599         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19600         $LCTL set_param fail_loc=0x31a
19601         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19602         $LCTL set_param fail_loc=0
19603         rm -r $DIR/$tdir
19604 }
19605 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19606
19607 test_222b () {
19608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19609
19610         rm -rf $DIR/$tdir
19611         test_mkdir $DIR/$tdir
19612         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19613         createmany -o $DIR/$tdir/$tfile 10
19614         cancel_lru_locks mdc
19615         cancel_lru_locks osc
19616         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19617         $LCTL set_param fail_loc=0x31a
19618         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19619         $LCTL set_param fail_loc=0
19620 }
19621 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19622
19623 test_223 () {
19624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19625
19626         rm -rf $DIR/$tdir
19627         test_mkdir $DIR/$tdir
19628         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19629         createmany -o $DIR/$tdir/$tfile 10
19630         cancel_lru_locks mdc
19631         cancel_lru_locks osc
19632         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19633         $LCTL set_param fail_loc=0x31b
19634         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19635         $LCTL set_param fail_loc=0
19636         rm -r $DIR/$tdir
19637 }
19638 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19639
19640 test_224a() { # LU-1039, MRP-303
19641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19642         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19643         $LCTL set_param fail_loc=0x508
19644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19645         $LCTL set_param fail_loc=0
19646         df $DIR
19647 }
19648 run_test 224a "Don't panic on bulk IO failure"
19649
19650 test_224bd_sub() { # LU-1039, MRP-303
19651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19652         local timeout=$1
19653
19654         shift
19655         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19656
19657         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19658
19659         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19660         cancel_lru_locks osc
19661         set_checksums 0
19662         stack_trap "set_checksums $ORIG_CSUM" EXIT
19663         local at_max_saved=0
19664
19665         # adaptive timeouts may prevent seeing the issue
19666         if at_is_enabled; then
19667                 at_max_saved=$(at_max_get mds)
19668                 at_max_set 0 mds client
19669                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19670         fi
19671
19672         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19673         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19674         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19675
19676         do_facet ost1 $LCTL set_param fail_loc=0
19677         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19678         df $DIR
19679 }
19680
19681 test_224b() {
19682         test_224bd_sub 3 error "dd failed"
19683 }
19684 run_test 224b "Don't panic on bulk IO failure"
19685
19686 test_224c() { # LU-6441
19687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19688         remote_mds_nodsh && skip "remote MDS with nodsh"
19689
19690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19691         save_writethrough $p
19692         set_cache writethrough on
19693
19694         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19695         local at_max=$($LCTL get_param -n at_max)
19696         local timeout=$($LCTL get_param -n timeout)
19697         local test_at="at_max"
19698         local param_at="$FSNAME.sys.at_max"
19699         local test_timeout="timeout"
19700         local param_timeout="$FSNAME.sys.timeout"
19701
19702         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19703
19704         set_persistent_param_and_check client "$test_at" "$param_at" 0
19705         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19706
19707         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19708         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19709         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19710         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19711         sync
19712         do_facet ost1 "$LCTL set_param fail_loc=0"
19713
19714         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19715         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19716                 $timeout
19717
19718         $LCTL set_param -n $pages_per_rpc
19719         restore_lustre_params < $p
19720         rm -f $p
19721 }
19722 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19723
19724 test_224d() { # LU-11169
19725         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19726 }
19727 run_test 224d "Don't corrupt data on bulk IO timeout"
19728
19729 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19730 test_225a () {
19731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19732         if [ -z ${MDSSURVEY} ]; then
19733                 skip_env "mds-survey not found"
19734         fi
19735         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19736                 skip "Need MDS version at least 2.2.51"
19737
19738         local mds=$(facet_host $SINGLEMDS)
19739         local target=$(do_nodes $mds 'lctl dl' |
19740                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19741
19742         local cmd1="file_count=1000 thrhi=4"
19743         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19744         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19745         local cmd="$cmd1 $cmd2 $cmd3"
19746
19747         rm -f ${TMP}/mds_survey*
19748         echo + $cmd
19749         eval $cmd || error "mds-survey with zero-stripe failed"
19750         cat ${TMP}/mds_survey*
19751         rm -f ${TMP}/mds_survey*
19752 }
19753 run_test 225a "Metadata survey sanity with zero-stripe"
19754
19755 test_225b () {
19756         if [ -z ${MDSSURVEY} ]; then
19757                 skip_env "mds-survey not found"
19758         fi
19759         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19760                 skip "Need MDS version at least 2.2.51"
19761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19762         remote_mds_nodsh && skip "remote MDS with nodsh"
19763         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19764                 skip_env "Need to mount OST to test"
19765         fi
19766
19767         local mds=$(facet_host $SINGLEMDS)
19768         local target=$(do_nodes $mds 'lctl dl' |
19769                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19770
19771         local cmd1="file_count=1000 thrhi=4"
19772         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19773         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19774         local cmd="$cmd1 $cmd2 $cmd3"
19775
19776         rm -f ${TMP}/mds_survey*
19777         echo + $cmd
19778         eval $cmd || error "mds-survey with stripe_count failed"
19779         cat ${TMP}/mds_survey*
19780         rm -f ${TMP}/mds_survey*
19781 }
19782 run_test 225b "Metadata survey sanity with stripe_count = 1"
19783
19784 mcreate_path2fid () {
19785         local mode=$1
19786         local major=$2
19787         local minor=$3
19788         local name=$4
19789         local desc=$5
19790         local path=$DIR/$tdir/$name
19791         local fid
19792         local rc
19793         local fid_path
19794
19795         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19796                 error "cannot create $desc"
19797
19798         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19799         rc=$?
19800         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19801
19802         fid_path=$($LFS fid2path $MOUNT $fid)
19803         rc=$?
19804         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19805
19806         [ "$path" == "$fid_path" ] ||
19807                 error "fid2path returned $fid_path, expected $path"
19808
19809         echo "pass with $path and $fid"
19810 }
19811
19812 test_226a () {
19813         rm -rf $DIR/$tdir
19814         mkdir -p $DIR/$tdir
19815
19816         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19817         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19818         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19819         mcreate_path2fid 0040666 0 0 dir "directory"
19820         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19821         mcreate_path2fid 0100666 0 0 file "regular file"
19822         mcreate_path2fid 0120666 0 0 link "symbolic link"
19823         mcreate_path2fid 0140666 0 0 sock "socket"
19824 }
19825 run_test 226a "call path2fid and fid2path on files of all type"
19826
19827 test_226b () {
19828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19829
19830         local MDTIDX=1
19831
19832         rm -rf $DIR/$tdir
19833         mkdir -p $DIR/$tdir
19834         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19835                 error "create remote directory failed"
19836         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19837         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19838                                 "character special file (null)"
19839         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19840                                 "character special file (no device)"
19841         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19842         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19843                                 "block special file (loop)"
19844         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19845         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19846         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19847 }
19848 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19849
19850 test_226c () {
19851         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19852         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19853                 skip "Need MDS version at least 2.13.55"
19854
19855         local submnt=/mnt/submnt
19856         local srcfile=/etc/passwd
19857         local dstfile=$submnt/passwd
19858         local path
19859         local fid
19860
19861         rm -rf $DIR/$tdir
19862         rm -rf $submnt
19863         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19864                 error "create remote directory failed"
19865         mkdir -p $submnt || error "create $submnt failed"
19866         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19867                 error "mount $submnt failed"
19868         stack_trap "umount $submnt" EXIT
19869
19870         cp $srcfile $dstfile
19871         fid=$($LFS path2fid $dstfile)
19872         path=$($LFS fid2path $submnt "$fid")
19873         [ "$path" = "$dstfile" ] ||
19874                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19875 }
19876 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19877
19878 # LU-1299 Executing or running ldd on a truncated executable does not
19879 # cause an out-of-memory condition.
19880 test_227() {
19881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19882         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19883
19884         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19885         chmod +x $MOUNT/date
19886
19887         $MOUNT/date > /dev/null
19888         ldd $MOUNT/date > /dev/null
19889         rm -f $MOUNT/date
19890 }
19891 run_test 227 "running truncated executable does not cause OOM"
19892
19893 # LU-1512 try to reuse idle OI blocks
19894 test_228a() {
19895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19896         remote_mds_nodsh && skip "remote MDS with nodsh"
19897         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19898
19899         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19900         local myDIR=$DIR/$tdir
19901
19902         mkdir -p $myDIR
19903         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19904         $LCTL set_param fail_loc=0x80001002
19905         createmany -o $myDIR/t- 10000
19906         $LCTL set_param fail_loc=0
19907         # The guard is current the largest FID holder
19908         touch $myDIR/guard
19909         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19910                     tr -d '[')
19911         local IDX=$(($SEQ % 64))
19912
19913         do_facet $SINGLEMDS sync
19914         # Make sure journal flushed.
19915         sleep 6
19916         local blk1=$(do_facet $SINGLEMDS \
19917                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19918                      grep Blockcount | awk '{print $4}')
19919
19920         # Remove old files, some OI blocks will become idle.
19921         unlinkmany $myDIR/t- 10000
19922         # Create new files, idle OI blocks should be reused.
19923         createmany -o $myDIR/t- 2000
19924         do_facet $SINGLEMDS sync
19925         # Make sure journal flushed.
19926         sleep 6
19927         local blk2=$(do_facet $SINGLEMDS \
19928                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19929                      grep Blockcount | awk '{print $4}')
19930
19931         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19932 }
19933 run_test 228a "try to reuse idle OI blocks"
19934
19935 test_228b() {
19936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19937         remote_mds_nodsh && skip "remote MDS with nodsh"
19938         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19939
19940         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19941         local myDIR=$DIR/$tdir
19942
19943         mkdir -p $myDIR
19944         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19945         $LCTL set_param fail_loc=0x80001002
19946         createmany -o $myDIR/t- 10000
19947         $LCTL set_param fail_loc=0
19948         # The guard is current the largest FID holder
19949         touch $myDIR/guard
19950         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19951                     tr -d '[')
19952         local IDX=$(($SEQ % 64))
19953
19954         do_facet $SINGLEMDS sync
19955         # Make sure journal flushed.
19956         sleep 6
19957         local blk1=$(do_facet $SINGLEMDS \
19958                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19959                      grep Blockcount | awk '{print $4}')
19960
19961         # Remove old files, some OI blocks will become idle.
19962         unlinkmany $myDIR/t- 10000
19963
19964         # stop the MDT
19965         stop $SINGLEMDS || error "Fail to stop MDT."
19966         # remount the MDT
19967         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19968                 error "Fail to start MDT."
19969
19970         df $MOUNT || error "Fail to df."
19971         # Create new files, idle OI blocks should be reused.
19972         createmany -o $myDIR/t- 2000
19973         do_facet $SINGLEMDS sync
19974         # Make sure journal flushed.
19975         sleep 6
19976         local blk2=$(do_facet $SINGLEMDS \
19977                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19978                      grep Blockcount | awk '{print $4}')
19979
19980         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19981 }
19982 run_test 228b "idle OI blocks can be reused after MDT restart"
19983
19984 #LU-1881
19985 test_228c() {
19986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19987         remote_mds_nodsh && skip "remote MDS with nodsh"
19988         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19989
19990         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19991         local myDIR=$DIR/$tdir
19992
19993         mkdir -p $myDIR
19994         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19995         $LCTL set_param fail_loc=0x80001002
19996         # 20000 files can guarantee there are index nodes in the OI file
19997         createmany -o $myDIR/t- 20000
19998         $LCTL set_param fail_loc=0
19999         # The guard is current the largest FID holder
20000         touch $myDIR/guard
20001         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20002                     tr -d '[')
20003         local IDX=$(($SEQ % 64))
20004
20005         do_facet $SINGLEMDS sync
20006         # Make sure journal flushed.
20007         sleep 6
20008         local blk1=$(do_facet $SINGLEMDS \
20009                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20010                      grep Blockcount | awk '{print $4}')
20011
20012         # Remove old files, some OI blocks will become idle.
20013         unlinkmany $myDIR/t- 20000
20014         rm -f $myDIR/guard
20015         # The OI file should become empty now
20016
20017         # Create new files, idle OI blocks should be reused.
20018         createmany -o $myDIR/t- 2000
20019         do_facet $SINGLEMDS sync
20020         # Make sure journal flushed.
20021         sleep 6
20022         local blk2=$(do_facet $SINGLEMDS \
20023                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20024                      grep Blockcount | awk '{print $4}')
20025
20026         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20027 }
20028 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20029
20030 test_229() { # LU-2482, LU-3448
20031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20032         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20033         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20034                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20035
20036         rm -f $DIR/$tfile
20037
20038         # Create a file with a released layout and stripe count 2.
20039         $MULTIOP $DIR/$tfile H2c ||
20040                 error "failed to create file with released layout"
20041
20042         $LFS getstripe -v $DIR/$tfile
20043
20044         local pattern=$($LFS getstripe -L $DIR/$tfile)
20045         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20046
20047         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20048                 error "getstripe"
20049         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20050         stat $DIR/$tfile || error "failed to stat released file"
20051
20052         chown $RUNAS_ID $DIR/$tfile ||
20053                 error "chown $RUNAS_ID $DIR/$tfile failed"
20054
20055         chgrp $RUNAS_ID $DIR/$tfile ||
20056                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20057
20058         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20059         rm $DIR/$tfile || error "failed to remove released file"
20060 }
20061 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20062
20063 test_230a() {
20064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20066         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20067                 skip "Need MDS version at least 2.11.52"
20068
20069         local MDTIDX=1
20070
20071         test_mkdir $DIR/$tdir
20072         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20073         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20074         [ $mdt_idx -ne 0 ] &&
20075                 error "create local directory on wrong MDT $mdt_idx"
20076
20077         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20078                         error "create remote directory failed"
20079         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20080         [ $mdt_idx -ne $MDTIDX ] &&
20081                 error "create remote directory on wrong MDT $mdt_idx"
20082
20083         createmany -o $DIR/$tdir/test_230/t- 10 ||
20084                 error "create files on remote directory failed"
20085         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20086         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20087         rm -r $DIR/$tdir || error "unlink remote directory failed"
20088 }
20089 run_test 230a "Create remote directory and files under the remote directory"
20090
20091 test_230b() {
20092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20094         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20095                 skip "Need MDS version at least 2.11.52"
20096
20097         local MDTIDX=1
20098         local mdt_index
20099         local i
20100         local file
20101         local pid
20102         local stripe_count
20103         local migrate_dir=$DIR/$tdir/migrate_dir
20104         local other_dir=$DIR/$tdir/other_dir
20105
20106         test_mkdir $DIR/$tdir
20107         test_mkdir -i0 -c1 $migrate_dir
20108         test_mkdir -i0 -c1 $other_dir
20109         for ((i=0; i<10; i++)); do
20110                 mkdir -p $migrate_dir/dir_${i}
20111                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20112                         error "create files under remote dir failed $i"
20113         done
20114
20115         cp /etc/passwd $migrate_dir/$tfile
20116         cp /etc/passwd $other_dir/$tfile
20117         chattr +SAD $migrate_dir
20118         chattr +SAD $migrate_dir/$tfile
20119
20120         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20121         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20122         local old_dir_mode=$(stat -c%f $migrate_dir)
20123         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20124
20125         mkdir -p $migrate_dir/dir_default_stripe2
20126         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20127         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20128
20129         mkdir -p $other_dir
20130         ln $migrate_dir/$tfile $other_dir/luna
20131         ln $migrate_dir/$tfile $migrate_dir/sofia
20132         ln $other_dir/$tfile $migrate_dir/david
20133         ln -s $migrate_dir/$tfile $other_dir/zachary
20134         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20135         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20136
20137         local len
20138         local lnktgt
20139
20140         # inline symlink
20141         for len in 58 59 60; do
20142                 lnktgt=$(str_repeat 'l' $len)
20143                 touch $migrate_dir/$lnktgt
20144                 ln -s $lnktgt $migrate_dir/${len}char_ln
20145         done
20146
20147         # PATH_MAX
20148         for len in 4094 4095; do
20149                 lnktgt=$(str_repeat 'l' $len)
20150                 ln -s $lnktgt $migrate_dir/${len}char_ln
20151         done
20152
20153         # NAME_MAX
20154         for len in 254 255; do
20155                 touch $migrate_dir/$(str_repeat 'l' $len)
20156         done
20157
20158         $LFS migrate -m $MDTIDX $migrate_dir ||
20159                 error "fails on migrating remote dir to MDT1"
20160
20161         echo "migratate to MDT1, then checking.."
20162         for ((i = 0; i < 10; i++)); do
20163                 for file in $(find $migrate_dir/dir_${i}); do
20164                         mdt_index=$($LFS getstripe -m $file)
20165                         # broken symlink getstripe will fail
20166                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20167                                 error "$file is not on MDT${MDTIDX}"
20168                 done
20169         done
20170
20171         # the multiple link file should still in MDT0
20172         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20173         [ $mdt_index == 0 ] ||
20174                 error "$file is not on MDT${MDTIDX}"
20175
20176         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20177         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20178                 error " expect $old_dir_flag get $new_dir_flag"
20179
20180         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20181         [ "$old_file_flag" = "$new_file_flag" ] ||
20182                 error " expect $old_file_flag get $new_file_flag"
20183
20184         local new_dir_mode=$(stat -c%f $migrate_dir)
20185         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20186                 error "expect mode $old_dir_mode get $new_dir_mode"
20187
20188         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20189         [ "$old_file_mode" = "$new_file_mode" ] ||
20190                 error "expect mode $old_file_mode get $new_file_mode"
20191
20192         diff /etc/passwd $migrate_dir/$tfile ||
20193                 error "$tfile different after migration"
20194
20195         diff /etc/passwd $other_dir/luna ||
20196                 error "luna different after migration"
20197
20198         diff /etc/passwd $migrate_dir/sofia ||
20199                 error "sofia different after migration"
20200
20201         diff /etc/passwd $migrate_dir/david ||
20202                 error "david different after migration"
20203
20204         diff /etc/passwd $other_dir/zachary ||
20205                 error "zachary different after migration"
20206
20207         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20208                 error "${tfile}_ln different after migration"
20209
20210         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20211                 error "${tfile}_ln_other different after migration"
20212
20213         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20214         [ $stripe_count = 2 ] ||
20215                 error "dir strpe_count $d != 2 after migration."
20216
20217         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20218         [ $stripe_count = 2 ] ||
20219                 error "file strpe_count $d != 2 after migration."
20220
20221         #migrate back to MDT0
20222         MDTIDX=0
20223
20224         $LFS migrate -m $MDTIDX $migrate_dir ||
20225                 error "fails on migrating remote dir to MDT0"
20226
20227         echo "migrate back to MDT0, checking.."
20228         for file in $(find $migrate_dir); do
20229                 mdt_index=$($LFS getstripe -m $file)
20230                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20231                         error "$file is not on MDT${MDTIDX}"
20232         done
20233
20234         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20235         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20236                 error " expect $old_dir_flag get $new_dir_flag"
20237
20238         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20239         [ "$old_file_flag" = "$new_file_flag" ] ||
20240                 error " expect $old_file_flag get $new_file_flag"
20241
20242         local new_dir_mode=$(stat -c%f $migrate_dir)
20243         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20244                 error "expect mode $old_dir_mode get $new_dir_mode"
20245
20246         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20247         [ "$old_file_mode" = "$new_file_mode" ] ||
20248                 error "expect mode $old_file_mode get $new_file_mode"
20249
20250         diff /etc/passwd ${migrate_dir}/$tfile ||
20251                 error "$tfile different after migration"
20252
20253         diff /etc/passwd ${other_dir}/luna ||
20254                 error "luna different after migration"
20255
20256         diff /etc/passwd ${migrate_dir}/sofia ||
20257                 error "sofia different after migration"
20258
20259         diff /etc/passwd ${other_dir}/zachary ||
20260                 error "zachary different after migration"
20261
20262         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20263                 error "${tfile}_ln different after migration"
20264
20265         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20266                 error "${tfile}_ln_other different after migration"
20267
20268         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20269         [ $stripe_count = 2 ] ||
20270                 error "dir strpe_count $d != 2 after migration."
20271
20272         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20273         [ $stripe_count = 2 ] ||
20274                 error "file strpe_count $d != 2 after migration."
20275
20276         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20277 }
20278 run_test 230b "migrate directory"
20279
20280 test_230c() {
20281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20283         remote_mds_nodsh && skip "remote MDS with nodsh"
20284         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20285                 skip "Need MDS version at least 2.11.52"
20286
20287         local MDTIDX=1
20288         local total=3
20289         local mdt_index
20290         local file
20291         local migrate_dir=$DIR/$tdir/migrate_dir
20292
20293         #If migrating directory fails in the middle, all entries of
20294         #the directory is still accessiable.
20295         test_mkdir $DIR/$tdir
20296         test_mkdir -i0 -c1 $migrate_dir
20297         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20298         stat $migrate_dir
20299         createmany -o $migrate_dir/f $total ||
20300                 error "create files under ${migrate_dir} failed"
20301
20302         # fail after migrating top dir, and this will fail only once, so the
20303         # first sub file migration will fail (currently f3), others succeed.
20304         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20305         do_facet mds1 lctl set_param fail_loc=0x1801
20306         local t=$(ls $migrate_dir | wc -l)
20307         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20308                 error "migrate should fail"
20309         local u=$(ls $migrate_dir | wc -l)
20310         [ "$u" == "$t" ] || error "$u != $t during migration"
20311
20312         # add new dir/file should succeed
20313         mkdir $migrate_dir/dir ||
20314                 error "mkdir failed under migrating directory"
20315         touch $migrate_dir/file ||
20316                 error "create file failed under migrating directory"
20317
20318         # add file with existing name should fail
20319         for file in $migrate_dir/f*; do
20320                 stat $file > /dev/null || error "stat $file failed"
20321                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20322                         error "open(O_CREAT|O_EXCL) $file should fail"
20323                 $MULTIOP $file m && error "create $file should fail"
20324                 touch $DIR/$tdir/remote_dir/$tfile ||
20325                         error "touch $tfile failed"
20326                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20327                         error "link $file should fail"
20328                 mdt_index=$($LFS getstripe -m $file)
20329                 if [ $mdt_index == 0 ]; then
20330                         # file failed to migrate is not allowed to rename to
20331                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20332                                 error "rename to $file should fail"
20333                 else
20334                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20335                                 error "rename to $file failed"
20336                 fi
20337                 echo hello >> $file || error "write $file failed"
20338         done
20339
20340         # resume migration with different options should fail
20341         $LFS migrate -m 0 $migrate_dir &&
20342                 error "migrate -m 0 $migrate_dir should fail"
20343
20344         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20345                 error "migrate -c 2 $migrate_dir should fail"
20346
20347         # resume migration should succeed
20348         $LFS migrate -m $MDTIDX $migrate_dir ||
20349                 error "migrate $migrate_dir failed"
20350
20351         echo "Finish migration, then checking.."
20352         for file in $(find $migrate_dir); do
20353                 mdt_index=$($LFS getstripe -m $file)
20354                 [ $mdt_index == $MDTIDX ] ||
20355                         error "$file is not on MDT${MDTIDX}"
20356         done
20357
20358         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20359 }
20360 run_test 230c "check directory accessiblity if migration failed"
20361
20362 test_230d() {
20363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20365         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20366                 skip "Need MDS version at least 2.11.52"
20367         # LU-11235
20368         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20369
20370         local migrate_dir=$DIR/$tdir/migrate_dir
20371         local old_index
20372         local new_index
20373         local old_count
20374         local new_count
20375         local new_hash
20376         local mdt_index
20377         local i
20378         local j
20379
20380         old_index=$((RANDOM % MDSCOUNT))
20381         old_count=$((MDSCOUNT - old_index))
20382         new_index=$((RANDOM % MDSCOUNT))
20383         new_count=$((MDSCOUNT - new_index))
20384         new_hash=1 # for all_char
20385
20386         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20387         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20388
20389         test_mkdir $DIR/$tdir
20390         test_mkdir -i $old_index -c $old_count $migrate_dir
20391
20392         for ((i=0; i<100; i++)); do
20393                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20394                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20395                         error "create files under remote dir failed $i"
20396         done
20397
20398         echo -n "Migrate from MDT$old_index "
20399         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20400         echo -n "to MDT$new_index"
20401         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20402         echo
20403
20404         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20405         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20406                 error "migrate remote dir error"
20407
20408         echo "Finish migration, then checking.."
20409         for file in $(find $migrate_dir -maxdepth 1); do
20410                 mdt_index=$($LFS getstripe -m $file)
20411                 if [ $mdt_index -lt $new_index ] ||
20412                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20413                         error "$file is on MDT$mdt_index"
20414                 fi
20415         done
20416
20417         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20418 }
20419 run_test 230d "check migrate big directory"
20420
20421 test_230e() {
20422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20423         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20424         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20425                 skip "Need MDS version at least 2.11.52"
20426
20427         local i
20428         local j
20429         local a_fid
20430         local b_fid
20431
20432         mkdir_on_mdt0 $DIR/$tdir
20433         mkdir $DIR/$tdir/migrate_dir
20434         mkdir $DIR/$tdir/other_dir
20435         touch $DIR/$tdir/migrate_dir/a
20436         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20437         ls $DIR/$tdir/other_dir
20438
20439         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20440                 error "migrate dir fails"
20441
20442         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20443         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20444
20445         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20446         [ $mdt_index == 0 ] || error "a is not on MDT0"
20447
20448         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20449                 error "migrate dir fails"
20450
20451         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20452         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20453
20454         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20455         [ $mdt_index == 1 ] || error "a is not on MDT1"
20456
20457         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20458         [ $mdt_index == 1 ] || error "b is not on MDT1"
20459
20460         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20461         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20462
20463         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20464
20465         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20466 }
20467 run_test 230e "migrate mulitple local link files"
20468
20469 test_230f() {
20470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20472         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20473                 skip "Need MDS version at least 2.11.52"
20474
20475         local a_fid
20476         local ln_fid
20477
20478         mkdir -p $DIR/$tdir
20479         mkdir $DIR/$tdir/migrate_dir
20480         $LFS mkdir -i1 $DIR/$tdir/other_dir
20481         touch $DIR/$tdir/migrate_dir/a
20482         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20483         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20484         ls $DIR/$tdir/other_dir
20485
20486         # a should be migrated to MDT1, since no other links on MDT0
20487         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20488                 error "#1 migrate dir fails"
20489         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20490         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20491         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20492         [ $mdt_index == 1 ] || error "a is not on MDT1"
20493
20494         # a should stay on MDT1, because it is a mulitple link file
20495         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20496                 error "#2 migrate dir fails"
20497         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20498         [ $mdt_index == 1 ] || error "a is not on MDT1"
20499
20500         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20501                 error "#3 migrate dir fails"
20502
20503         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20504         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20505         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20506
20507         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20508         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20509
20510         # a should be migrated to MDT0, since no other links on MDT1
20511         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20512                 error "#4 migrate dir fails"
20513         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20514         [ $mdt_index == 0 ] || error "a is not on MDT0"
20515
20516         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20517 }
20518 run_test 230f "migrate mulitple remote link files"
20519
20520 test_230g() {
20521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20523         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20524                 skip "Need MDS version at least 2.11.52"
20525
20526         mkdir -p $DIR/$tdir/migrate_dir
20527
20528         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20529                 error "migrating dir to non-exist MDT succeeds"
20530         true
20531 }
20532 run_test 230g "migrate dir to non-exist MDT"
20533
20534 test_230h() {
20535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20537         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20538                 skip "Need MDS version at least 2.11.52"
20539
20540         local mdt_index
20541
20542         mkdir -p $DIR/$tdir/migrate_dir
20543
20544         $LFS migrate -m1 $DIR &&
20545                 error "migrating mountpoint1 should fail"
20546
20547         $LFS migrate -m1 $DIR/$tdir/.. &&
20548                 error "migrating mountpoint2 should fail"
20549
20550         # same as mv
20551         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20552                 error "migrating $tdir/migrate_dir/.. should fail"
20553
20554         true
20555 }
20556 run_test 230h "migrate .. and root"
20557
20558 test_230i() {
20559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20560         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20561         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20562                 skip "Need MDS version at least 2.11.52"
20563
20564         mkdir -p $DIR/$tdir/migrate_dir
20565
20566         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20567                 error "migration fails with a tailing slash"
20568
20569         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20570                 error "migration fails with two tailing slashes"
20571 }
20572 run_test 230i "lfs migrate -m tolerates trailing slashes"
20573
20574 test_230j() {
20575         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20576         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20577                 skip "Need MDS version at least 2.11.52"
20578
20579         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20580         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20581                 error "create $tfile failed"
20582         cat /etc/passwd > $DIR/$tdir/$tfile
20583
20584         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20585
20586         cmp /etc/passwd $DIR/$tdir/$tfile ||
20587                 error "DoM file mismatch after migration"
20588 }
20589 run_test 230j "DoM file data not changed after dir migration"
20590
20591 test_230k() {
20592         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20593         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20594                 skip "Need MDS version at least 2.11.56"
20595
20596         local total=20
20597         local files_on_starting_mdt=0
20598
20599         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20600         $LFS getdirstripe $DIR/$tdir
20601         for i in $(seq $total); do
20602                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20603                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20604                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20605         done
20606
20607         echo "$files_on_starting_mdt files on MDT0"
20608
20609         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20610         $LFS getdirstripe $DIR/$tdir
20611
20612         files_on_starting_mdt=0
20613         for i in $(seq $total); do
20614                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20615                         error "file $tfile.$i mismatch after migration"
20616                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20617                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20618         done
20619
20620         echo "$files_on_starting_mdt files on MDT1 after migration"
20621         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20622
20623         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20624         $LFS getdirstripe $DIR/$tdir
20625
20626         files_on_starting_mdt=0
20627         for i in $(seq $total); do
20628                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20629                         error "file $tfile.$i mismatch after 2nd migration"
20630                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20631                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20632         done
20633
20634         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20635         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20636
20637         true
20638 }
20639 run_test 230k "file data not changed after dir migration"
20640
20641 test_230l() {
20642         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20643         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20644                 skip "Need MDS version at least 2.11.56"
20645
20646         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20647         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20648                 error "create files under remote dir failed $i"
20649         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20650 }
20651 run_test 230l "readdir between MDTs won't crash"
20652
20653 test_230m() {
20654         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20655         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20656                 skip "Need MDS version at least 2.11.56"
20657
20658         local MDTIDX=1
20659         local mig_dir=$DIR/$tdir/migrate_dir
20660         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20661         local shortstr="b"
20662         local val
20663
20664         echo "Creating files and dirs with xattrs"
20665         test_mkdir $DIR/$tdir
20666         test_mkdir -i0 -c1 $mig_dir
20667         mkdir $mig_dir/dir
20668         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20669                 error "cannot set xattr attr1 on dir"
20670         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20671                 error "cannot set xattr attr2 on dir"
20672         touch $mig_dir/dir/f0
20673         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20674                 error "cannot set xattr attr1 on file"
20675         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20676                 error "cannot set xattr attr2 on file"
20677         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20678         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20679         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20680         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20681         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20682         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20683         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20684         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20685         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20686
20687         echo "Migrating to MDT1"
20688         $LFS migrate -m $MDTIDX $mig_dir ||
20689                 error "fails on migrating dir to MDT1"
20690
20691         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20692         echo "Checking xattrs"
20693         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20694         [ "$val" = $longstr ] ||
20695                 error "expecting xattr1 $longstr on dir, found $val"
20696         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20697         [ "$val" = $shortstr ] ||
20698                 error "expecting xattr2 $shortstr on dir, found $val"
20699         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20700         [ "$val" = $longstr ] ||
20701                 error "expecting xattr1 $longstr on file, found $val"
20702         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20703         [ "$val" = $shortstr ] ||
20704                 error "expecting xattr2 $shortstr on file, found $val"
20705 }
20706 run_test 230m "xattrs not changed after dir migration"
20707
20708 test_230n() {
20709         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20710         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20711                 skip "Need MDS version at least 2.13.53"
20712
20713         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20714         cat /etc/hosts > $DIR/$tdir/$tfile
20715         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20716         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20717
20718         cmp /etc/hosts $DIR/$tdir/$tfile ||
20719                 error "File data mismatch after migration"
20720 }
20721 run_test 230n "Dir migration with mirrored file"
20722
20723 test_230o() {
20724         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20725         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20726                 skip "Need MDS version at least 2.13.52"
20727
20728         local mdts=$(comma_list $(mdts_nodes))
20729         local timeout=100
20730         local restripe_status
20731         local delta
20732         local i
20733
20734         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20735
20736         # in case "crush" hash type is not set
20737         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20738
20739         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20740                            mdt.*MDT0000.enable_dir_restripe)
20741         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20742         stack_trap "do_nodes $mdts $LCTL set_param \
20743                     mdt.*.enable_dir_restripe=$restripe_status"
20744
20745         mkdir $DIR/$tdir
20746         createmany -m $DIR/$tdir/f 100 ||
20747                 error "create files under remote dir failed $i"
20748         createmany -d $DIR/$tdir/d 100 ||
20749                 error "create dirs under remote dir failed $i"
20750
20751         for i in $(seq 2 $MDSCOUNT); do
20752                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20753                 $LFS setdirstripe -c $i $DIR/$tdir ||
20754                         error "split -c $i $tdir failed"
20755                 wait_update $HOSTNAME \
20756                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20757                         error "dir split not finished"
20758                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20759                         awk '/migrate/ {sum += $2} END { print sum }')
20760                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20761                 # delta is around total_files/stripe_count
20762                 (( $delta < 200 / (i - 1) + 4 )) ||
20763                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20764         done
20765 }
20766 run_test 230o "dir split"
20767
20768 test_230p() {
20769         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20770         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20771                 skip "Need MDS version at least 2.13.52"
20772
20773         local mdts=$(comma_list $(mdts_nodes))
20774         local timeout=100
20775         local restripe_status
20776         local delta
20777         local c
20778
20779         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20780
20781         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20782
20783         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20784                            mdt.*MDT0000.enable_dir_restripe)
20785         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20786         stack_trap "do_nodes $mdts $LCTL set_param \
20787                     mdt.*.enable_dir_restripe=$restripe_status"
20788
20789         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20790         createmany -m $DIR/$tdir/f 100 ||
20791                 error "create files under remote dir failed"
20792         createmany -d $DIR/$tdir/d 100 ||
20793                 error "create dirs under remote dir failed"
20794
20795         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20796                 local mdt_hash="crush"
20797
20798                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20799                 $LFS setdirstripe -c $c $DIR/$tdir ||
20800                         error "split -c $c $tdir failed"
20801                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20802                         mdt_hash="$mdt_hash,fixed"
20803                 elif [ $c -eq 1 ]; then
20804                         mdt_hash="none"
20805                 fi
20806                 wait_update $HOSTNAME \
20807                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20808                         error "dir merge not finished"
20809                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20810                         awk '/migrate/ {sum += $2} END { print sum }')
20811                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20812                 # delta is around total_files/stripe_count
20813                 (( delta < 200 / c + 4 )) ||
20814                         error "$delta files migrated >= $((200 / c + 4))"
20815         done
20816 }
20817 run_test 230p "dir merge"
20818
20819 test_230q() {
20820         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20821         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20822                 skip "Need MDS version at least 2.13.52"
20823
20824         local mdts=$(comma_list $(mdts_nodes))
20825         local saved_threshold=$(do_facet mds1 \
20826                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20827         local saved_delta=$(do_facet mds1 \
20828                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20829         local threshold=100
20830         local delta=2
20831         local total=0
20832         local stripe_count=0
20833         local stripe_index
20834         local nr_files
20835         local create
20836
20837         # test with fewer files on ZFS
20838         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20839
20840         stack_trap "do_nodes $mdts $LCTL set_param \
20841                     mdt.*.dir_split_count=$saved_threshold"
20842         stack_trap "do_nodes $mdts $LCTL set_param \
20843                     mdt.*.dir_split_delta=$saved_delta"
20844         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20845         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20846         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20847         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20848         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20849         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20850
20851         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20852         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20853
20854         create=$((threshold * 3 / 2))
20855         while [ $stripe_count -lt $MDSCOUNT ]; do
20856                 createmany -m $DIR/$tdir/f $total $create ||
20857                         error "create sub files failed"
20858                 stat $DIR/$tdir > /dev/null
20859                 total=$((total + create))
20860                 stripe_count=$((stripe_count + delta))
20861                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20862
20863                 wait_update $HOSTNAME \
20864                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20865                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20866
20867                 wait_update $HOSTNAME \
20868                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20869                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20870
20871                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20872                 echo "$nr_files/$total files on MDT$stripe_index after split"
20873                 # allow 10% margin of imbalance with crush hash
20874                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20875                         error "$nr_files files on MDT$stripe_index after split"
20876
20877                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20878                 [ $nr_files -eq $total ] ||
20879                         error "total sub files $nr_files != $total"
20880         done
20881
20882         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20883
20884         echo "fixed layout directory won't auto split"
20885         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20886         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20887                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20888         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20889                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20890 }
20891 run_test 230q "dir auto split"
20892
20893 test_230r() {
20894         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20895         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20896         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20897                 skip "Need MDS version at least 2.13.54"
20898
20899         # maximum amount of local locks:
20900         # parent striped dir - 2 locks
20901         # new stripe in parent to migrate to - 1 lock
20902         # source and target - 2 locks
20903         # Total 5 locks for regular file
20904         mkdir -p $DIR/$tdir
20905         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20906         touch $DIR/$tdir/dir1/eee
20907
20908         # create 4 hardlink for 4 more locks
20909         # Total: 9 locks > RS_MAX_LOCKS (8)
20910         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20911         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20912         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20913         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20914         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20915         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20916         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20917         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20918
20919         cancel_lru_locks mdc
20920
20921         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20922                 error "migrate dir fails"
20923
20924         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20925 }
20926 run_test 230r "migrate with too many local locks"
20927
20928 test_230s() {
20929         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20930                 skip "Need MDS version at least 2.14.52"
20931
20932         local mdts=$(comma_list $(mdts_nodes))
20933         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20934                                 mdt.*MDT0000.enable_dir_restripe)
20935
20936         stack_trap "do_nodes $mdts $LCTL set_param \
20937                     mdt.*.enable_dir_restripe=$restripe_status"
20938
20939         local st
20940         for st in 0 1; do
20941                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20942                 test_mkdir $DIR/$tdir
20943                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20944                         error "$LFS mkdir should return EEXIST if target exists"
20945                 rmdir $DIR/$tdir
20946         done
20947 }
20948 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20949
20950 test_230t()
20951 {
20952         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20953         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20954                 skip "Need MDS version at least 2.14.50"
20955
20956         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20957         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20958         $LFS project -p 1 -s $DIR/$tdir ||
20959                 error "set $tdir project id failed"
20960         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20961                 error "set subdir project id failed"
20962         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20963 }
20964 run_test 230t "migrate directory with project ID set"
20965
20966 test_230u()
20967 {
20968         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20969         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20970                 skip "Need MDS version at least 2.14.53"
20971
20972         local count
20973
20974         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20975         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20976         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20977         for i in $(seq 0 $((MDSCOUNT - 1))); do
20978                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20979                 echo "$count dirs migrated to MDT$i"
20980         done
20981         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20982         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20983 }
20984 run_test 230u "migrate directory by QOS"
20985
20986 test_230v()
20987 {
20988         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20989         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20990                 skip "Need MDS version at least 2.14.53"
20991
20992         local count
20993
20994         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20995         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20996         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20997         for i in $(seq 0 $((MDSCOUNT - 1))); do
20998                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20999                 echo "$count subdirs migrated to MDT$i"
21000                 (( i == 3 )) && (( count > 0 )) &&
21001                         error "subdir shouldn't be migrated to MDT3"
21002         done
21003         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21004         (( count == 3 )) || error "dirs migrated to $count MDTs"
21005 }
21006 run_test 230v "subdir migrated to the MDT where its parent is located"
21007
21008 test_230w() {
21009         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21010         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21011                 skip "Need MDS version at least 2.15.0"
21012
21013         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21014         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21015         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21016
21017         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21018                 error "migrate failed"
21019
21020         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21021                 error "$tdir stripe count mismatch"
21022
21023         for i in $(seq 0 9); do
21024                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21025                         error "d$i is striped"
21026         done
21027 }
21028 run_test 230w "non-recursive mode dir migration"
21029
21030 test_231a()
21031 {
21032         # For simplicity this test assumes that max_pages_per_rpc
21033         # is the same across all OSCs
21034         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21035         local bulk_size=$((max_pages * PAGE_SIZE))
21036         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21037                                        head -n 1)
21038
21039         mkdir -p $DIR/$tdir
21040         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21041                 error "failed to set stripe with -S ${brw_size}M option"
21042
21043         # clear the OSC stats
21044         $LCTL set_param osc.*.stats=0 &>/dev/null
21045         stop_writeback
21046
21047         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21048         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21049                 oflag=direct &>/dev/null || error "dd failed"
21050
21051         sync; sleep 1; sync # just to be safe
21052         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21053         if [ x$nrpcs != "x1" ]; then
21054                 $LCTL get_param osc.*.stats
21055                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21056         fi
21057
21058         start_writeback
21059         # Drop the OSC cache, otherwise we will read from it
21060         cancel_lru_locks osc
21061
21062         # clear the OSC stats
21063         $LCTL set_param osc.*.stats=0 &>/dev/null
21064
21065         # Client reads $bulk_size.
21066         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21067                 iflag=direct &>/dev/null || error "dd failed"
21068
21069         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21070         if [ x$nrpcs != "x1" ]; then
21071                 $LCTL get_param osc.*.stats
21072                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21073         fi
21074 }
21075 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21076
21077 test_231b() {
21078         mkdir -p $DIR/$tdir
21079         local i
21080         for i in {0..1023}; do
21081                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21082                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21083                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21084         done
21085         sync
21086 }
21087 run_test 231b "must not assert on fully utilized OST request buffer"
21088
21089 test_232a() {
21090         mkdir -p $DIR/$tdir
21091         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21092
21093         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21094         do_facet ost1 $LCTL set_param fail_loc=0x31c
21095
21096         # ignore dd failure
21097         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21098
21099         do_facet ost1 $LCTL set_param fail_loc=0
21100         umount_client $MOUNT || error "umount failed"
21101         mount_client $MOUNT || error "mount failed"
21102         stop ost1 || error "cannot stop ost1"
21103         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21104 }
21105 run_test 232a "failed lock should not block umount"
21106
21107 test_232b() {
21108         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21109                 skip "Need MDS version at least 2.10.58"
21110
21111         mkdir -p $DIR/$tdir
21112         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21113         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21114         sync
21115         cancel_lru_locks osc
21116
21117         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21118         do_facet ost1 $LCTL set_param fail_loc=0x31c
21119
21120         # ignore failure
21121         $LFS data_version $DIR/$tdir/$tfile || true
21122
21123         do_facet ost1 $LCTL set_param fail_loc=0
21124         umount_client $MOUNT || error "umount failed"
21125         mount_client $MOUNT || error "mount failed"
21126         stop ost1 || error "cannot stop ost1"
21127         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21128 }
21129 run_test 232b "failed data version lock should not block umount"
21130
21131 test_233a() {
21132         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21133                 skip "Need MDS version at least 2.3.64"
21134         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21135
21136         local fid=$($LFS path2fid $MOUNT)
21137
21138         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21139                 error "cannot access $MOUNT using its FID '$fid'"
21140 }
21141 run_test 233a "checking that OBF of the FS root succeeds"
21142
21143 test_233b() {
21144         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21145                 skip "Need MDS version at least 2.5.90"
21146         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21147
21148         local fid=$($LFS path2fid $MOUNT/.lustre)
21149
21150         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21151                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21152
21153         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21154         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21155                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21156 }
21157 run_test 233b "checking that OBF of the FS .lustre succeeds"
21158
21159 test_234() {
21160         local p="$TMP/sanityN-$TESTNAME.parameters"
21161         save_lustre_params client "llite.*.xattr_cache" > $p
21162         lctl set_param llite.*.xattr_cache 1 ||
21163                 skip_env "xattr cache is not supported"
21164
21165         mkdir -p $DIR/$tdir || error "mkdir failed"
21166         touch $DIR/$tdir/$tfile || error "touch failed"
21167         # OBD_FAIL_LLITE_XATTR_ENOMEM
21168         $LCTL set_param fail_loc=0x1405
21169         getfattr -n user.attr $DIR/$tdir/$tfile &&
21170                 error "getfattr should have failed with ENOMEM"
21171         $LCTL set_param fail_loc=0x0
21172         rm -rf $DIR/$tdir
21173
21174         restore_lustre_params < $p
21175         rm -f $p
21176 }
21177 run_test 234 "xattr cache should not crash on ENOMEM"
21178
21179 test_235() {
21180         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21181                 skip "Need MDS version at least 2.4.52"
21182
21183         flock_deadlock $DIR/$tfile
21184         local RC=$?
21185         case $RC in
21186                 0)
21187                 ;;
21188                 124) error "process hangs on a deadlock"
21189                 ;;
21190                 *) error "error executing flock_deadlock $DIR/$tfile"
21191                 ;;
21192         esac
21193 }
21194 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21195
21196 #LU-2935
21197 test_236() {
21198         check_swap_layouts_support
21199
21200         local ref1=/etc/passwd
21201         local ref2=/etc/group
21202         local file1=$DIR/$tdir/f1
21203         local file2=$DIR/$tdir/f2
21204
21205         test_mkdir -c1 $DIR/$tdir
21206         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21207         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21208         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21209         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21210         local fd=$(free_fd)
21211         local cmd="exec $fd<>$file2"
21212         eval $cmd
21213         rm $file2
21214         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21215                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21216         cmd="exec $fd>&-"
21217         eval $cmd
21218         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21219
21220         #cleanup
21221         rm -rf $DIR/$tdir
21222 }
21223 run_test 236 "Layout swap on open unlinked file"
21224
21225 # LU-4659 linkea consistency
21226 test_238() {
21227         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21228                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21229                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21230                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21231
21232         touch $DIR/$tfile
21233         ln $DIR/$tfile $DIR/$tfile.lnk
21234         touch $DIR/$tfile.new
21235         mv $DIR/$tfile.new $DIR/$tfile
21236         local fid1=$($LFS path2fid $DIR/$tfile)
21237         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21238         local path1=$($LFS fid2path $FSNAME "$fid1")
21239         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21240         local path2=$($LFS fid2path $FSNAME "$fid2")
21241         [ $tfile.lnk == $path2 ] ||
21242                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21243         rm -f $DIR/$tfile*
21244 }
21245 run_test 238 "Verify linkea consistency"
21246
21247 test_239A() { # was test_239
21248         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21249                 skip "Need MDS version at least 2.5.60"
21250
21251         local list=$(comma_list $(mdts_nodes))
21252
21253         mkdir -p $DIR/$tdir
21254         createmany -o $DIR/$tdir/f- 5000
21255         unlinkmany $DIR/$tdir/f- 5000
21256         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21257                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21258         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21259                         osp.*MDT*.sync_in_flight" | calc_sum)
21260         [ "$changes" -eq 0 ] || error "$changes not synced"
21261 }
21262 run_test 239A "osp_sync test"
21263
21264 test_239a() { #LU-5297
21265         remote_mds_nodsh && skip "remote MDS with nodsh"
21266
21267         touch $DIR/$tfile
21268         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21269         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21270         chgrp $RUNAS_GID $DIR/$tfile
21271         wait_delete_completed
21272 }
21273 run_test 239a "process invalid osp sync record correctly"
21274
21275 test_239b() { #LU-5297
21276         remote_mds_nodsh && skip "remote MDS with nodsh"
21277
21278         touch $DIR/$tfile1
21279         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21280         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21281         chgrp $RUNAS_GID $DIR/$tfile1
21282         wait_delete_completed
21283         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21284         touch $DIR/$tfile2
21285         chgrp $RUNAS_GID $DIR/$tfile2
21286         wait_delete_completed
21287 }
21288 run_test 239b "process osp sync record with ENOMEM error correctly"
21289
21290 test_240() {
21291         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21292         remote_mds_nodsh && skip "remote MDS with nodsh"
21293
21294         mkdir -p $DIR/$tdir
21295
21296         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21297                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21298         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21299                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21300
21301         umount_client $MOUNT || error "umount failed"
21302         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21303         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21304         mount_client $MOUNT || error "failed to mount client"
21305
21306         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21307         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21308 }
21309 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21310
21311 test_241_bio() {
21312         local count=$1
21313         local bsize=$2
21314
21315         for LOOP in $(seq $count); do
21316                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21317                 cancel_lru_locks $OSC || true
21318         done
21319 }
21320
21321 test_241_dio() {
21322         local count=$1
21323         local bsize=$2
21324
21325         for LOOP in $(seq $1); do
21326                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21327                         2>/dev/null
21328         done
21329 }
21330
21331 test_241a() { # was test_241
21332         local bsize=$PAGE_SIZE
21333
21334         (( bsize < 40960 )) && bsize=40960
21335         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21336         ls -la $DIR/$tfile
21337         cancel_lru_locks $OSC
21338         test_241_bio 1000 $bsize &
21339         PID=$!
21340         test_241_dio 1000 $bsize
21341         wait $PID
21342 }
21343 run_test 241a "bio vs dio"
21344
21345 test_241b() {
21346         local bsize=$PAGE_SIZE
21347
21348         (( bsize < 40960 )) && bsize=40960
21349         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21350         ls -la $DIR/$tfile
21351         test_241_dio 1000 $bsize &
21352         PID=$!
21353         test_241_dio 1000 $bsize
21354         wait $PID
21355 }
21356 run_test 241b "dio vs dio"
21357
21358 test_242() {
21359         remote_mds_nodsh && skip "remote MDS with nodsh"
21360
21361         mkdir_on_mdt0 $DIR/$tdir
21362         touch $DIR/$tdir/$tfile
21363
21364         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21365         do_facet mds1 lctl set_param fail_loc=0x105
21366         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21367
21368         do_facet mds1 lctl set_param fail_loc=0
21369         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21370 }
21371 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21372
21373 test_243()
21374 {
21375         test_mkdir $DIR/$tdir
21376         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21377 }
21378 run_test 243 "various group lock tests"
21379
21380 test_244a()
21381 {
21382         test_mkdir $DIR/$tdir
21383         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21384         sendfile_grouplock $DIR/$tdir/$tfile || \
21385                 error "sendfile+grouplock failed"
21386         rm -rf $DIR/$tdir
21387 }
21388 run_test 244a "sendfile with group lock tests"
21389
21390 test_grouplock_244()
21391 {
21392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21393
21394         local threads=50
21395         local size=$((1024*1024))
21396
21397         for i in $(seq 1 $threads); do
21398                 local file=$DIR/$tdir/file_$((i / 10))
21399                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21400                 local pids[$i]=$!
21401         done
21402         for i in $(seq 1 $threads); do
21403                 wait ${pids[$i]}
21404         done
21405
21406 }
21407
21408 test_244b()
21409 {
21410         test_mkdir $DIR/$tdir
21411         $LFS setstripe -E 10M -E -1 -c 1 $DIR/$tdir
21412         test_grouplock_244
21413 }
21414 run_test 244b "multi-threaded write with group lock"
21415
21416 test_244c()
21417 {
21418         test_mkdir $DIR/$tdir
21419         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $DIR/$tdir
21420         test_grouplock_244
21421 }
21422 run_test 244c "multi-threaded write with group lock on DOM file"
21423
21424 test_245a() {
21425         local flagname="multi_mod_rpcs"
21426         local connect_data_name="max_mod_rpcs"
21427         local out
21428
21429         # check if multiple modify RPCs flag is set
21430         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21431                 grep "connect_flags:")
21432         echo "$out"
21433
21434         echo "$out" | grep -qw $flagname
21435         if [ $? -ne 0 ]; then
21436                 echo "connect flag $flagname is not set"
21437                 return
21438         fi
21439
21440         # check if multiple modify RPCs data is set
21441         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21442         echo "$out"
21443
21444         echo "$out" | grep -qw $connect_data_name ||
21445                 error "import should have connect data $connect_data_name"
21446 }
21447 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21448
21449 test_245b() {
21450         local flagname="multi_mod_rpcs"
21451         local connect_data_name="max_mod_rpcs"
21452         local out
21453
21454         remote_mds_nodsh && skip "remote MDS with nodsh"
21455         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21456
21457         # check if multiple modify RPCs flag is set
21458         out=$(do_facet mds1 \
21459               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21460               grep "connect_flags:")
21461         echo "$out"
21462
21463         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21464
21465         # check if multiple modify RPCs data is set
21466         out=$(do_facet mds1 \
21467               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21468
21469         [[ "$out" =~ $connect_data_name ]] ||
21470                 {
21471                         echo "$out"
21472                         error "missing connect data $connect_data_name"
21473                 }
21474 }
21475 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21476
21477 cleanup_247() {
21478         local submount=$1
21479
21480         trap 0
21481         umount_client $submount
21482         rmdir $submount
21483 }
21484
21485 test_247a() {
21486         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21487                 grep -q subtree ||
21488                 skip_env "Fileset feature is not supported"
21489
21490         local submount=${MOUNT}_$tdir
21491
21492         mkdir $MOUNT/$tdir
21493         mkdir -p $submount || error "mkdir $submount failed"
21494         FILESET="$FILESET/$tdir" mount_client $submount ||
21495                 error "mount $submount failed"
21496         trap "cleanup_247 $submount" EXIT
21497         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21498         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21499                 error "read $MOUNT/$tdir/$tfile failed"
21500         cleanup_247 $submount
21501 }
21502 run_test 247a "mount subdir as fileset"
21503
21504 test_247b() {
21505         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21506                 skip_env "Fileset feature is not supported"
21507
21508         local submount=${MOUNT}_$tdir
21509
21510         rm -rf $MOUNT/$tdir
21511         mkdir -p $submount || error "mkdir $submount failed"
21512         SKIP_FILESET=1
21513         FILESET="$FILESET/$tdir" mount_client $submount &&
21514                 error "mount $submount should fail"
21515         rmdir $submount
21516 }
21517 run_test 247b "mount subdir that dose not exist"
21518
21519 test_247c() {
21520         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21521                 skip_env "Fileset feature is not supported"
21522
21523         local submount=${MOUNT}_$tdir
21524
21525         mkdir -p $MOUNT/$tdir/dir1
21526         mkdir -p $submount || error "mkdir $submount failed"
21527         trap "cleanup_247 $submount" EXIT
21528         FILESET="$FILESET/$tdir" mount_client $submount ||
21529                 error "mount $submount failed"
21530         local fid=$($LFS path2fid $MOUNT/)
21531         $LFS fid2path $submount $fid && error "fid2path should fail"
21532         cleanup_247 $submount
21533 }
21534 run_test 247c "running fid2path outside subdirectory root"
21535
21536 test_247d() {
21537         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21538                 skip "Fileset feature is not supported"
21539
21540         local submount=${MOUNT}_$tdir
21541
21542         mkdir -p $MOUNT/$tdir/dir1
21543         mkdir -p $submount || error "mkdir $submount failed"
21544         FILESET="$FILESET/$tdir" mount_client $submount ||
21545                 error "mount $submount failed"
21546         trap "cleanup_247 $submount" EXIT
21547
21548         local td=$submount/dir1
21549         local fid=$($LFS path2fid $td)
21550         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21551
21552         # check that we get the same pathname back
21553         local rootpath
21554         local found
21555         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21556                 echo "$rootpath $fid"
21557                 found=$($LFS fid2path $rootpath "$fid")
21558                 [ -n "$found" ] || error "fid2path should succeed"
21559                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21560         done
21561         # check wrong root path format
21562         rootpath=$submount"_wrong"
21563         found=$($LFS fid2path $rootpath "$fid")
21564         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21565
21566         cleanup_247 $submount
21567 }
21568 run_test 247d "running fid2path inside subdirectory root"
21569
21570 # LU-8037
21571 test_247e() {
21572         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21573                 grep -q subtree ||
21574                 skip "Fileset feature is not supported"
21575
21576         local submount=${MOUNT}_$tdir
21577
21578         mkdir $MOUNT/$tdir
21579         mkdir -p $submount || error "mkdir $submount failed"
21580         FILESET="$FILESET/.." mount_client $submount &&
21581                 error "mount $submount should fail"
21582         rmdir $submount
21583 }
21584 run_test 247e "mount .. as fileset"
21585
21586 test_247f() {
21587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21588         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21589                 skip "Need at least version 2.13.52"
21590         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21591                 skip "Need at least version 2.14.50"
21592         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21593                 grep -q subtree ||
21594                 skip "Fileset feature is not supported"
21595
21596         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21597         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21598                 error "mkdir remote failed"
21599         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21600                 error "mkdir remote/subdir failed"
21601         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21602                 error "mkdir striped failed"
21603         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21604
21605         local submount=${MOUNT}_$tdir
21606
21607         mkdir -p $submount || error "mkdir $submount failed"
21608         stack_trap "rmdir $submount"
21609
21610         local dir
21611         local stat
21612         local fileset=$FILESET
21613         local mdts=$(comma_list $(mdts_nodes))
21614
21615         stat=$(do_facet mds1 $LCTL get_param -n \
21616                 mdt.*MDT0000.enable_remote_subdir_mount)
21617         stack_trap "do_nodes $mdts $LCTL set_param \
21618                 mdt.*.enable_remote_subdir_mount=$stat"
21619
21620         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21621         stack_trap "umount_client $submount"
21622         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21623                 error "mount remote dir $dir should fail"
21624
21625         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21626                 $tdir/striped/. ; do
21627                 FILESET="$fileset/$dir" mount_client $submount ||
21628                         error "mount $dir failed"
21629                 umount_client $submount
21630         done
21631
21632         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21633         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21634                 error "mount $tdir/remote failed"
21635 }
21636 run_test 247f "mount striped or remote directory as fileset"
21637
21638 test_247g() {
21639         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21640         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21641                 skip "Need at least version 2.14.50"
21642
21643         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21644                 error "mkdir $tdir failed"
21645         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21646
21647         local submount=${MOUNT}_$tdir
21648
21649         mkdir -p $submount || error "mkdir $submount failed"
21650         stack_trap "rmdir $submount"
21651
21652         FILESET="$fileset/$tdir" mount_client $submount ||
21653                 error "mount $dir failed"
21654         stack_trap "umount $submount"
21655
21656         local mdts=$(comma_list $(mdts_nodes))
21657
21658         local nrpcs
21659
21660         stat $submount > /dev/null
21661         cancel_lru_locks $MDC
21662         stat $submount > /dev/null
21663         stat $submount/$tfile > /dev/null
21664         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21665         stat $submount/$tfile > /dev/null
21666         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21667                 awk '/getattr/ {sum += $2} END {print sum}')
21668
21669         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21670 }
21671 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21672
21673 test_248a() {
21674         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21675         [ -z "$fast_read_sav" ] && skip "no fast read support"
21676
21677         # create a large file for fast read verification
21678         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21679
21680         # make sure the file is created correctly
21681         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21682                 { rm -f $DIR/$tfile; skip "file creation error"; }
21683
21684         echo "Test 1: verify that fast read is 4 times faster on cache read"
21685
21686         # small read with fast read enabled
21687         $LCTL set_param -n llite.*.fast_read=1
21688         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21689                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21690                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21691         # small read with fast read disabled
21692         $LCTL set_param -n llite.*.fast_read=0
21693         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21694                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21695                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21696
21697         # verify that fast read is 4 times faster for cache read
21698         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21699                 error_not_in_vm "fast read was not 4 times faster: " \
21700                            "$t_fast vs $t_slow"
21701
21702         echo "Test 2: verify the performance between big and small read"
21703         $LCTL set_param -n llite.*.fast_read=1
21704
21705         # 1k non-cache read
21706         cancel_lru_locks osc
21707         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21708                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21709                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21710
21711         # 1M non-cache read
21712         cancel_lru_locks osc
21713         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21714                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21715                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21716
21717         # verify that big IO is not 4 times faster than small IO
21718         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21719                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21720
21721         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21722         rm -f $DIR/$tfile
21723 }
21724 run_test 248a "fast read verification"
21725
21726 test_248b() {
21727         # Default short_io_bytes=16384, try both smaller and larger sizes.
21728         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21729         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21730         echo "bs=53248 count=113 normal buffered write"
21731         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21732                 error "dd of initial data file failed"
21733         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21734
21735         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21736         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21737                 error "dd with sync normal writes failed"
21738         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21739
21740         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21741         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21742                 error "dd with sync small writes failed"
21743         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21744
21745         cancel_lru_locks osc
21746
21747         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21748         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21749         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21750         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21751                 iflag=direct || error "dd with O_DIRECT small read failed"
21752         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21753         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21754                 error "compare $TMP/$tfile.1 failed"
21755
21756         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21757         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21758
21759         # just to see what the maximum tunable value is, and test parsing
21760         echo "test invalid parameter 2MB"
21761         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21762                 error "too-large short_io_bytes allowed"
21763         echo "test maximum parameter 512KB"
21764         # if we can set a larger short_io_bytes, run test regardless of version
21765         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21766                 # older clients may not allow setting it this large, that's OK
21767                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21768                         skip "Need at least client version 2.13.50"
21769                 error "medium short_io_bytes failed"
21770         fi
21771         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21772         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21773
21774         echo "test large parameter 64KB"
21775         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21776         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21777
21778         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21779         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21780                 error "dd with sync large writes failed"
21781         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21782
21783         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21784         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21785         num=$((113 * 4096 / PAGE_SIZE))
21786         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21787         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21788                 error "dd with O_DIRECT large writes failed"
21789         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21790                 error "compare $DIR/$tfile.3 failed"
21791
21792         cancel_lru_locks osc
21793
21794         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21795         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21796                 error "dd with O_DIRECT large read failed"
21797         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21798                 error "compare $TMP/$tfile.2 failed"
21799
21800         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21801         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21802                 error "dd with O_DIRECT large read failed"
21803         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21804                 error "compare $TMP/$tfile.3 failed"
21805 }
21806 run_test 248b "test short_io read and write for both small and large sizes"
21807
21808 test_249() { # LU-7890
21809         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21810                 skip "Need at least version 2.8.54"
21811
21812         rm -f $DIR/$tfile
21813         $LFS setstripe -c 1 $DIR/$tfile
21814         # Offset 2T == 4k * 512M
21815         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21816                 error "dd to 2T offset failed"
21817 }
21818 run_test 249 "Write above 2T file size"
21819
21820 test_250() {
21821         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21822          && skip "no 16TB file size limit on ZFS"
21823
21824         $LFS setstripe -c 1 $DIR/$tfile
21825         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21826         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21827         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21828         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21829                 conv=notrunc,fsync && error "append succeeded"
21830         return 0
21831 }
21832 run_test 250 "Write above 16T limit"
21833
21834 test_251() {
21835         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21836
21837         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21838         #Skip once - writing the first stripe will succeed
21839         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21840         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21841                 error "short write happened"
21842
21843         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21844         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21845                 error "short read happened"
21846
21847         rm -f $DIR/$tfile
21848 }
21849 run_test 251 "Handling short read and write correctly"
21850
21851 test_252() {
21852         remote_mds_nodsh && skip "remote MDS with nodsh"
21853         remote_ost_nodsh && skip "remote OST with nodsh"
21854         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21855                 skip_env "ldiskfs only test"
21856         fi
21857
21858         local tgt
21859         local dev
21860         local out
21861         local uuid
21862         local num
21863         local gen
21864
21865         # check lr_reader on OST0000
21866         tgt=ost1
21867         dev=$(facet_device $tgt)
21868         out=$(do_facet $tgt $LR_READER $dev)
21869         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21870         echo "$out"
21871         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21872         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21873                 error "Invalid uuid returned by $LR_READER on target $tgt"
21874         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21875
21876         # check lr_reader -c on MDT0000
21877         tgt=mds1
21878         dev=$(facet_device $tgt)
21879         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21880                 skip "$LR_READER does not support additional options"
21881         fi
21882         out=$(do_facet $tgt $LR_READER -c $dev)
21883         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21884         echo "$out"
21885         num=$(echo "$out" | grep -c "mdtlov")
21886         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21887                 error "Invalid number of mdtlov clients returned by $LR_READER"
21888         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21889
21890         # check lr_reader -cr on MDT0000
21891         out=$(do_facet $tgt $LR_READER -cr $dev)
21892         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21893         echo "$out"
21894         echo "$out" | grep -q "^reply_data:$" ||
21895                 error "$LR_READER should have returned 'reply_data' section"
21896         num=$(echo "$out" | grep -c "client_generation")
21897         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21898 }
21899 run_test 252 "check lr_reader tool"
21900
21901 test_253() {
21902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21903         remote_mds_nodsh && skip "remote MDS with nodsh"
21904         remote_mgs_nodsh && skip "remote MGS with nodsh"
21905
21906         local ostidx=0
21907         local rc=0
21908         local ost_name=$(ostname_from_index $ostidx)
21909
21910         # on the mdt's osc
21911         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21912         do_facet $SINGLEMDS $LCTL get_param -n \
21913                 osp.$mdtosc_proc1.reserved_mb_high ||
21914                 skip  "remote MDS does not support reserved_mb_high"
21915
21916         rm -rf $DIR/$tdir
21917         wait_mds_ost_sync
21918         wait_delete_completed
21919         mkdir $DIR/$tdir
21920
21921         pool_add $TESTNAME || error "Pool creation failed"
21922         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21923
21924         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21925                 error "Setstripe failed"
21926
21927         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21928
21929         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21930                     grep "watermarks")
21931         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21932
21933         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21934                         osp.$mdtosc_proc1.prealloc_status)
21935         echo "prealloc_status $oa_status"
21936
21937         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21938                 error "File creation should fail"
21939
21940         #object allocation was stopped, but we still able to append files
21941         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21942                 oflag=append || error "Append failed"
21943
21944         rm -f $DIR/$tdir/$tfile.0
21945
21946         # For this test, we want to delete the files we created to go out of
21947         # space but leave the watermark, so we remain nearly out of space
21948         ost_watermarks_enospc_delete_files $tfile $ostidx
21949
21950         wait_delete_completed
21951
21952         sleep_maxage
21953
21954         for i in $(seq 10 12); do
21955                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21956                         2>/dev/null || error "File creation failed after rm"
21957         done
21958
21959         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21960                         osp.$mdtosc_proc1.prealloc_status)
21961         echo "prealloc_status $oa_status"
21962
21963         if (( oa_status != 0 )); then
21964                 error "Object allocation still disable after rm"
21965         fi
21966 }
21967 run_test 253 "Check object allocation limit"
21968
21969 test_254() {
21970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21971         remote_mds_nodsh && skip "remote MDS with nodsh"
21972
21973         local mdt=$(facet_svc $SINGLEMDS)
21974
21975         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21976                 skip "MDS does not support changelog_size"
21977
21978         local cl_user
21979
21980         changelog_register || error "changelog_register failed"
21981
21982         changelog_clear 0 || error "changelog_clear failed"
21983
21984         local size1=$(do_facet $SINGLEMDS \
21985                       $LCTL get_param -n mdd.$mdt.changelog_size)
21986         echo "Changelog size $size1"
21987
21988         rm -rf $DIR/$tdir
21989         $LFS mkdir -i 0 $DIR/$tdir
21990         # change something
21991         mkdir -p $DIR/$tdir/pics/2008/zachy
21992         touch $DIR/$tdir/pics/2008/zachy/timestamp
21993         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21994         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21995         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21996         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21997         rm $DIR/$tdir/pics/desktop.jpg
21998
21999         local size2=$(do_facet $SINGLEMDS \
22000                       $LCTL get_param -n mdd.$mdt.changelog_size)
22001         echo "Changelog size after work $size2"
22002
22003         (( $size2 > $size1 )) ||
22004                 error "new Changelog size=$size2 less than old size=$size1"
22005 }
22006 run_test 254 "Check changelog size"
22007
22008 ladvise_no_type()
22009 {
22010         local type=$1
22011         local file=$2
22012
22013         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22014                 awk -F: '{print $2}' | grep $type > /dev/null
22015         if [ $? -ne 0 ]; then
22016                 return 0
22017         fi
22018         return 1
22019 }
22020
22021 ladvise_no_ioctl()
22022 {
22023         local file=$1
22024
22025         lfs ladvise -a willread $file > /dev/null 2>&1
22026         if [ $? -eq 0 ]; then
22027                 return 1
22028         fi
22029
22030         lfs ladvise -a willread $file 2>&1 |
22031                 grep "Inappropriate ioctl for device" > /dev/null
22032         if [ $? -eq 0 ]; then
22033                 return 0
22034         fi
22035         return 1
22036 }
22037
22038 percent() {
22039         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22040 }
22041
22042 # run a random read IO workload
22043 # usage: random_read_iops <filename> <filesize> <iosize>
22044 random_read_iops() {
22045         local file=$1
22046         local fsize=$2
22047         local iosize=${3:-4096}
22048
22049         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22050                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22051 }
22052
22053 drop_file_oss_cache() {
22054         local file="$1"
22055         local nodes="$2"
22056
22057         $LFS ladvise -a dontneed $file 2>/dev/null ||
22058                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22059 }
22060
22061 ladvise_willread_performance()
22062 {
22063         local repeat=10
22064         local average_origin=0
22065         local average_cache=0
22066         local average_ladvise=0
22067
22068         for ((i = 1; i <= $repeat; i++)); do
22069                 echo "Iter $i/$repeat: reading without willread hint"
22070                 cancel_lru_locks osc
22071                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22072                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22073                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22074                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22075
22076                 cancel_lru_locks osc
22077                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22078                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22079                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22080
22081                 cancel_lru_locks osc
22082                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22083                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22084                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22085                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22086                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22087         done
22088         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22089         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22090         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22091
22092         speedup_cache=$(percent $average_cache $average_origin)
22093         speedup_ladvise=$(percent $average_ladvise $average_origin)
22094
22095         echo "Average uncached read: $average_origin"
22096         echo "Average speedup with OSS cached read: " \
22097                 "$average_cache = +$speedup_cache%"
22098         echo "Average speedup with ladvise willread: " \
22099                 "$average_ladvise = +$speedup_ladvise%"
22100
22101         local lowest_speedup=20
22102         if (( ${average_cache%.*} < $lowest_speedup )); then
22103                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22104                      " got $average_cache%. Skipping ladvise willread check."
22105                 return 0
22106         fi
22107
22108         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22109         # it is still good to run until then to exercise 'ladvise willread'
22110         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22111                 [ "$ost1_FSTYPE" = "zfs" ] &&
22112                 echo "osd-zfs does not support dontneed or drop_caches" &&
22113                 return 0
22114
22115         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22116         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22117                 error_not_in_vm "Speedup with willread is less than " \
22118                         "$lowest_speedup%, got $average_ladvise%"
22119 }
22120
22121 test_255a() {
22122         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22123                 skip "lustre < 2.8.54 does not support ladvise "
22124         remote_ost_nodsh && skip "remote OST with nodsh"
22125
22126         stack_trap "rm -f $DIR/$tfile"
22127         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22128
22129         ladvise_no_type willread $DIR/$tfile &&
22130                 skip "willread ladvise is not supported"
22131
22132         ladvise_no_ioctl $DIR/$tfile &&
22133                 skip "ladvise ioctl is not supported"
22134
22135         local size_mb=100
22136         local size=$((size_mb * 1048576))
22137         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22138                 error "dd to $DIR/$tfile failed"
22139
22140         lfs ladvise -a willread $DIR/$tfile ||
22141                 error "Ladvise failed with no range argument"
22142
22143         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22144                 error "Ladvise failed with no -l or -e argument"
22145
22146         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22147                 error "Ladvise failed with only -e argument"
22148
22149         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22150                 error "Ladvise failed with only -l argument"
22151
22152         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22153                 error "End offset should not be smaller than start offset"
22154
22155         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22156                 error "End offset should not be equal to start offset"
22157
22158         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22159                 error "Ladvise failed with overflowing -s argument"
22160
22161         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22162                 error "Ladvise failed with overflowing -e argument"
22163
22164         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22165                 error "Ladvise failed with overflowing -l argument"
22166
22167         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22168                 error "Ladvise succeeded with conflicting -l and -e arguments"
22169
22170         echo "Synchronous ladvise should wait"
22171         local delay=4
22172 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22173         do_nodes $(comma_list $(osts_nodes)) \
22174                 $LCTL set_param fail_val=$delay fail_loc=0x237
22175
22176         local start_ts=$SECONDS
22177         lfs ladvise -a willread $DIR/$tfile ||
22178                 error "Ladvise failed with no range argument"
22179         local end_ts=$SECONDS
22180         local inteval_ts=$((end_ts - start_ts))
22181
22182         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22183                 error "Synchronous advice didn't wait reply"
22184         fi
22185
22186         echo "Asynchronous ladvise shouldn't wait"
22187         local start_ts=$SECONDS
22188         lfs ladvise -a willread -b $DIR/$tfile ||
22189                 error "Ladvise failed with no range argument"
22190         local end_ts=$SECONDS
22191         local inteval_ts=$((end_ts - start_ts))
22192
22193         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22194                 error "Asynchronous advice blocked"
22195         fi
22196
22197         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22198         ladvise_willread_performance
22199 }
22200 run_test 255a "check 'lfs ladvise -a willread'"
22201
22202 facet_meminfo() {
22203         local facet=$1
22204         local info=$2
22205
22206         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22207 }
22208
22209 test_255b() {
22210         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22211                 skip "lustre < 2.8.54 does not support ladvise "
22212         remote_ost_nodsh && skip "remote OST with nodsh"
22213
22214         stack_trap "rm -f $DIR/$tfile"
22215         lfs setstripe -c 1 -i 0 $DIR/$tfile
22216
22217         ladvise_no_type dontneed $DIR/$tfile &&
22218                 skip "dontneed ladvise is not supported"
22219
22220         ladvise_no_ioctl $DIR/$tfile &&
22221                 skip "ladvise ioctl is not supported"
22222
22223         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22224                 [ "$ost1_FSTYPE" = "zfs" ] &&
22225                 skip "zfs-osd does not support 'ladvise dontneed'"
22226
22227         local size_mb=100
22228         local size=$((size_mb * 1048576))
22229         # In order to prevent disturbance of other processes, only check 3/4
22230         # of the memory usage
22231         local kibibytes=$((size_mb * 1024 * 3 / 4))
22232
22233         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22234                 error "dd to $DIR/$tfile failed"
22235
22236         #force write to complete before dropping OST cache & checking memory
22237         sync
22238
22239         local total=$(facet_meminfo ost1 MemTotal)
22240         echo "Total memory: $total KiB"
22241
22242         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22243         local before_read=$(facet_meminfo ost1 Cached)
22244         echo "Cache used before read: $before_read KiB"
22245
22246         lfs ladvise -a willread $DIR/$tfile ||
22247                 error "Ladvise willread failed"
22248         local after_read=$(facet_meminfo ost1 Cached)
22249         echo "Cache used after read: $after_read KiB"
22250
22251         lfs ladvise -a dontneed $DIR/$tfile ||
22252                 error "Ladvise dontneed again failed"
22253         local no_read=$(facet_meminfo ost1 Cached)
22254         echo "Cache used after dontneed ladvise: $no_read KiB"
22255
22256         if [ $total -lt $((before_read + kibibytes)) ]; then
22257                 echo "Memory is too small, abort checking"
22258                 return 0
22259         fi
22260
22261         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22262                 error "Ladvise willread should use more memory" \
22263                         "than $kibibytes KiB"
22264         fi
22265
22266         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22267                 error "Ladvise dontneed should release more memory" \
22268                         "than $kibibytes KiB"
22269         fi
22270 }
22271 run_test 255b "check 'lfs ladvise -a dontneed'"
22272
22273 test_255c() {
22274         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22275                 skip "lustre < 2.10.50 does not support lockahead"
22276
22277         local ost1_imp=$(get_osc_import_name client ost1)
22278         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22279                          cut -d'.' -f2)
22280         local count
22281         local new_count
22282         local difference
22283         local i
22284         local rc
22285
22286         test_mkdir -p $DIR/$tdir
22287         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22288
22289         #test 10 returns only success/failure
22290         i=10
22291         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22292         rc=$?
22293         if [ $rc -eq 255 ]; then
22294                 error "Ladvise test${i} failed, ${rc}"
22295         fi
22296
22297         #test 11 counts lock enqueue requests, all others count new locks
22298         i=11
22299         count=$(do_facet ost1 \
22300                 $LCTL get_param -n ost.OSS.ost.stats)
22301         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22302
22303         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22304         rc=$?
22305         if [ $rc -eq 255 ]; then
22306                 error "Ladvise test${i} failed, ${rc}"
22307         fi
22308
22309         new_count=$(do_facet ost1 \
22310                 $LCTL get_param -n ost.OSS.ost.stats)
22311         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22312                    awk '{ print $2 }')
22313
22314         difference="$((new_count - count))"
22315         if [ $difference -ne $rc ]; then
22316                 error "Ladvise test${i}, bad enqueue count, returned " \
22317                       "${rc}, actual ${difference}"
22318         fi
22319
22320         for i in $(seq 12 21); do
22321                 # If we do not do this, we run the risk of having too many
22322                 # locks and starting lock cancellation while we are checking
22323                 # lock counts.
22324                 cancel_lru_locks osc
22325
22326                 count=$($LCTL get_param -n \
22327                        ldlm.namespaces.$imp_name.lock_unused_count)
22328
22329                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22330                 rc=$?
22331                 if [ $rc -eq 255 ]; then
22332                         error "Ladvise test ${i} failed, ${rc}"
22333                 fi
22334
22335                 new_count=$($LCTL get_param -n \
22336                        ldlm.namespaces.$imp_name.lock_unused_count)
22337                 difference="$((new_count - count))"
22338
22339                 # Test 15 output is divided by 100 to map down to valid return
22340                 if [ $i -eq 15 ]; then
22341                         rc="$((rc * 100))"
22342                 fi
22343
22344                 if [ $difference -ne $rc ]; then
22345                         error "Ladvise test ${i}, bad lock count, returned " \
22346                               "${rc}, actual ${difference}"
22347                 fi
22348         done
22349
22350         #test 22 returns only success/failure
22351         i=22
22352         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22353         rc=$?
22354         if [ $rc -eq 255 ]; then
22355                 error "Ladvise test${i} failed, ${rc}"
22356         fi
22357 }
22358 run_test 255c "suite of ladvise lockahead tests"
22359
22360 test_256() {
22361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22362         remote_mds_nodsh && skip "remote MDS with nodsh"
22363         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22364         changelog_users $SINGLEMDS | grep "^cl" &&
22365                 skip "active changelog user"
22366
22367         local cl_user
22368         local cat_sl
22369         local mdt_dev
22370
22371         mdt_dev=$(facet_device $SINGLEMDS)
22372         echo $mdt_dev
22373
22374         changelog_register || error "changelog_register failed"
22375
22376         rm -rf $DIR/$tdir
22377         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22378
22379         changelog_clear 0 || error "changelog_clear failed"
22380
22381         # change something
22382         touch $DIR/$tdir/{1..10}
22383
22384         # stop the MDT
22385         stop $SINGLEMDS || error "Fail to stop MDT"
22386
22387         # remount the MDT
22388         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22389                 error "Fail to start MDT"
22390
22391         #after mount new plainllog is used
22392         touch $DIR/$tdir/{11..19}
22393         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22394         stack_trap "rm -f $tmpfile"
22395         cat_sl=$(do_facet $SINGLEMDS "sync; \
22396                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22397                  llog_reader $tmpfile | grep -c type=1064553b")
22398         do_facet $SINGLEMDS llog_reader $tmpfile
22399
22400         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22401
22402         changelog_clear 0 || error "changelog_clear failed"
22403
22404         cat_sl=$(do_facet $SINGLEMDS "sync; \
22405                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22406                  llog_reader $tmpfile | grep -c type=1064553b")
22407
22408         if (( cat_sl == 2 )); then
22409                 error "Empty plain llog was not deleted from changelog catalog"
22410         elif (( cat_sl != 1 )); then
22411                 error "Active plain llog shouldn't be deleted from catalog"
22412         fi
22413 }
22414 run_test 256 "Check llog delete for empty and not full state"
22415
22416 test_257() {
22417         remote_mds_nodsh && skip "remote MDS with nodsh"
22418         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22419                 skip "Need MDS version at least 2.8.55"
22420
22421         test_mkdir $DIR/$tdir
22422
22423         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22424                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22425         stat $DIR/$tdir
22426
22427 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22428         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22429         local facet=mds$((mdtidx + 1))
22430         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22431         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22432
22433         stop $facet || error "stop MDS failed"
22434         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22435                 error "start MDS fail"
22436         wait_recovery_complete $facet
22437 }
22438 run_test 257 "xattr locks are not lost"
22439
22440 # Verify we take the i_mutex when security requires it
22441 test_258a() {
22442 #define OBD_FAIL_IMUTEX_SEC 0x141c
22443         $LCTL set_param fail_loc=0x141c
22444         touch $DIR/$tfile
22445         chmod u+s $DIR/$tfile
22446         chmod a+rwx $DIR/$tfile
22447         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22448         RC=$?
22449         if [ $RC -ne 0 ]; then
22450                 error "error, failed to take i_mutex, rc=$?"
22451         fi
22452         rm -f $DIR/$tfile
22453 }
22454 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22455
22456 # Verify we do NOT take the i_mutex in the normal case
22457 test_258b() {
22458 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22459         $LCTL set_param fail_loc=0x141d
22460         touch $DIR/$tfile
22461         chmod a+rwx $DIR
22462         chmod a+rw $DIR/$tfile
22463         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22464         RC=$?
22465         if [ $RC -ne 0 ]; then
22466                 error "error, took i_mutex unnecessarily, rc=$?"
22467         fi
22468         rm -f $DIR/$tfile
22469
22470 }
22471 run_test 258b "verify i_mutex security behavior"
22472
22473 test_259() {
22474         local file=$DIR/$tfile
22475         local before
22476         local after
22477
22478         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22479
22480         stack_trap "rm -f $file" EXIT
22481
22482         wait_delete_completed
22483         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22484         echo "before: $before"
22485
22486         $LFS setstripe -i 0 -c 1 $file
22487         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22488         sync_all_data
22489         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22490         echo "after write: $after"
22491
22492 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22493         do_facet ost1 $LCTL set_param fail_loc=0x2301
22494         $TRUNCATE $file 0
22495         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22496         echo "after truncate: $after"
22497
22498         stop ost1
22499         do_facet ost1 $LCTL set_param fail_loc=0
22500         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22501         sleep 2
22502         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22503         echo "after restart: $after"
22504         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22505                 error "missing truncate?"
22506
22507         return 0
22508 }
22509 run_test 259 "crash at delayed truncate"
22510
22511 test_260() {
22512 #define OBD_FAIL_MDC_CLOSE               0x806
22513         $LCTL set_param fail_loc=0x80000806
22514         touch $DIR/$tfile
22515
22516 }
22517 run_test 260 "Check mdc_close fail"
22518
22519 ### Data-on-MDT sanity tests ###
22520 test_270a() {
22521         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22522                 skip "Need MDS version at least 2.10.55 for DoM"
22523
22524         # create DoM file
22525         local dom=$DIR/$tdir/dom_file
22526         local tmp=$DIR/$tdir/tmp_file
22527
22528         mkdir_on_mdt0 $DIR/$tdir
22529
22530         # basic checks for DoM component creation
22531         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22532                 error "Can set MDT layout to non-first entry"
22533
22534         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22535                 error "Can define multiple entries as MDT layout"
22536
22537         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22538
22539         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22540         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22541         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22542
22543         local mdtidx=$($LFS getstripe -m $dom)
22544         local mdtname=MDT$(printf %04x $mdtidx)
22545         local facet=mds$((mdtidx + 1))
22546         local space_check=1
22547
22548         # Skip free space checks with ZFS
22549         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22550
22551         # write
22552         sync
22553         local size_tmp=$((65536 * 3))
22554         local mdtfree1=$(do_facet $facet \
22555                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22556
22557         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22558         # check also direct IO along write
22559         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22560         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22561         sync
22562         cmp $tmp $dom || error "file data is different"
22563         [ $(stat -c%s $dom) == $size_tmp ] ||
22564                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22565         if [ $space_check == 1 ]; then
22566                 local mdtfree2=$(do_facet $facet \
22567                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22568
22569                 # increase in usage from by $size_tmp
22570                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22571                         error "MDT free space wrong after write: " \
22572                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22573         fi
22574
22575         # truncate
22576         local size_dom=10000
22577
22578         $TRUNCATE $dom $size_dom
22579         [ $(stat -c%s $dom) == $size_dom ] ||
22580                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22581         if [ $space_check == 1 ]; then
22582                 mdtfree1=$(do_facet $facet \
22583                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22584                 # decrease in usage from $size_tmp to new $size_dom
22585                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22586                   $(((size_tmp - size_dom) / 1024)) ] ||
22587                         error "MDT free space is wrong after truncate: " \
22588                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22589         fi
22590
22591         # append
22592         cat $tmp >> $dom
22593         sync
22594         size_dom=$((size_dom + size_tmp))
22595         [ $(stat -c%s $dom) == $size_dom ] ||
22596                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22597         if [ $space_check == 1 ]; then
22598                 mdtfree2=$(do_facet $facet \
22599                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22600                 # increase in usage by $size_tmp from previous
22601                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22602                         error "MDT free space is wrong after append: " \
22603                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22604         fi
22605
22606         # delete
22607         rm $dom
22608         if [ $space_check == 1 ]; then
22609                 mdtfree1=$(do_facet $facet \
22610                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22611                 # decrease in usage by $size_dom from previous
22612                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22613                         error "MDT free space is wrong after removal: " \
22614                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22615         fi
22616
22617         # combined striping
22618         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22619                 error "Can't create DoM + OST striping"
22620
22621         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22622         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22623         # check also direct IO along write
22624         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22625         sync
22626         cmp $tmp $dom || error "file data is different"
22627         [ $(stat -c%s $dom) == $size_tmp ] ||
22628                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22629         rm $dom $tmp
22630
22631         return 0
22632 }
22633 run_test 270a "DoM: basic functionality tests"
22634
22635 test_270b() {
22636         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22637                 skip "Need MDS version at least 2.10.55"
22638
22639         local dom=$DIR/$tdir/dom_file
22640         local max_size=1048576
22641
22642         mkdir -p $DIR/$tdir
22643         $LFS setstripe -E $max_size -L mdt $dom
22644
22645         # truncate over the limit
22646         $TRUNCATE $dom $(($max_size + 1)) &&
22647                 error "successful truncate over the maximum size"
22648         # write over the limit
22649         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22650                 error "successful write over the maximum size"
22651         # append over the limit
22652         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22653         echo "12345" >> $dom && error "successful append over the maximum size"
22654         rm $dom
22655
22656         return 0
22657 }
22658 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22659
22660 test_270c() {
22661         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22662                 skip "Need MDS version at least 2.10.55"
22663
22664         mkdir -p $DIR/$tdir
22665         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22666
22667         # check files inherit DoM EA
22668         touch $DIR/$tdir/first
22669         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22670                 error "bad pattern"
22671         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22672                 error "bad stripe count"
22673         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22674                 error "bad stripe size"
22675
22676         # check directory inherits DoM EA and uses it as default
22677         mkdir $DIR/$tdir/subdir
22678         touch $DIR/$tdir/subdir/second
22679         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22680                 error "bad pattern in sub-directory"
22681         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22682                 error "bad stripe count in sub-directory"
22683         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22684                 error "bad stripe size in sub-directory"
22685         return 0
22686 }
22687 run_test 270c "DoM: DoM EA inheritance tests"
22688
22689 test_270d() {
22690         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22691                 skip "Need MDS version at least 2.10.55"
22692
22693         mkdir -p $DIR/$tdir
22694         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22695
22696         # inherit default DoM striping
22697         mkdir $DIR/$tdir/subdir
22698         touch $DIR/$tdir/subdir/f1
22699
22700         # change default directory striping
22701         $LFS setstripe -c 1 $DIR/$tdir/subdir
22702         touch $DIR/$tdir/subdir/f2
22703         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22704                 error "wrong default striping in file 2"
22705         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22706                 error "bad pattern in file 2"
22707         return 0
22708 }
22709 run_test 270d "DoM: change striping from DoM to RAID0"
22710
22711 test_270e() {
22712         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22713                 skip "Need MDS version at least 2.10.55"
22714
22715         mkdir -p $DIR/$tdir/dom
22716         mkdir -p $DIR/$tdir/norm
22717         DOMFILES=20
22718         NORMFILES=10
22719         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22720         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22721
22722         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22723         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22724
22725         # find DoM files by layout
22726         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22727         [ $NUM -eq  $DOMFILES ] ||
22728                 error "lfs find -L: found $NUM, expected $DOMFILES"
22729         echo "Test 1: lfs find 20 DOM files by layout: OK"
22730
22731         # there should be 1 dir with default DOM striping
22732         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22733         [ $NUM -eq  1 ] ||
22734                 error "lfs find -L: found $NUM, expected 1 dir"
22735         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22736
22737         # find DoM files by stripe size
22738         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22739         [ $NUM -eq  $DOMFILES ] ||
22740                 error "lfs find -S: found $NUM, expected $DOMFILES"
22741         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22742
22743         # find files by stripe offset except DoM files
22744         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22745         [ $NUM -eq  $NORMFILES ] ||
22746                 error "lfs find -i: found $NUM, expected $NORMFILES"
22747         echo "Test 5: lfs find no DOM files by stripe index: OK"
22748         return 0
22749 }
22750 run_test 270e "DoM: lfs find with DoM files test"
22751
22752 test_270f() {
22753         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22754                 skip "Need MDS version at least 2.10.55"
22755
22756         local mdtname=${FSNAME}-MDT0000-mdtlov
22757         local dom=$DIR/$tdir/dom_file
22758         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22759                                                 lod.$mdtname.dom_stripesize)
22760         local dom_limit=131072
22761
22762         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22763         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22764                                                 lod.$mdtname.dom_stripesize)
22765         [ ${dom_limit} -eq ${dom_current} ] ||
22766                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22767
22768         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22769         $LFS setstripe -d $DIR/$tdir
22770         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22771                 error "Can't set directory default striping"
22772
22773         # exceed maximum stripe size
22774         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22775                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22776         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22777                 error "Able to create DoM component size more than LOD limit"
22778
22779         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22780         dom_current=$(do_facet mds1 $LCTL get_param -n \
22781                                                 lod.$mdtname.dom_stripesize)
22782         [ 0 -eq ${dom_current} ] ||
22783                 error "Can't set zero DoM stripe limit"
22784         rm $dom
22785
22786         # attempt to create DoM file on server with disabled DoM should
22787         # remove DoM entry from layout and be succeed
22788         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22789                 error "Can't create DoM file (DoM is disabled)"
22790         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22791                 error "File has DoM component while DoM is disabled"
22792         rm $dom
22793
22794         # attempt to create DoM file with only DoM stripe should return error
22795         $LFS setstripe -E $dom_limit -L mdt $dom &&
22796                 error "Able to create DoM-only file while DoM is disabled"
22797
22798         # too low values to be aligned with smallest stripe size 64K
22799         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22800         dom_current=$(do_facet mds1 $LCTL get_param -n \
22801                                                 lod.$mdtname.dom_stripesize)
22802         [ 30000 -eq ${dom_current} ] &&
22803                 error "Can set too small DoM stripe limit"
22804
22805         # 64K is a minimal stripe size in Lustre, expect limit of that size
22806         [ 65536 -eq ${dom_current} ] ||
22807                 error "Limit is not set to 64K but ${dom_current}"
22808
22809         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22810         dom_current=$(do_facet mds1 $LCTL get_param -n \
22811                                                 lod.$mdtname.dom_stripesize)
22812         echo $dom_current
22813         [ 2147483648 -eq ${dom_current} ] &&
22814                 error "Can set too large DoM stripe limit"
22815
22816         do_facet mds1 $LCTL set_param -n \
22817                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22818         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22819                 error "Can't create DoM component size after limit change"
22820         do_facet mds1 $LCTL set_param -n \
22821                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22822         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22823                 error "Can't create DoM file after limit decrease"
22824         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22825                 error "Can create big DoM component after limit decrease"
22826         touch ${dom}_def ||
22827                 error "Can't create file with old default layout"
22828
22829         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22830         return 0
22831 }
22832 run_test 270f "DoM: maximum DoM stripe size checks"
22833
22834 test_270g() {
22835         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22836                 skip "Need MDS version at least 2.13.52"
22837         local dom=$DIR/$tdir/$tfile
22838
22839         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22840         local lodname=${FSNAME}-MDT0000-mdtlov
22841
22842         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22843         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22844         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22845         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22846
22847         local dom_limit=1024
22848         local dom_threshold="50%"
22849
22850         $LFS setstripe -d $DIR/$tdir
22851         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22852                 error "Can't set directory default striping"
22853
22854         do_facet mds1 $LCTL set_param -n \
22855                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22856         # set 0 threshold and create DOM file to change tunable stripesize
22857         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22858         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22859                 error "Failed to create $dom file"
22860         # now tunable dom_cur_stripesize should reach maximum
22861         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22862                                         lod.${lodname}.dom_stripesize_cur_kb)
22863         [[ $dom_current == $dom_limit ]] ||
22864                 error "Current DOM stripesize is not maximum"
22865         rm $dom
22866
22867         # set threshold for further tests
22868         do_facet mds1 $LCTL set_param -n \
22869                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22870         echo "DOM threshold is $dom_threshold free space"
22871         local dom_def
22872         local dom_set
22873         # Spoof bfree to exceed threshold
22874         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22875         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22876         for spfree in 40 20 0 15 30 55; do
22877                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22878                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22879                         error "Failed to create $dom file"
22880                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22881                                         lod.${lodname}.dom_stripesize_cur_kb)
22882                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22883                 [[ $dom_def != $dom_current ]] ||
22884                         error "Default stripe size was not changed"
22885                 if (( spfree > 0 )) ; then
22886                         dom_set=$($LFS getstripe -S $dom)
22887                         (( dom_set == dom_def * 1024 )) ||
22888                                 error "DOM component size is still old"
22889                 else
22890                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22891                                 error "DoM component is set with no free space"
22892                 fi
22893                 rm $dom
22894                 dom_current=$dom_def
22895         done
22896 }
22897 run_test 270g "DoM: default DoM stripe size depends on free space"
22898
22899 test_270h() {
22900         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22901                 skip "Need MDS version at least 2.13.53"
22902
22903         local mdtname=${FSNAME}-MDT0000-mdtlov
22904         local dom=$DIR/$tdir/$tfile
22905         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22906
22907         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22908         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22909
22910         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22911         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22912                 error "can't create OST file"
22913         # mirrored file with DOM entry in the second mirror
22914         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22915                 error "can't create mirror with DoM component"
22916
22917         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22918
22919         # DOM component in the middle and has other enries in the same mirror,
22920         # should succeed but lost DoM component
22921         $LFS setstripe --copy=${dom}_1 $dom ||
22922                 error "Can't create file from OST|DOM mirror layout"
22923         # check new file has no DoM layout after all
22924         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22925                 error "File has DoM component while DoM is disabled"
22926 }
22927 run_test 270h "DoM: DoM stripe removal when disabled on server"
22928
22929 test_270i() {
22930         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22931                 skip "Need MDS version at least 2.14.54"
22932
22933         mkdir $DIR/$tdir
22934         # DoM with plain layout
22935         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22936                 error "default plain layout with DoM must fail"
22937         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
22938                 error "setstripe plain file layout with DoM must fail"
22939         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
22940                 error "default DoM layout with bad striping must fail"
22941         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
22942                 error "setstripe to DoM layout with bad striping must fail"
22943         return 0
22944 }
22945 run_test 270i "DoM: setting invalid DoM striping should fail"
22946
22947 test_271a() {
22948         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22949                 skip "Need MDS version at least 2.10.55"
22950
22951         local dom=$DIR/$tdir/dom
22952
22953         mkdir -p $DIR/$tdir
22954
22955         $LFS setstripe -E 1024K -L mdt $dom
22956
22957         lctl set_param -n mdc.*.stats=clear
22958         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22959         cat $dom > /dev/null
22960         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22961         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22962         ls $dom
22963         rm -f $dom
22964 }
22965 run_test 271a "DoM: data is cached for read after write"
22966
22967 test_271b() {
22968         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22969                 skip "Need MDS version at least 2.10.55"
22970
22971         local dom=$DIR/$tdir/dom
22972
22973         mkdir -p $DIR/$tdir
22974
22975         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22976
22977         lctl set_param -n mdc.*.stats=clear
22978         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22979         cancel_lru_locks mdc
22980         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22981         # second stat to check size is cached on client
22982         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22983         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22984         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22985         rm -f $dom
22986 }
22987 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22988
22989 test_271ba() {
22990         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22991                 skip "Need MDS version at least 2.10.55"
22992
22993         local dom=$DIR/$tdir/dom
22994
22995         mkdir -p $DIR/$tdir
22996
22997         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22998
22999         lctl set_param -n mdc.*.stats=clear
23000         lctl set_param -n osc.*.stats=clear
23001         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23002         cancel_lru_locks mdc
23003         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23004         # second stat to check size is cached on client
23005         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23006         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23007         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23008         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23009         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23010         rm -f $dom
23011 }
23012 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23013
23014
23015 get_mdc_stats() {
23016         local mdtidx=$1
23017         local param=$2
23018         local mdt=MDT$(printf %04x $mdtidx)
23019
23020         if [ -z $param ]; then
23021                 lctl get_param -n mdc.*$mdt*.stats
23022         else
23023                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23024         fi
23025 }
23026
23027 test_271c() {
23028         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23029                 skip "Need MDS version at least 2.10.55"
23030
23031         local dom=$DIR/$tdir/dom
23032
23033         mkdir -p $DIR/$tdir
23034
23035         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23036
23037         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23038         local facet=mds$((mdtidx + 1))
23039
23040         cancel_lru_locks mdc
23041         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23042         createmany -o $dom 1000
23043         lctl set_param -n mdc.*.stats=clear
23044         smalliomany -w $dom 1000 200
23045         get_mdc_stats $mdtidx
23046         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23047         # Each file has 1 open, 1 IO enqueues, total 2000
23048         # but now we have also +1 getxattr for security.capability, total 3000
23049         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23050         unlinkmany $dom 1000
23051
23052         cancel_lru_locks mdc
23053         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23054         createmany -o $dom 1000
23055         lctl set_param -n mdc.*.stats=clear
23056         smalliomany -w $dom 1000 200
23057         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23058         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23059         # for OPEN and IO lock.
23060         [ $((enq - enq_2)) -ge 1000 ] ||
23061                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23062         unlinkmany $dom 1000
23063         return 0
23064 }
23065 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23066
23067 cleanup_271def_tests() {
23068         trap 0
23069         rm -f $1
23070 }
23071
23072 test_271d() {
23073         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23074                 skip "Need MDS version at least 2.10.57"
23075
23076         local dom=$DIR/$tdir/dom
23077         local tmp=$TMP/$tfile
23078         trap "cleanup_271def_tests $tmp" EXIT
23079
23080         mkdir -p $DIR/$tdir
23081
23082         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23083
23084         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23085
23086         cancel_lru_locks mdc
23087         dd if=/dev/urandom of=$tmp bs=1000 count=1
23088         dd if=$tmp of=$dom bs=1000 count=1
23089         cancel_lru_locks mdc
23090
23091         cat /etc/hosts >> $tmp
23092         lctl set_param -n mdc.*.stats=clear
23093
23094         # append data to the same file it should update local page
23095         echo "Append to the same page"
23096         cat /etc/hosts >> $dom
23097         local num=$(get_mdc_stats $mdtidx ost_read)
23098         local ra=$(get_mdc_stats $mdtidx req_active)
23099         local rw=$(get_mdc_stats $mdtidx req_waittime)
23100
23101         [ -z $num ] || error "$num READ RPC occured"
23102         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23103         echo "... DONE"
23104
23105         # compare content
23106         cmp $tmp $dom || error "file miscompare"
23107
23108         cancel_lru_locks mdc
23109         lctl set_param -n mdc.*.stats=clear
23110
23111         echo "Open and read file"
23112         cat $dom > /dev/null
23113         local num=$(get_mdc_stats $mdtidx ost_read)
23114         local ra=$(get_mdc_stats $mdtidx req_active)
23115         local rw=$(get_mdc_stats $mdtidx req_waittime)
23116
23117         [ -z $num ] || error "$num READ RPC occured"
23118         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23119         echo "... DONE"
23120
23121         # compare content
23122         cmp $tmp $dom || error "file miscompare"
23123
23124         return 0
23125 }
23126 run_test 271d "DoM: read on open (1K file in reply buffer)"
23127
23128 test_271f() {
23129         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23130                 skip "Need MDS version at least 2.10.57"
23131
23132         local dom=$DIR/$tdir/dom
23133         local tmp=$TMP/$tfile
23134         trap "cleanup_271def_tests $tmp" EXIT
23135
23136         mkdir -p $DIR/$tdir
23137
23138         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23139
23140         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23141
23142         cancel_lru_locks mdc
23143         dd if=/dev/urandom of=$tmp bs=265000 count=1
23144         dd if=$tmp of=$dom bs=265000 count=1
23145         cancel_lru_locks mdc
23146         cat /etc/hosts >> $tmp
23147         lctl set_param -n mdc.*.stats=clear
23148
23149         echo "Append to the same page"
23150         cat /etc/hosts >> $dom
23151         local num=$(get_mdc_stats $mdtidx ost_read)
23152         local ra=$(get_mdc_stats $mdtidx req_active)
23153         local rw=$(get_mdc_stats $mdtidx req_waittime)
23154
23155         [ -z $num ] || error "$num READ RPC occured"
23156         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23157         echo "... DONE"
23158
23159         # compare content
23160         cmp $tmp $dom || error "file miscompare"
23161
23162         cancel_lru_locks mdc
23163         lctl set_param -n mdc.*.stats=clear
23164
23165         echo "Open and read file"
23166         cat $dom > /dev/null
23167         local num=$(get_mdc_stats $mdtidx ost_read)
23168         local ra=$(get_mdc_stats $mdtidx req_active)
23169         local rw=$(get_mdc_stats $mdtidx req_waittime)
23170
23171         [ -z $num ] && num=0
23172         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23173         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23174         echo "... DONE"
23175
23176         # compare content
23177         cmp $tmp $dom || error "file miscompare"
23178
23179         return 0
23180 }
23181 run_test 271f "DoM: read on open (200K file and read tail)"
23182
23183 test_271g() {
23184         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23185                 skip "Skipping due to old client or server version"
23186
23187         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23188         # to get layout
23189         $CHECKSTAT -t file $DIR1/$tfile
23190
23191         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23192         MULTIOP_PID=$!
23193         sleep 1
23194         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23195         $LCTL set_param fail_loc=0x80000314
23196         rm $DIR1/$tfile || error "Unlink fails"
23197         RC=$?
23198         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23199         [ $RC -eq 0 ] || error "Failed write to stale object"
23200 }
23201 run_test 271g "Discard DoM data vs client flush race"
23202
23203 test_272a() {
23204         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23205                 skip "Need MDS version at least 2.11.50"
23206
23207         local dom=$DIR/$tdir/dom
23208         mkdir -p $DIR/$tdir
23209
23210         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23211         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23212                 error "failed to write data into $dom"
23213         local old_md5=$(md5sum $dom)
23214
23215         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23216                 error "failed to migrate to the same DoM component"
23217
23218         local new_md5=$(md5sum $dom)
23219
23220         [ "$old_md5" == "$new_md5" ] ||
23221                 error "md5sum differ: $old_md5, $new_md5"
23222
23223         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23224                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23225 }
23226 run_test 272a "DoM migration: new layout with the same DOM component"
23227
23228 test_272b() {
23229         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23230                 skip "Need MDS version at least 2.11.50"
23231
23232         local dom=$DIR/$tdir/dom
23233         mkdir -p $DIR/$tdir
23234         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23235
23236         local mdtidx=$($LFS getstripe -m $dom)
23237         local mdtname=MDT$(printf %04x $mdtidx)
23238         local facet=mds$((mdtidx + 1))
23239
23240         local mdtfree1=$(do_facet $facet \
23241                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23242         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23243                 error "failed to write data into $dom"
23244         local old_md5=$(md5sum $dom)
23245         cancel_lru_locks mdc
23246         local mdtfree1=$(do_facet $facet \
23247                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23248
23249         $LFS migrate -c2 $dom ||
23250                 error "failed to migrate to the new composite layout"
23251         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23252                 error "MDT stripe was not removed"
23253
23254         cancel_lru_locks mdc
23255         local new_md5=$(md5sum $dom)
23256         [ "$old_md5" == "$new_md5" ] ||
23257                 error "$old_md5 != $new_md5"
23258
23259         # Skip free space checks with ZFS
23260         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23261                 local mdtfree2=$(do_facet $facet \
23262                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23263                 [ $mdtfree2 -gt $mdtfree1 ] ||
23264                         error "MDT space is not freed after migration"
23265         fi
23266         return 0
23267 }
23268 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23269
23270 test_272c() {
23271         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23272                 skip "Need MDS version at least 2.11.50"
23273
23274         local dom=$DIR/$tdir/$tfile
23275         mkdir -p $DIR/$tdir
23276         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23277
23278         local mdtidx=$($LFS getstripe -m $dom)
23279         local mdtname=MDT$(printf %04x $mdtidx)
23280         local facet=mds$((mdtidx + 1))
23281
23282         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23283                 error "failed to write data into $dom"
23284         local old_md5=$(md5sum $dom)
23285         cancel_lru_locks mdc
23286         local mdtfree1=$(do_facet $facet \
23287                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23288
23289         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23290                 error "failed to migrate to the new composite layout"
23291         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23292                 error "MDT stripe was not removed"
23293
23294         cancel_lru_locks mdc
23295         local new_md5=$(md5sum $dom)
23296         [ "$old_md5" == "$new_md5" ] ||
23297                 error "$old_md5 != $new_md5"
23298
23299         # Skip free space checks with ZFS
23300         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23301                 local mdtfree2=$(do_facet $facet \
23302                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23303                 [ $mdtfree2 -gt $mdtfree1 ] ||
23304                         error "MDS space is not freed after migration"
23305         fi
23306         return 0
23307 }
23308 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23309
23310 test_272d() {
23311         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23312                 skip "Need MDS version at least 2.12.55"
23313
23314         local dom=$DIR/$tdir/$tfile
23315         mkdir -p $DIR/$tdir
23316         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23317
23318         local mdtidx=$($LFS getstripe -m $dom)
23319         local mdtname=MDT$(printf %04x $mdtidx)
23320         local facet=mds$((mdtidx + 1))
23321
23322         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23323                 error "failed to write data into $dom"
23324         local old_md5=$(md5sum $dom)
23325         cancel_lru_locks mdc
23326         local mdtfree1=$(do_facet $facet \
23327                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23328
23329         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23330                 error "failed mirroring to the new composite layout"
23331         $LFS mirror resync $dom ||
23332                 error "failed mirror resync"
23333         $LFS mirror split --mirror-id 1 -d $dom ||
23334                 error "failed mirror split"
23335
23336         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23337                 error "MDT stripe was not removed"
23338
23339         cancel_lru_locks mdc
23340         local new_md5=$(md5sum $dom)
23341         [ "$old_md5" == "$new_md5" ] ||
23342                 error "$old_md5 != $new_md5"
23343
23344         # Skip free space checks with ZFS
23345         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23346                 local mdtfree2=$(do_facet $facet \
23347                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23348                 [ $mdtfree2 -gt $mdtfree1 ] ||
23349                         error "MDS space is not freed after DOM mirror deletion"
23350         fi
23351         return 0
23352 }
23353 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23354
23355 test_272e() {
23356         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23357                 skip "Need MDS version at least 2.12.55"
23358
23359         local dom=$DIR/$tdir/$tfile
23360         mkdir -p $DIR/$tdir
23361         $LFS setstripe -c 2 $dom
23362
23363         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23364                 error "failed to write data into $dom"
23365         local old_md5=$(md5sum $dom)
23366         cancel_lru_locks
23367
23368         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23369                 error "failed mirroring to the DOM layout"
23370         $LFS mirror resync $dom ||
23371                 error "failed mirror resync"
23372         $LFS mirror split --mirror-id 1 -d $dom ||
23373                 error "failed mirror split"
23374
23375         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23376                 error "MDT stripe wasn't set"
23377
23378         cancel_lru_locks
23379         local new_md5=$(md5sum $dom)
23380         [ "$old_md5" == "$new_md5" ] ||
23381                 error "$old_md5 != $new_md5"
23382
23383         return 0
23384 }
23385 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23386
23387 test_272f() {
23388         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23389                 skip "Need MDS version at least 2.12.55"
23390
23391         local dom=$DIR/$tdir/$tfile
23392         mkdir -p $DIR/$tdir
23393         $LFS setstripe -c 2 $dom
23394
23395         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23396                 error "failed to write data into $dom"
23397         local old_md5=$(md5sum $dom)
23398         cancel_lru_locks
23399
23400         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23401                 error "failed migrating to the DOM file"
23402
23403         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23404                 error "MDT stripe wasn't set"
23405
23406         cancel_lru_locks
23407         local new_md5=$(md5sum $dom)
23408         [ "$old_md5" != "$new_md5" ] &&
23409                 error "$old_md5 != $new_md5"
23410
23411         return 0
23412 }
23413 run_test 272f "DoM migration: OST-striped file to DOM file"
23414
23415 test_273a() {
23416         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23417                 skip "Need MDS version at least 2.11.50"
23418
23419         # Layout swap cannot be done if either file has DOM component,
23420         # this will never be supported, migration should be used instead
23421
23422         local dom=$DIR/$tdir/$tfile
23423         mkdir -p $DIR/$tdir
23424
23425         $LFS setstripe -c2 ${dom}_plain
23426         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23427         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23428                 error "can swap layout with DoM component"
23429         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23430                 error "can swap layout with DoM component"
23431
23432         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23433         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23434                 error "can swap layout with DoM component"
23435         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23436                 error "can swap layout with DoM component"
23437         return 0
23438 }
23439 run_test 273a "DoM: layout swapping should fail with DOM"
23440
23441 test_273b() {
23442         mkdir -p $DIR/$tdir
23443         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23444
23445 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23446         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23447
23448         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23449 }
23450 run_test 273b "DoM: race writeback and object destroy"
23451
23452 test_275() {
23453         remote_ost_nodsh && skip "remote OST with nodsh"
23454         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23455                 skip "Need OST version >= 2.10.57"
23456
23457         local file=$DIR/$tfile
23458         local oss
23459
23460         oss=$(comma_list $(osts_nodes))
23461
23462         dd if=/dev/urandom of=$file bs=1M count=2 ||
23463                 error "failed to create a file"
23464         cancel_lru_locks osc
23465
23466         #lock 1
23467         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23468                 error "failed to read a file"
23469
23470 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23471         $LCTL set_param fail_loc=0x8000031f
23472
23473         cancel_lru_locks osc &
23474         sleep 1
23475
23476 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23477         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23478         #IO takes another lock, but matches the PENDING one
23479         #and places it to the IO RPC
23480         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23481                 error "failed to read a file with PENDING lock"
23482 }
23483 run_test 275 "Read on a canceled duplicate lock"
23484
23485 test_276() {
23486         remote_ost_nodsh && skip "remote OST with nodsh"
23487         local pid
23488
23489         do_facet ost1 "(while true; do \
23490                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23491                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23492         pid=$!
23493
23494         for LOOP in $(seq 20); do
23495                 stop ost1
23496                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23497         done
23498         kill -9 $pid
23499         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23500                 rm $TMP/sanity_276_pid"
23501 }
23502 run_test 276 "Race between mount and obd_statfs"
23503
23504 test_277() {
23505         $LCTL set_param ldlm.namespaces.*.lru_size=0
23506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23507         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23508                         grep ^used_mb | awk '{print $2}')
23509         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23510         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23511                 oflag=direct conv=notrunc
23512         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23513                         grep ^used_mb | awk '{print $2}')
23514         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23515 }
23516 run_test 277 "Direct IO shall drop page cache"
23517
23518 test_278() {
23519         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23520         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23521         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23522                 skip "needs the same host for mdt1 mdt2" && return
23523
23524         local pid1
23525         local pid2
23526
23527 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23528         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23529         stop mds2 &
23530         pid2=$!
23531
23532         stop mds1
23533
23534         echo "Starting MDTs"
23535         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23536         wait $pid2
23537 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23538 #will return NULL
23539         do_facet mds2 $LCTL set_param fail_loc=0
23540
23541         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23542         wait_recovery_complete mds2
23543 }
23544 run_test 278 "Race starting MDS between MDTs stop/start"
23545
23546 test_280() {
23547         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23548                 skip "Need MGS version at least 2.13.52"
23549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23550         combined_mgs_mds || skip "needs combined MGS/MDT"
23551
23552         umount_client $MOUNT
23553 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23554         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23555
23556         mount_client $MOUNT &
23557         sleep 1
23558         stop mgs || error "stop mgs failed"
23559         #for a race mgs would crash
23560         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23561         # make sure we unmount client before remounting
23562         wait
23563         umount_client $MOUNT
23564         mount_client $MOUNT || error "mount client failed"
23565 }
23566 run_test 280 "Race between MGS umount and client llog processing"
23567
23568 cleanup_test_300() {
23569         trap 0
23570         umask $SAVE_UMASK
23571 }
23572 test_striped_dir() {
23573         local mdt_index=$1
23574         local stripe_count
23575         local stripe_index
23576
23577         mkdir -p $DIR/$tdir
23578
23579         SAVE_UMASK=$(umask)
23580         trap cleanup_test_300 RETURN EXIT
23581
23582         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23583                                                 $DIR/$tdir/striped_dir ||
23584                 error "set striped dir error"
23585
23586         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23587         [ "$mode" = "755" ] || error "expect 755 got $mode"
23588
23589         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23590                 error "getdirstripe failed"
23591         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23592         if [ "$stripe_count" != "2" ]; then
23593                 error "1:stripe_count is $stripe_count, expect 2"
23594         fi
23595         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23596         if [ "$stripe_count" != "2" ]; then
23597                 error "2:stripe_count is $stripe_count, expect 2"
23598         fi
23599
23600         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23601         if [ "$stripe_index" != "$mdt_index" ]; then
23602                 error "stripe_index is $stripe_index, expect $mdt_index"
23603         fi
23604
23605         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23606                 error "nlink error after create striped dir"
23607
23608         mkdir $DIR/$tdir/striped_dir/a
23609         mkdir $DIR/$tdir/striped_dir/b
23610
23611         stat $DIR/$tdir/striped_dir/a ||
23612                 error "create dir under striped dir failed"
23613         stat $DIR/$tdir/striped_dir/b ||
23614                 error "create dir under striped dir failed"
23615
23616         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23617                 error "nlink error after mkdir"
23618
23619         rmdir $DIR/$tdir/striped_dir/a
23620         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23621                 error "nlink error after rmdir"
23622
23623         rmdir $DIR/$tdir/striped_dir/b
23624         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23625                 error "nlink error after rmdir"
23626
23627         chattr +i $DIR/$tdir/striped_dir
23628         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23629                 error "immutable flags not working under striped dir!"
23630         chattr -i $DIR/$tdir/striped_dir
23631
23632         rmdir $DIR/$tdir/striped_dir ||
23633                 error "rmdir striped dir error"
23634
23635         cleanup_test_300
23636
23637         true
23638 }
23639
23640 test_300a() {
23641         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23642                 skip "skipped for lustre < 2.7.0"
23643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23645
23646         test_striped_dir 0 || error "failed on striped dir on MDT0"
23647         test_striped_dir 1 || error "failed on striped dir on MDT0"
23648 }
23649 run_test 300a "basic striped dir sanity test"
23650
23651 test_300b() {
23652         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23653                 skip "skipped for lustre < 2.7.0"
23654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23655         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23656
23657         local i
23658         local mtime1
23659         local mtime2
23660         local mtime3
23661
23662         test_mkdir $DIR/$tdir || error "mkdir fail"
23663         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23664                 error "set striped dir error"
23665         for i in {0..9}; do
23666                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23667                 sleep 1
23668                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23669                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23670                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23671                 sleep 1
23672                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23673                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23674                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23675         done
23676         true
23677 }
23678 run_test 300b "check ctime/mtime for striped dir"
23679
23680 test_300c() {
23681         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23682                 skip "skipped for lustre < 2.7.0"
23683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23685
23686         local file_count
23687
23688         mkdir_on_mdt0 $DIR/$tdir
23689         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23690                 error "set striped dir error"
23691
23692         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23693                 error "chown striped dir failed"
23694
23695         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23696                 error "create 5k files failed"
23697
23698         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23699
23700         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23701
23702         rm -rf $DIR/$tdir
23703 }
23704 run_test 300c "chown && check ls under striped directory"
23705
23706 test_300d() {
23707         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23708                 skip "skipped for lustre < 2.7.0"
23709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23710         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23711
23712         local stripe_count
23713         local file
23714
23715         mkdir -p $DIR/$tdir
23716         $LFS setstripe -c 2 $DIR/$tdir
23717
23718         #local striped directory
23719         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23720                 error "set striped dir error"
23721         #look at the directories for debug purposes
23722         ls -l $DIR/$tdir
23723         $LFS getdirstripe $DIR/$tdir
23724         ls -l $DIR/$tdir/striped_dir
23725         $LFS getdirstripe $DIR/$tdir/striped_dir
23726         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23727                 error "create 10 files failed"
23728
23729         #remote striped directory
23730         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23731                 error "set striped dir error"
23732         #look at the directories for debug purposes
23733         ls -l $DIR/$tdir
23734         $LFS getdirstripe $DIR/$tdir
23735         ls -l $DIR/$tdir/remote_striped_dir
23736         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23737         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23738                 error "create 10 files failed"
23739
23740         for file in $(find $DIR/$tdir); do
23741                 stripe_count=$($LFS getstripe -c $file)
23742                 [ $stripe_count -eq 2 ] ||
23743                         error "wrong stripe $stripe_count for $file"
23744         done
23745
23746         rm -rf $DIR/$tdir
23747 }
23748 run_test 300d "check default stripe under striped directory"
23749
23750 test_300e() {
23751         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23752                 skip "Need MDS version at least 2.7.55"
23753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23754         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23755
23756         local stripe_count
23757         local file
23758
23759         mkdir -p $DIR/$tdir
23760
23761         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23762                 error "set striped dir error"
23763
23764         touch $DIR/$tdir/striped_dir/a
23765         touch $DIR/$tdir/striped_dir/b
23766         touch $DIR/$tdir/striped_dir/c
23767
23768         mkdir $DIR/$tdir/striped_dir/dir_a
23769         mkdir $DIR/$tdir/striped_dir/dir_b
23770         mkdir $DIR/$tdir/striped_dir/dir_c
23771
23772         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23773                 error "set striped adir under striped dir error"
23774
23775         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23776                 error "set striped bdir under striped dir error"
23777
23778         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23779                 error "set striped cdir under striped dir error"
23780
23781         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23782                 error "rename dir under striped dir fails"
23783
23784         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23785                 error "rename dir under different stripes fails"
23786
23787         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23788                 error "rename file under striped dir should succeed"
23789
23790         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23791                 error "rename dir under striped dir should succeed"
23792
23793         rm -rf $DIR/$tdir
23794 }
23795 run_test 300e "check rename under striped directory"
23796
23797 test_300f() {
23798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23799         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23800         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23801                 skip "Need MDS version at least 2.7.55"
23802
23803         local stripe_count
23804         local file
23805
23806         rm -rf $DIR/$tdir
23807         mkdir -p $DIR/$tdir
23808
23809         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23810                 error "set striped dir error"
23811
23812         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23813                 error "set striped dir error"
23814
23815         touch $DIR/$tdir/striped_dir/a
23816         mkdir $DIR/$tdir/striped_dir/dir_a
23817         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23818                 error "create striped dir under striped dir fails"
23819
23820         touch $DIR/$tdir/striped_dir1/b
23821         mkdir $DIR/$tdir/striped_dir1/dir_b
23822         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23823                 error "create striped dir under striped dir fails"
23824
23825         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23826                 error "rename dir under different striped dir should fail"
23827
23828         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23829                 error "rename striped dir under diff striped dir should fail"
23830
23831         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23832                 error "rename file under diff striped dirs fails"
23833
23834         rm -rf $DIR/$tdir
23835 }
23836 run_test 300f "check rename cross striped directory"
23837
23838 test_300_check_default_striped_dir()
23839 {
23840         local dirname=$1
23841         local default_count=$2
23842         local default_index=$3
23843         local stripe_count
23844         local stripe_index
23845         local dir_stripe_index
23846         local dir
23847
23848         echo "checking $dirname $default_count $default_index"
23849         $LFS setdirstripe -D -c $default_count -i $default_index \
23850                                 -H all_char $DIR/$tdir/$dirname ||
23851                 error "set default stripe on striped dir error"
23852         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23853         [ $stripe_count -eq $default_count ] ||
23854                 error "expect $default_count get $stripe_count for $dirname"
23855
23856         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23857         [ $stripe_index -eq $default_index ] ||
23858                 error "expect $default_index get $stripe_index for $dirname"
23859
23860         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23861                                                 error "create dirs failed"
23862
23863         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23864         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23865         for dir in $(find $DIR/$tdir/$dirname/*); do
23866                 stripe_count=$($LFS getdirstripe -c $dir)
23867                 (( $stripe_count == $default_count )) ||
23868                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23869                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23870                 error "stripe count $default_count != $stripe_count for $dir"
23871
23872                 stripe_index=$($LFS getdirstripe -i $dir)
23873                 [ $default_index -eq -1 ] ||
23874                         [ $stripe_index -eq $default_index ] ||
23875                         error "$stripe_index != $default_index for $dir"
23876
23877                 #check default stripe
23878                 stripe_count=$($LFS getdirstripe -D -c $dir)
23879                 [ $stripe_count -eq $default_count ] ||
23880                 error "default count $default_count != $stripe_count for $dir"
23881
23882                 stripe_index=$($LFS getdirstripe -D -i $dir)
23883                 [ $stripe_index -eq $default_index ] ||
23884                 error "default index $default_index != $stripe_index for $dir"
23885         done
23886         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23887 }
23888
23889 test_300g() {
23890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23891         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23892                 skip "Need MDS version at least 2.7.55"
23893
23894         local dir
23895         local stripe_count
23896         local stripe_index
23897
23898         mkdir_on_mdt0 $DIR/$tdir
23899         mkdir $DIR/$tdir/normal_dir
23900
23901         #Checking when client cache stripe index
23902         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23903         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23904                 error "create striped_dir failed"
23905
23906         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23907                 error "create dir0 fails"
23908         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23909         [ $stripe_index -eq 0 ] ||
23910                 error "dir0 expect index 0 got $stripe_index"
23911
23912         mkdir $DIR/$tdir/striped_dir/dir1 ||
23913                 error "create dir1 fails"
23914         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23915         [ $stripe_index -eq 1 ] ||
23916                 error "dir1 expect index 1 got $stripe_index"
23917
23918         #check default stripe count/stripe index
23919         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23920         test_300_check_default_striped_dir normal_dir 1 0
23921         test_300_check_default_striped_dir normal_dir -1 1
23922         test_300_check_default_striped_dir normal_dir 2 -1
23923
23924         #delete default stripe information
23925         echo "delete default stripeEA"
23926         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23927                 error "set default stripe on striped dir error"
23928
23929         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23930         for dir in $(find $DIR/$tdir/normal_dir/*); do
23931                 stripe_count=$($LFS getdirstripe -c $dir)
23932                 [ $stripe_count -eq 0 ] ||
23933                         error "expect 1 get $stripe_count for $dir"
23934         done
23935 }
23936 run_test 300g "check default striped directory for normal directory"
23937
23938 test_300h() {
23939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23940         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23941                 skip "Need MDS version at least 2.7.55"
23942
23943         local dir
23944         local stripe_count
23945
23946         mkdir $DIR/$tdir
23947         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23948                 error "set striped dir error"
23949
23950         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23951         test_300_check_default_striped_dir striped_dir 1 0
23952         test_300_check_default_striped_dir striped_dir -1 1
23953         test_300_check_default_striped_dir striped_dir 2 -1
23954
23955         #delete default stripe information
23956         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23957                 error "set default stripe on striped dir error"
23958
23959         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23960         for dir in $(find $DIR/$tdir/striped_dir/*); do
23961                 stripe_count=$($LFS getdirstripe -c $dir)
23962                 [ $stripe_count -eq 0 ] ||
23963                         error "expect 1 get $stripe_count for $dir"
23964         done
23965 }
23966 run_test 300h "check default striped directory for striped directory"
23967
23968 test_300i() {
23969         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23970         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23971         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23972                 skip "Need MDS version at least 2.7.55"
23973
23974         local stripe_count
23975         local file
23976
23977         mkdir $DIR/$tdir
23978
23979         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23980                 error "set striped dir error"
23981
23982         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23983                 error "create files under striped dir failed"
23984
23985         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23986                 error "set striped hashdir error"
23987
23988         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23989                 error "create dir0 under hash dir failed"
23990         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23991                 error "create dir1 under hash dir failed"
23992         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23993                 error "create dir2 under hash dir failed"
23994
23995         # unfortunately, we need to umount to clear dir layout cache for now
23996         # once we fully implement dir layout, we can drop this
23997         umount_client $MOUNT || error "umount failed"
23998         mount_client $MOUNT || error "mount failed"
23999
24000         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24001         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24002         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24003
24004         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24005                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24006                         error "create crush2 dir $tdir/hashdir/d3 failed"
24007                 $LFS find -H crush2 $DIR/$tdir/hashdir
24008                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24009                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24010
24011                 # mkdir with an invalid hash type (hash=fail_val) from client
24012                 # should be replaced on MDS with a valid (default) hash type
24013                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24014                 $LCTL set_param fail_loc=0x1901 fail_val=99
24015                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24016
24017                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24018                 local expect=$(do_facet mds1 \
24019                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24020                 [[ $hash == $expect ]] ||
24021                         error "d99 hash '$hash' != expected hash '$expect'"
24022         fi
24023
24024         #set the stripe to be unknown hash type on read
24025         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24026         $LCTL set_param fail_loc=0x1901 fail_val=99
24027         for ((i = 0; i < 10; i++)); do
24028                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24029                         error "stat f-$i failed"
24030                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24031         done
24032
24033         touch $DIR/$tdir/striped_dir/f0 &&
24034                 error "create under striped dir with unknown hash should fail"
24035
24036         $LCTL set_param fail_loc=0
24037
24038         umount_client $MOUNT || error "umount failed"
24039         mount_client $MOUNT || error "mount failed"
24040
24041         return 0
24042 }
24043 run_test 300i "client handle unknown hash type striped directory"
24044
24045 test_300j() {
24046         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24048         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24049                 skip "Need MDS version at least 2.7.55"
24050
24051         local stripe_count
24052         local file
24053
24054         mkdir $DIR/$tdir
24055
24056         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24057         $LCTL set_param fail_loc=0x1702
24058         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24059                 error "set striped dir error"
24060
24061         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24062                 error "create files under striped dir failed"
24063
24064         $LCTL set_param fail_loc=0
24065
24066         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24067
24068         return 0
24069 }
24070 run_test 300j "test large update record"
24071
24072 test_300k() {
24073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24075         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24076                 skip "Need MDS version at least 2.7.55"
24077
24078         # this test needs a huge transaction
24079         local kb
24080         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24081              osd*.$FSNAME-MDT0000.kbytestotal")
24082         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24083
24084         local stripe_count
24085         local file
24086
24087         mkdir $DIR/$tdir
24088
24089         #define OBD_FAIL_LARGE_STRIPE   0x1703
24090         $LCTL set_param fail_loc=0x1703
24091         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24092                 error "set striped dir error"
24093         $LCTL set_param fail_loc=0
24094
24095         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24096                 error "getstripeddir fails"
24097         rm -rf $DIR/$tdir/striped_dir ||
24098                 error "unlink striped dir fails"
24099
24100         return 0
24101 }
24102 run_test 300k "test large striped directory"
24103
24104 test_300l() {
24105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24106         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24107         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24108                 skip "Need MDS version at least 2.7.55"
24109
24110         local stripe_index
24111
24112         test_mkdir -p $DIR/$tdir/striped_dir
24113         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24114                         error "chown $RUNAS_ID failed"
24115         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24116                 error "set default striped dir failed"
24117
24118         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24119         $LCTL set_param fail_loc=0x80000158
24120         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24121
24122         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24123         [ $stripe_index -eq 1 ] ||
24124                 error "expect 1 get $stripe_index for $dir"
24125 }
24126 run_test 300l "non-root user to create dir under striped dir with stale layout"
24127
24128 test_300m() {
24129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24130         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24131         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24132                 skip "Need MDS version at least 2.7.55"
24133
24134         mkdir -p $DIR/$tdir/striped_dir
24135         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24136                 error "set default stripes dir error"
24137
24138         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24139
24140         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24141         [ $stripe_count -eq 0 ] ||
24142                         error "expect 0 get $stripe_count for a"
24143
24144         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24145                 error "set default stripes dir error"
24146
24147         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24148
24149         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24150         [ $stripe_count -eq 0 ] ||
24151                         error "expect 0 get $stripe_count for b"
24152
24153         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24154                 error "set default stripes dir error"
24155
24156         mkdir $DIR/$tdir/striped_dir/c &&
24157                 error "default stripe_index is invalid, mkdir c should fails"
24158
24159         rm -rf $DIR/$tdir || error "rmdir fails"
24160 }
24161 run_test 300m "setstriped directory on single MDT FS"
24162
24163 cleanup_300n() {
24164         local list=$(comma_list $(mdts_nodes))
24165
24166         trap 0
24167         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24168 }
24169
24170 test_300n() {
24171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24172         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24173         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24174                 skip "Need MDS version at least 2.7.55"
24175         remote_mds_nodsh && skip "remote MDS with nodsh"
24176
24177         local stripe_index
24178         local list=$(comma_list $(mdts_nodes))
24179
24180         trap cleanup_300n RETURN EXIT
24181         mkdir -p $DIR/$tdir
24182         chmod 777 $DIR/$tdir
24183         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24184                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24185                 error "create striped dir succeeds with gid=0"
24186
24187         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24188         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24189                 error "create striped dir fails with gid=-1"
24190
24191         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24192         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24193                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24194                 error "set default striped dir succeeds with gid=0"
24195
24196
24197         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24198         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24199                 error "set default striped dir fails with gid=-1"
24200
24201
24202         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24203         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24204                                         error "create test_dir fails"
24205         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24206                                         error "create test_dir1 fails"
24207         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24208                                         error "create test_dir2 fails"
24209         cleanup_300n
24210 }
24211 run_test 300n "non-root user to create dir under striped dir with default EA"
24212
24213 test_300o() {
24214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24215         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24216         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24217                 skip "Need MDS version at least 2.7.55"
24218
24219         local numfree1
24220         local numfree2
24221
24222         mkdir -p $DIR/$tdir
24223
24224         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24225         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24226         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24227                 skip "not enough free inodes $numfree1 $numfree2"
24228         fi
24229
24230         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24231         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24232         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24233                 skip "not enough free space $numfree1 $numfree2"
24234         fi
24235
24236         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24237                 error "setdirstripe fails"
24238
24239         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24240                 error "create dirs fails"
24241
24242         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24243         ls $DIR/$tdir/striped_dir > /dev/null ||
24244                 error "ls striped dir fails"
24245         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24246                 error "unlink big striped dir fails"
24247 }
24248 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24249
24250 test_300p() {
24251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24252         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24253         remote_mds_nodsh && skip "remote MDS with nodsh"
24254
24255         mkdir_on_mdt0 $DIR/$tdir
24256
24257         #define OBD_FAIL_OUT_ENOSPC     0x1704
24258         do_facet mds2 lctl set_param fail_loc=0x80001704
24259         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24260                  && error "create striped directory should fail"
24261
24262         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24263
24264         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24265         true
24266 }
24267 run_test 300p "create striped directory without space"
24268
24269 test_300q() {
24270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24272
24273         local fd=$(free_fd)
24274         local cmd="exec $fd<$tdir"
24275         cd $DIR
24276         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24277         eval $cmd
24278         cmd="exec $fd<&-"
24279         trap "eval $cmd" EXIT
24280         cd $tdir || error "cd $tdir fails"
24281         rmdir  ../$tdir || error "rmdir $tdir fails"
24282         mkdir local_dir && error "create dir succeeds"
24283         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24284         eval $cmd
24285         return 0
24286 }
24287 run_test 300q "create remote directory under orphan directory"
24288
24289 test_300r() {
24290         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24291                 skip "Need MDS version at least 2.7.55" && return
24292         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24293
24294         mkdir $DIR/$tdir
24295
24296         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24297                 error "set striped dir error"
24298
24299         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24300                 error "getstripeddir fails"
24301
24302         local stripe_count
24303         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24304                       awk '/lmv_stripe_count:/ { print $2 }')
24305
24306         [ $MDSCOUNT -ne $stripe_count ] &&
24307                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24308
24309         rm -rf $DIR/$tdir/striped_dir ||
24310                 error "unlink striped dir fails"
24311 }
24312 run_test 300r "test -1 striped directory"
24313
24314 test_300s_helper() {
24315         local count=$1
24316
24317         local stripe_dir=$DIR/$tdir/striped_dir.$count
24318
24319         $LFS mkdir -c $count $stripe_dir ||
24320                 error "lfs mkdir -c error"
24321
24322         $LFS getdirstripe $stripe_dir ||
24323                 error "lfs getdirstripe fails"
24324
24325         local stripe_count
24326         stripe_count=$($LFS getdirstripe $stripe_dir |
24327                       awk '/lmv_stripe_count:/ { print $2 }')
24328
24329         [ $count -ne $stripe_count ] &&
24330                 error_noexit "bad stripe count $stripe_count expected $count"
24331
24332         local dupe_stripes
24333         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24334                 awk '/0x/ {count[$1] += 1}; END {
24335                         for (idx in count) {
24336                                 if (count[idx]>1) {
24337                                         print "index " idx " count " count[idx]
24338                                 }
24339                         }
24340                 }')
24341
24342         if [[ -n "$dupe_stripes" ]] ; then
24343                 lfs getdirstripe $stripe_dir
24344                 error_noexit "Dupe MDT above: $dupe_stripes "
24345         fi
24346
24347         rm -rf $stripe_dir ||
24348                 error_noexit "unlink $stripe_dir fails"
24349 }
24350
24351 test_300s() {
24352         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24353                 skip "Need MDS version at least 2.7.55" && return
24354         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24355
24356         mkdir $DIR/$tdir
24357         for count in $(seq 2 $MDSCOUNT); do
24358                 test_300s_helper $count
24359         done
24360 }
24361 run_test 300s "test lfs mkdir -c without -i"
24362
24363 test_300t() {
24364         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24365                 skip "need MDS 2.14.55 or later"
24366         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24367
24368         local testdir="$DIR/$tdir/striped_dir"
24369         local dir1=$testdir/dir1
24370         local dir2=$testdir/dir2
24371
24372         mkdir -p $testdir
24373
24374         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24375                 error "failed to set default stripe count for $testdir"
24376
24377         mkdir $dir1
24378         local stripe_count=$($LFS getdirstripe -c $dir1)
24379
24380         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24381
24382         local max_count=$((MDSCOUNT - 1))
24383         local mdts=$(comma_list $(mdts_nodes))
24384
24385         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24386         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24387
24388         mkdir $dir2
24389         stripe_count=$($LFS getdirstripe -c $dir2)
24390
24391         (( $stripe_count == $max_count )) || error "wrong stripe count"
24392 }
24393 run_test 300t "test max_mdt_stripecount"
24394
24395 prepare_remote_file() {
24396         mkdir $DIR/$tdir/src_dir ||
24397                 error "create remote source failed"
24398
24399         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24400                  error "cp to remote source failed"
24401         touch $DIR/$tdir/src_dir/a
24402
24403         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24404                 error "create remote target dir failed"
24405
24406         touch $DIR/$tdir/tgt_dir/b
24407
24408         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24409                 error "rename dir cross MDT failed!"
24410
24411         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24412                 error "src_child still exists after rename"
24413
24414         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24415                 error "missing file(a) after rename"
24416
24417         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24418                 error "diff after rename"
24419 }
24420
24421 test_310a() {
24422         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24424
24425         local remote_file=$DIR/$tdir/tgt_dir/b
24426
24427         mkdir -p $DIR/$tdir
24428
24429         prepare_remote_file || error "prepare remote file failed"
24430
24431         #open-unlink file
24432         $OPENUNLINK $remote_file $remote_file ||
24433                 error "openunlink $remote_file failed"
24434         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24435 }
24436 run_test 310a "open unlink remote file"
24437
24438 test_310b() {
24439         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24441
24442         local remote_file=$DIR/$tdir/tgt_dir/b
24443
24444         mkdir -p $DIR/$tdir
24445
24446         prepare_remote_file || error "prepare remote file failed"
24447
24448         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24449         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24450         $CHECKSTAT -t file $remote_file || error "check file failed"
24451 }
24452 run_test 310b "unlink remote file with multiple links while open"
24453
24454 test_310c() {
24455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24456         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24457
24458         local remote_file=$DIR/$tdir/tgt_dir/b
24459
24460         mkdir -p $DIR/$tdir
24461
24462         prepare_remote_file || error "prepare remote file failed"
24463
24464         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24465         multiop_bg_pause $remote_file O_uc ||
24466                         error "mulitop failed for remote file"
24467         MULTIPID=$!
24468         $MULTIOP $DIR/$tfile Ouc
24469         kill -USR1 $MULTIPID
24470         wait $MULTIPID
24471 }
24472 run_test 310c "open-unlink remote file with multiple links"
24473
24474 #LU-4825
24475 test_311() {
24476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24477         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24478         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24479                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24480         remote_mds_nodsh && skip "remote MDS with nodsh"
24481
24482         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24483         local mdts=$(comma_list $(mdts_nodes))
24484
24485         mkdir -p $DIR/$tdir
24486         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24487         createmany -o $DIR/$tdir/$tfile. 1000
24488
24489         # statfs data is not real time, let's just calculate it
24490         old_iused=$((old_iused + 1000))
24491
24492         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24493                         osp.*OST0000*MDT0000.create_count")
24494         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24495                                 osp.*OST0000*MDT0000.max_create_count")
24496         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24497
24498         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24499         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24500         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24501
24502         unlinkmany $DIR/$tdir/$tfile. 1000
24503
24504         do_nodes $mdts "$LCTL set_param -n \
24505                         osp.*OST0000*.max_create_count=$max_count"
24506         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24507                 do_nodes $mdts "$LCTL set_param -n \
24508                                 osp.*OST0000*.create_count=$count"
24509         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24510                         grep "=0" && error "create_count is zero"
24511
24512         local new_iused
24513         for i in $(seq 120); do
24514                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24515                 # system may be too busy to destroy all objs in time, use
24516                 # a somewhat small value to not fail autotest
24517                 [ $((old_iused - new_iused)) -gt 400 ] && break
24518                 sleep 1
24519         done
24520
24521         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24522         [ $((old_iused - new_iused)) -gt 400 ] ||
24523                 error "objs not destroyed after unlink"
24524 }
24525 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24526
24527 zfs_oid_to_objid()
24528 {
24529         local ost=$1
24530         local objid=$2
24531
24532         local vdevdir=$(dirname $(facet_vdevice $ost))
24533         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24534         local zfs_zapid=$(do_facet $ost $cmd |
24535                           grep -w "/O/0/d$((objid%32))" -C 5 |
24536                           awk '/Object/{getline; print $1}')
24537         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24538                           awk "/$objid = /"'{printf $3}')
24539
24540         echo $zfs_objid
24541 }
24542
24543 zfs_object_blksz() {
24544         local ost=$1
24545         local objid=$2
24546
24547         local vdevdir=$(dirname $(facet_vdevice $ost))
24548         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24549         local blksz=$(do_facet $ost $cmd $objid |
24550                       awk '/dblk/{getline; printf $4}')
24551
24552         case "${blksz: -1}" in
24553                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24554                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24555                 *) ;;
24556         esac
24557
24558         echo $blksz
24559 }
24560
24561 test_312() { # LU-4856
24562         remote_ost_nodsh && skip "remote OST with nodsh"
24563         [ "$ost1_FSTYPE" = "zfs" ] ||
24564                 skip_env "the test only applies to zfs"
24565
24566         local max_blksz=$(do_facet ost1 \
24567                           $ZFS get -p recordsize $(facet_device ost1) |
24568                           awk '!/VALUE/{print $3}')
24569
24570         # to make life a little bit easier
24571         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24572         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24573
24574         local tf=$DIR/$tdir/$tfile
24575         touch $tf
24576         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24577
24578         # Get ZFS object id
24579         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24580         # block size change by sequential overwrite
24581         local bs
24582
24583         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24584                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24585
24586                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24587                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24588         done
24589         rm -f $tf
24590
24591         # block size change by sequential append write
24592         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24593         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24594         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24595         local count
24596
24597         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24598                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24599                         oflag=sync conv=notrunc
24600
24601                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24602                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24603                         error "blksz error, actual $blksz, " \
24604                                 "expected: 2 * $count * $PAGE_SIZE"
24605         done
24606         rm -f $tf
24607
24608         # random write
24609         touch $tf
24610         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24611         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24612
24613         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24614         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24615         [ $blksz -eq $PAGE_SIZE ] ||
24616                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24617
24618         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24619         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24620         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24621
24622         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24623         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24624         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24625 }
24626 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24627
24628 test_313() {
24629         remote_ost_nodsh && skip "remote OST with nodsh"
24630
24631         local file=$DIR/$tfile
24632
24633         rm -f $file
24634         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24635
24636         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24637         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24638         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24639                 error "write should failed"
24640         do_facet ost1 "$LCTL set_param fail_loc=0"
24641         rm -f $file
24642 }
24643 run_test 313 "io should fail after last_rcvd update fail"
24644
24645 test_314() {
24646         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24647
24648         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24649         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24650         rm -f $DIR/$tfile
24651         wait_delete_completed
24652         do_facet ost1 "$LCTL set_param fail_loc=0"
24653 }
24654 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24655
24656 test_315() { # LU-618
24657         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24658
24659         local file=$DIR/$tfile
24660         rm -f $file
24661
24662         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24663                 error "multiop file write failed"
24664         $MULTIOP $file oO_RDONLY:r4063232_c &
24665         PID=$!
24666
24667         sleep 2
24668
24669         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24670         kill -USR1 $PID
24671
24672         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24673         rm -f $file
24674 }
24675 run_test 315 "read should be accounted"
24676
24677 test_316() {
24678         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24679         large_xattr_enabled || skip "ea_inode feature disabled"
24680
24681         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24682         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24683         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24684         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24685
24686         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24687 }
24688 run_test 316 "lfs migrate of file with large_xattr enabled"
24689
24690 test_317() {
24691         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24692                 skip "Need MDS version at least 2.11.53"
24693         if [ "$ost1_FSTYPE" == "zfs" ]; then
24694                 skip "LU-10370: no implementation for ZFS"
24695         fi
24696
24697         local trunc_sz
24698         local grant_blk_size
24699
24700         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24701                         awk '/grant_block_size:/ { print $2; exit; }')
24702         #
24703         # Create File of size 5M. Truncate it to below size's and verify
24704         # blocks count.
24705         #
24706         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24707                 error "Create file $DIR/$tfile failed"
24708         stack_trap "rm -f $DIR/$tfile" EXIT
24709
24710         for trunc_sz in 2097152 4097 4000 509 0; do
24711                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24712                         error "truncate $tfile to $trunc_sz failed"
24713                 local sz=$(stat --format=%s $DIR/$tfile)
24714                 local blk=$(stat --format=%b $DIR/$tfile)
24715                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24716                                      grant_blk_size) * 8))
24717
24718                 if [[ $blk -ne $trunc_blk ]]; then
24719                         $(which stat) $DIR/$tfile
24720                         error "Expected Block $trunc_blk got $blk for $tfile"
24721                 fi
24722
24723                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24724                         error "Expected Size $trunc_sz got $sz for $tfile"
24725         done
24726
24727         #
24728         # sparse file test
24729         # Create file with a hole and write actual 65536 bytes which aligned
24730         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24731         #
24732         local bs=65536
24733         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24734                 error "Create file : $DIR/$tfile"
24735
24736         #
24737         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24738         # blocks. The block count must drop to 8.
24739         #
24740         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24741                 ((bs - grant_blk_size) + 1)))
24742         $TRUNCATE $DIR/$tfile $trunc_sz ||
24743                 error "truncate $tfile to $trunc_sz failed"
24744
24745         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24746         sz=$(stat --format=%s $DIR/$tfile)
24747         blk=$(stat --format=%b $DIR/$tfile)
24748
24749         if [[ $blk -ne $trunc_bsz ]]; then
24750                 $(which stat) $DIR/$tfile
24751                 error "Expected Block $trunc_bsz got $blk for $tfile"
24752         fi
24753
24754         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24755                 error "Expected Size $trunc_sz got $sz for $tfile"
24756 }
24757 run_test 317 "Verify blocks get correctly update after truncate"
24758
24759 test_318() {
24760         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24761         local old_max_active=$($LCTL get_param -n \
24762                             ${llite_name}.max_read_ahead_async_active \
24763                             2>/dev/null)
24764
24765         $LCTL set_param llite.*.max_read_ahead_async_active=256
24766         local max_active=$($LCTL get_param -n \
24767                            ${llite_name}.max_read_ahead_async_active \
24768                            2>/dev/null)
24769         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24770
24771         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24772                 error "set max_read_ahead_async_active should succeed"
24773
24774         $LCTL set_param llite.*.max_read_ahead_async_active=512
24775         max_active=$($LCTL get_param -n \
24776                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24777         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24778
24779         # restore @max_active
24780         [ $old_max_active -ne 0 ] && $LCTL set_param \
24781                 llite.*.max_read_ahead_async_active=$old_max_active
24782
24783         local old_threshold=$($LCTL get_param -n \
24784                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24785         local max_per_file_mb=$($LCTL get_param -n \
24786                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24787
24788         local invalid=$(($max_per_file_mb + 1))
24789         $LCTL set_param \
24790                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24791                         && error "set $invalid should fail"
24792
24793         local valid=$(($invalid - 1))
24794         $LCTL set_param \
24795                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24796                         error "set $valid should succeed"
24797         local threshold=$($LCTL get_param -n \
24798                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24799         [ $threshold -eq $valid ] || error \
24800                 "expect threshold $valid got $threshold"
24801         $LCTL set_param \
24802                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24803 }
24804 run_test 318 "Verify async readahead tunables"
24805
24806 test_319() {
24807         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24808
24809         local before=$(date +%s)
24810         local evict
24811         local mdir=$DIR/$tdir
24812         local file=$mdir/xxx
24813
24814         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24815         touch $file
24816
24817 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24818         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24819         $LFS migrate -m1 $mdir &
24820
24821         sleep 1
24822         dd if=$file of=/dev/null
24823         wait
24824         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24825           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24826
24827         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24828 }
24829 run_test 319 "lost lease lock on migrate error"
24830
24831 test_398a() { # LU-4198
24832         local ost1_imp=$(get_osc_import_name client ost1)
24833         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24834                          cut -d'.' -f2)
24835
24836         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24837         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24838
24839         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24840         # request a new lock on client
24841         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24842
24843         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24844         #local lock_count=$($LCTL get_param -n \
24845         #                  ldlm.namespaces.$imp_name.lru_size)
24846         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24847
24848         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24849
24850         # no lock cached, should use lockless DIO and not enqueue new lock
24851         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24852                 conv=notrunc ||
24853                 error "dio write failed"
24854         lock_count=$($LCTL get_param -n \
24855                      ldlm.namespaces.$imp_name.lru_size)
24856         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24857
24858         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24859
24860         # no lock cached, should use locked DIO append
24861         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24862                 conv=notrunc || error "DIO append failed"
24863         lock_count=$($LCTL get_param -n \
24864                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24865         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24866 }
24867 run_test 398a "direct IO should cancel lock otherwise lockless"
24868
24869 test_398b() { # LU-4198
24870         which fio || skip_env "no fio installed"
24871         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24872
24873         local size=48
24874         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24875
24876         local njobs=4
24877         # Single page, multiple pages, stripe size, 4*stripe size
24878         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24879                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24880                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24881                         --numjobs=$njobs --fallocate=none \
24882                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24883                         --filename=$DIR/$tfile &
24884                 bg_pid=$!
24885
24886                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24887                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24888                         --numjobs=$njobs --fallocate=none \
24889                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24890                         --filename=$DIR/$tfile || true
24891                 wait $bg_pid
24892         done
24893
24894         evict=$(do_facet client $LCTL get_param \
24895                 osc.$FSNAME-OST*-osc-*/state |
24896             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24897
24898         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24899                 (do_facet client $LCTL get_param \
24900                         osc.$FSNAME-OST*-osc-*/state;
24901                     error "eviction happened: $evict before:$before")
24902
24903         rm -f $DIR/$tfile
24904 }
24905 run_test 398b "DIO and buffer IO race"
24906
24907 test_398c() { # LU-4198
24908         local ost1_imp=$(get_osc_import_name client ost1)
24909         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24910                          cut -d'.' -f2)
24911
24912         which fio || skip_env "no fio installed"
24913
24914         saved_debug=$($LCTL get_param -n debug)
24915         $LCTL set_param debug=0
24916
24917         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24918         ((size /= 1024)) # by megabytes
24919         ((size /= 2)) # write half of the OST at most
24920         [ $size -gt 40 ] && size=40 #reduce test time anyway
24921
24922         $LFS setstripe -c 1 $DIR/$tfile
24923
24924         # it seems like ldiskfs reserves more space than necessary if the
24925         # writing blocks are not mapped, so it extends the file firstly
24926         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24927         cancel_lru_locks osc
24928
24929         # clear and verify rpc_stats later
24930         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24931
24932         local njobs=4
24933         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24934         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24935                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24936                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24937                 --filename=$DIR/$tfile
24938         [ $? -eq 0 ] || error "fio write error"
24939
24940         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24941                 error "Locks were requested while doing AIO"
24942
24943         # get the percentage of 1-page I/O
24944         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24945                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24946                 awk '{print $7}')
24947         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24948
24949         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24950         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24951                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24952                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24953                 --filename=$DIR/$tfile
24954         [ $? -eq 0 ] || error "fio mixed read write error"
24955
24956         echo "AIO with large block size ${size}M"
24957         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24958                 --numjobs=1 --fallocate=none --ioengine=libaio \
24959                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24960                 --filename=$DIR/$tfile
24961         [ $? -eq 0 ] || error "fio large block size failed"
24962
24963         rm -f $DIR/$tfile
24964         $LCTL set_param debug="$saved_debug"
24965 }
24966 run_test 398c "run fio to test AIO"
24967
24968 test_398d() { #  LU-13846
24969         which aiocp || skip_env "no aiocp installed"
24970         local aio_file=$DIR/$tfile.aio
24971
24972         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24973
24974         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24975         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24976         stack_trap "rm -f $DIR/$tfile $aio_file"
24977
24978         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24979
24980         # make sure we don't crash and fail properly
24981         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24982                 error "aio not aligned with PAGE SIZE should fail"
24983
24984         rm -f $DIR/$tfile $aio_file
24985 }
24986 run_test 398d "run aiocp to verify block size > stripe size"
24987
24988 test_398e() {
24989         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24990         touch $DIR/$tfile.new
24991         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24992 }
24993 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24994
24995 test_398f() { #  LU-14687
24996         which aiocp || skip_env "no aiocp installed"
24997         local aio_file=$DIR/$tfile.aio
24998
24999         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25000
25001         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25002         stack_trap "rm -f $DIR/$tfile $aio_file"
25003
25004         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25005         $LCTL set_param fail_loc=0x1418
25006         # make sure we don't crash and fail properly
25007         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25008                 error "aio with page allocation failure succeeded"
25009         $LCTL set_param fail_loc=0
25010         diff $DIR/$tfile $aio_file
25011         [[ $? != 0 ]] || error "no diff after failed aiocp"
25012 }
25013 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25014
25015 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25016 # stripe and i/o size must be > stripe size
25017 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25018 # single RPC in flight.  This test shows async DIO submission is working by
25019 # showing multiple RPCs in flight.
25020 test_398g() { #  LU-13798
25021         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25022
25023         # We need to do some i/o first to acquire enough grant to put our RPCs
25024         # in flight; otherwise a new connection may not have enough grant
25025         # available
25026         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25027                 error "parallel dio failed"
25028         stack_trap "rm -f $DIR/$tfile"
25029
25030         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25031         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25032         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25033         stack_trap "$LCTL set_param -n $pages_per_rpc"
25034
25035         # Recreate file so it's empty
25036         rm -f $DIR/$tfile
25037         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25038         #Pause rpc completion to guarantee we see multiple rpcs in flight
25039         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25040         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25041         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25042
25043         # Clear rpc stats
25044         $LCTL set_param osc.*.rpc_stats=c
25045
25046         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25047                 error "parallel dio failed"
25048         stack_trap "rm -f $DIR/$tfile"
25049
25050         $LCTL get_param osc.*-OST0000-*.rpc_stats
25051         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25052                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25053                 grep "8:" | awk '{print $8}')
25054         # We look at the "8 rpcs in flight" field, and verify A) it is present
25055         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25056         # as expected for an 8M DIO to a file with 1M stripes.
25057         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25058
25059         # Verify turning off parallel dio works as expected
25060         # Clear rpc stats
25061         $LCTL set_param osc.*.rpc_stats=c
25062         $LCTL set_param llite.*.parallel_dio=0
25063         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25064
25065         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25066                 error "dio with parallel dio disabled failed"
25067
25068         # Ideally, we would see only one RPC in flight here, but there is an
25069         # unavoidable race between i/o completion and RPC in flight counting,
25070         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25071         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25072         # So instead we just verify it's always < 8.
25073         $LCTL get_param osc.*-OST0000-*.rpc_stats
25074         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25075                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25076                 grep '^$' -B1 | grep . | awk '{print $1}')
25077         [ $ret != "8:" ] ||
25078                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25079 }
25080 run_test 398g "verify parallel dio async RPC submission"
25081
25082 test_398h() { #  LU-13798
25083         local dio_file=$DIR/$tfile.dio
25084
25085         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25086
25087         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25088         stack_trap "rm -f $DIR/$tfile $dio_file"
25089
25090         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25091                 error "parallel dio failed"
25092         diff $DIR/$tfile $dio_file
25093         [[ $? == 0 ]] || error "file diff after aiocp"
25094 }
25095 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25096
25097 test_398i() { #  LU-13798
25098         local dio_file=$DIR/$tfile.dio
25099
25100         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25101
25102         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25103         stack_trap "rm -f $DIR/$tfile $dio_file"
25104
25105         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25106         $LCTL set_param fail_loc=0x1418
25107         # make sure we don't crash and fail properly
25108         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25109                 error "parallel dio page allocation failure succeeded"
25110         diff $DIR/$tfile $dio_file
25111         [[ $? != 0 ]] || error "no diff after failed aiocp"
25112 }
25113 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25114
25115 test_398j() { #  LU-13798
25116         # Stripe size > RPC size but less than i/o size tests split across
25117         # stripes and RPCs for individual i/o op
25118         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25119
25120         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25121         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25122         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25123         stack_trap "$LCTL set_param -n $pages_per_rpc"
25124
25125         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25126                 error "parallel dio write failed"
25127         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25128
25129         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25130                 error "parallel dio read failed"
25131         diff $DIR/$tfile $DIR/$tfile.2
25132         [[ $? == 0 ]] || error "file diff after parallel dio read"
25133 }
25134 run_test 398j "test parallel dio where stripe size > rpc_size"
25135
25136 test_398k() { #  LU-13798
25137         wait_delete_completed
25138         wait_mds_ost_sync
25139
25140         # 4 stripe file; we will cause out of space on OST0
25141         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25142
25143         # Fill OST0 (if it's not too large)
25144         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25145                    head -n1)
25146         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25147                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25148         fi
25149         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25150         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25151                 error "dd should fill OST0"
25152         stack_trap "rm -f $DIR/$tfile.1"
25153
25154         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25155         err=$?
25156
25157         ls -la $DIR/$tfile
25158         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25159                 error "file is not 0 bytes in size"
25160
25161         # dd above should not succeed, but don't error until here so we can
25162         # get debug info above
25163         [[ $err != 0 ]] ||
25164                 error "parallel dio write with enospc succeeded"
25165         stack_trap "rm -f $DIR/$tfile"
25166 }
25167 run_test 398k "test enospc on first stripe"
25168
25169 test_398l() { #  LU-13798
25170         wait_delete_completed
25171         wait_mds_ost_sync
25172
25173         # 4 stripe file; we will cause out of space on OST0
25174         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25175         # happens on the second i/o chunk we issue
25176         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25177
25178         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25179         stack_trap "rm -f $DIR/$tfile"
25180
25181         # Fill OST0 (if it's not too large)
25182         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25183                    head -n1)
25184         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25185                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25186         fi
25187         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25188         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25189                 error "dd should fill OST0"
25190         stack_trap "rm -f $DIR/$tfile.1"
25191
25192         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25193         err=$?
25194         stack_trap "rm -f $DIR/$tfile.2"
25195
25196         # Check that short write completed as expected
25197         ls -la $DIR/$tfile.2
25198         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25199                 error "file is not 1M in size"
25200
25201         # dd above should not succeed, but don't error until here so we can
25202         # get debug info above
25203         [[ $err != 0 ]] ||
25204                 error "parallel dio write with enospc succeeded"
25205
25206         # Truncate source file to same length as output file and diff them
25207         $TRUNCATE $DIR/$tfile 1048576
25208         diff $DIR/$tfile $DIR/$tfile.2
25209         [[ $? == 0 ]] || error "data incorrect after short write"
25210 }
25211 run_test 398l "test enospc on intermediate stripe/RPC"
25212
25213 test_398m() { #  LU-13798
25214         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25215
25216         # Set up failure on OST0, the first stripe:
25217         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25218         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25219         # So this fail_val specifies OST0
25220         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25221         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25222
25223         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25224                 error "parallel dio write with failure on first stripe succeeded"
25225         stack_trap "rm -f $DIR/$tfile"
25226         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25227
25228         # Place data in file for read
25229         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25230                 error "parallel dio write failed"
25231
25232         # Fail read on OST0, first stripe
25233         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25234         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25235         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25236                 error "parallel dio read with error on first stripe succeeded"
25237         rm -f $DIR/$tfile.2
25238         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25239
25240         # Switch to testing on OST1, second stripe
25241         # Clear file contents, maintain striping
25242         echo > $DIR/$tfile
25243         # Set up failure on OST1, second stripe:
25244         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
25245         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25246
25247         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25248                 error "parallel dio write with failure on first stripe succeeded"
25249         stack_trap "rm -f $DIR/$tfile"
25250         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25251
25252         # Place data in file for read
25253         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25254                 error "parallel dio write failed"
25255
25256         # Fail read on OST1, second stripe
25257         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25258         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25259         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25260                 error "parallel dio read with error on first stripe succeeded"
25261         rm -f $DIR/$tfile.2
25262         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25263 }
25264 run_test 398m "test RPC failures with parallel dio"
25265
25266 # Parallel submission of DIO should not cause problems for append, but it's
25267 # important to verify.
25268 test_398n() { #  LU-13798
25269         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25270
25271         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25272                 error "dd to create source file failed"
25273         stack_trap "rm -f $DIR/$tfile"
25274
25275         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25276                 error "parallel dio write with failure on second stripe succeeded"
25277         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25278         diff $DIR/$tfile $DIR/$tfile.1
25279         [[ $? == 0 ]] || error "data incorrect after append"
25280
25281 }
25282 run_test 398n "test append with parallel DIO"
25283
25284 test_398o() {
25285         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25286 }
25287 run_test 398o "right kms with DIO"
25288
25289 test_fake_rw() {
25290         local read_write=$1
25291         if [ "$read_write" = "write" ]; then
25292                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25293         elif [ "$read_write" = "read" ]; then
25294                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25295         else
25296                 error "argument error"
25297         fi
25298
25299         # turn off debug for performance testing
25300         local saved_debug=$($LCTL get_param -n debug)
25301         $LCTL set_param debug=0
25302
25303         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25304
25305         # get ost1 size - $FSNAME-OST0000
25306         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25307         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25308         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25309
25310         if [ "$read_write" = "read" ]; then
25311                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25312         fi
25313
25314         local start_time=$(date +%s.%N)
25315         $dd_cmd bs=1M count=$blocks oflag=sync ||
25316                 error "real dd $read_write error"
25317         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25318
25319         if [ "$read_write" = "write" ]; then
25320                 rm -f $DIR/$tfile
25321         fi
25322
25323         # define OBD_FAIL_OST_FAKE_RW           0x238
25324         do_facet ost1 $LCTL set_param fail_loc=0x238
25325
25326         local start_time=$(date +%s.%N)
25327         $dd_cmd bs=1M count=$blocks oflag=sync ||
25328                 error "fake dd $read_write error"
25329         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25330
25331         if [ "$read_write" = "write" ]; then
25332                 # verify file size
25333                 cancel_lru_locks osc
25334                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25335                         error "$tfile size not $blocks MB"
25336         fi
25337         do_facet ost1 $LCTL set_param fail_loc=0
25338
25339         echo "fake $read_write $duration_fake vs. normal $read_write" \
25340                 "$duration in seconds"
25341         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25342                 error_not_in_vm "fake write is slower"
25343
25344         $LCTL set_param -n debug="$saved_debug"
25345         rm -f $DIR/$tfile
25346 }
25347 test_399a() { # LU-7655 for OST fake write
25348         remote_ost_nodsh && skip "remote OST with nodsh"
25349
25350         test_fake_rw write
25351 }
25352 run_test 399a "fake write should not be slower than normal write"
25353
25354 test_399b() { # LU-8726 for OST fake read
25355         remote_ost_nodsh && skip "remote OST with nodsh"
25356         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25357                 skip_env "ldiskfs only test"
25358         fi
25359
25360         test_fake_rw read
25361 }
25362 run_test 399b "fake read should not be slower than normal read"
25363
25364 test_400a() { # LU-1606, was conf-sanity test_74
25365         if ! which $CC > /dev/null 2>&1; then
25366                 skip_env "$CC is not installed"
25367         fi
25368
25369         local extra_flags=''
25370         local out=$TMP/$tfile
25371         local prefix=/usr/include/lustre
25372         local prog
25373
25374         # Oleg removes c files in his test rig so test if any c files exist
25375         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25376                 skip_env "Needed c test files are missing"
25377
25378         if ! [[ -d $prefix ]]; then
25379                 # Assume we're running in tree and fixup the include path.
25380                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25381                 extra_flags+=" -L$LUSTRE/utils/.lib"
25382         fi
25383
25384         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25385                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25386                         error "client api broken"
25387         done
25388         rm -f $out
25389 }
25390 run_test 400a "Lustre client api program can compile and link"
25391
25392 test_400b() { # LU-1606, LU-5011
25393         local header
25394         local out=$TMP/$tfile
25395         local prefix=/usr/include/linux/lustre
25396
25397         # We use a hard coded prefix so that this test will not fail
25398         # when run in tree. There are headers in lustre/include/lustre/
25399         # that are not packaged (like lustre_idl.h) and have more
25400         # complicated include dependencies (like config.h and lnet/types.h).
25401         # Since this test about correct packaging we just skip them when
25402         # they don't exist (see below) rather than try to fixup cppflags.
25403
25404         if ! which $CC > /dev/null 2>&1; then
25405                 skip_env "$CC is not installed"
25406         fi
25407
25408         for header in $prefix/*.h; do
25409                 if ! [[ -f "$header" ]]; then
25410                         continue
25411                 fi
25412
25413                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25414                         continue # lustre_ioctl.h is internal header
25415                 fi
25416
25417                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25418                         error "cannot compile '$header'"
25419         done
25420         rm -f $out
25421 }
25422 run_test 400b "packaged headers can be compiled"
25423
25424 test_401a() { #LU-7437
25425         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25426         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25427
25428         #count the number of parameters by "list_param -R"
25429         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25430         #count the number of parameters by listing proc files
25431         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25432         echo "proc_dirs='$proc_dirs'"
25433         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25434         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25435                       sort -u | wc -l)
25436
25437         [ $params -eq $procs ] ||
25438                 error "found $params parameters vs. $procs proc files"
25439
25440         # test the list_param -D option only returns directories
25441         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25442         #count the number of parameters by listing proc directories
25443         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25444                 sort -u | wc -l)
25445
25446         [ $params -eq $procs ] ||
25447                 error "found $params parameters vs. $procs proc files"
25448 }
25449 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25450
25451 test_401b() {
25452         # jobid_var may not allow arbitrary values, so use jobid_name
25453         # if available
25454         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25455                 local testname=jobid_name tmp='testing%p'
25456         else
25457                 local testname=jobid_var tmp=testing
25458         fi
25459
25460         local save=$($LCTL get_param -n $testname)
25461
25462         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25463                 error "no error returned when setting bad parameters"
25464
25465         local jobid_new=$($LCTL get_param -n foe $testname baz)
25466         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25467
25468         $LCTL set_param -n fog=bam $testname=$save bat=fog
25469         local jobid_old=$($LCTL get_param -n foe $testname bag)
25470         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25471 }
25472 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25473
25474 test_401c() {
25475         # jobid_var may not allow arbitrary values, so use jobid_name
25476         # if available
25477         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25478                 local testname=jobid_name
25479         else
25480                 local testname=jobid_var
25481         fi
25482
25483         local jobid_var_old=$($LCTL get_param -n $testname)
25484         local jobid_var_new
25485
25486         $LCTL set_param $testname= &&
25487                 error "no error returned for 'set_param a='"
25488
25489         jobid_var_new=$($LCTL get_param -n $testname)
25490         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25491                 error "$testname was changed by setting without value"
25492
25493         $LCTL set_param $testname &&
25494                 error "no error returned for 'set_param a'"
25495
25496         jobid_var_new=$($LCTL get_param -n $testname)
25497         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25498                 error "$testname was changed by setting without value"
25499 }
25500 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25501
25502 test_401d() {
25503         # jobid_var may not allow arbitrary values, so use jobid_name
25504         # if available
25505         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25506                 local testname=jobid_name new_value='foo=bar%p'
25507         else
25508                 local testname=jobid_var new_valuie=foo=bar
25509         fi
25510
25511         local jobid_var_old=$($LCTL get_param -n $testname)
25512         local jobid_var_new
25513
25514         $LCTL set_param $testname=$new_value ||
25515                 error "'set_param a=b' did not accept a value containing '='"
25516
25517         jobid_var_new=$($LCTL get_param -n $testname)
25518         [[ "$jobid_var_new" == "$new_value" ]] ||
25519                 error "'set_param a=b' failed on a value containing '='"
25520
25521         # Reset the $testname to test the other format
25522         $LCTL set_param $testname=$jobid_var_old
25523         jobid_var_new=$($LCTL get_param -n $testname)
25524         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25525                 error "failed to reset $testname"
25526
25527         $LCTL set_param $testname $new_value ||
25528                 error "'set_param a b' did not accept a value containing '='"
25529
25530         jobid_var_new=$($LCTL get_param -n $testname)
25531         [[ "$jobid_var_new" == "$new_value" ]] ||
25532                 error "'set_param a b' failed on a value containing '='"
25533
25534         $LCTL set_param $testname $jobid_var_old
25535         jobid_var_new=$($LCTL get_param -n $testname)
25536         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25537                 error "failed to reset $testname"
25538 }
25539 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25540
25541 test_401e() { # LU-14779
25542         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25543                 error "lctl list_param MGC* failed"
25544         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25545         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25546                 error "lctl get_param lru_size failed"
25547 }
25548 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25549
25550 test_402() {
25551         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25552         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25553                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25554         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25555                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25556                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25557         remote_mds_nodsh && skip "remote MDS with nodsh"
25558
25559         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25560 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25561         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25562         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25563                 echo "Touch failed - OK"
25564 }
25565 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25566
25567 test_403() {
25568         local file1=$DIR/$tfile.1
25569         local file2=$DIR/$tfile.2
25570         local tfile=$TMP/$tfile
25571
25572         rm -f $file1 $file2 $tfile
25573
25574         touch $file1
25575         ln $file1 $file2
25576
25577         # 30 sec OBD_TIMEOUT in ll_getattr()
25578         # right before populating st_nlink
25579         $LCTL set_param fail_loc=0x80001409
25580         stat -c %h $file1 > $tfile &
25581
25582         # create an alias, drop all locks and reclaim the dentry
25583         < $file2
25584         cancel_lru_locks mdc
25585         cancel_lru_locks osc
25586         sysctl -w vm.drop_caches=2
25587
25588         wait
25589
25590         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25591
25592         rm -f $tfile $file1 $file2
25593 }
25594 run_test 403 "i_nlink should not drop to zero due to aliasing"
25595
25596 test_404() { # LU-6601
25597         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25598                 skip "Need server version newer than 2.8.52"
25599         remote_mds_nodsh && skip "remote MDS with nodsh"
25600
25601         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25602                 awk '/osp .*-osc-MDT/ { print $4}')
25603
25604         local osp
25605         for osp in $mosps; do
25606                 echo "Deactivate: " $osp
25607                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25608                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25609                         awk -vp=$osp '$4 == p { print $2 }')
25610                 [ $stat = IN ] || {
25611                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25612                         error "deactivate error"
25613                 }
25614                 echo "Activate: " $osp
25615                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25616                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25617                         awk -vp=$osp '$4 == p { print $2 }')
25618                 [ $stat = UP ] || {
25619                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25620                         error "activate error"
25621                 }
25622         done
25623 }
25624 run_test 404 "validate manual {de}activated works properly for OSPs"
25625
25626 test_405() {
25627         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25628         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25629                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25630                         skip "Layout swap lock is not supported"
25631
25632         check_swap_layouts_support
25633         check_swap_layout_no_dom $DIR
25634
25635         test_mkdir $DIR/$tdir
25636         swap_lock_test -d $DIR/$tdir ||
25637                 error "One layout swap locked test failed"
25638 }
25639 run_test 405 "Various layout swap lock tests"
25640
25641 test_406() {
25642         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25643         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25644         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25646         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25647                 skip "Need MDS version at least 2.8.50"
25648
25649         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25650         local test_pool=$TESTNAME
25651
25652         pool_add $test_pool || error "pool_add failed"
25653         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25654                 error "pool_add_targets failed"
25655
25656         save_layout_restore_at_exit $MOUNT
25657
25658         # parent set default stripe count only, child will stripe from both
25659         # parent and fs default
25660         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25661                 error "setstripe $MOUNT failed"
25662         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25663         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25664         for i in $(seq 10); do
25665                 local f=$DIR/$tdir/$tfile.$i
25666                 touch $f || error "touch failed"
25667                 local count=$($LFS getstripe -c $f)
25668                 [ $count -eq $OSTCOUNT ] ||
25669                         error "$f stripe count $count != $OSTCOUNT"
25670                 local offset=$($LFS getstripe -i $f)
25671                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25672                 local size=$($LFS getstripe -S $f)
25673                 [ $size -eq $((def_stripe_size * 2)) ] ||
25674                         error "$f stripe size $size != $((def_stripe_size * 2))"
25675                 local pool=$($LFS getstripe -p $f)
25676                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25677         done
25678
25679         # change fs default striping, delete parent default striping, now child
25680         # will stripe from new fs default striping only
25681         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25682                 error "change $MOUNT default stripe failed"
25683         $LFS setstripe -c 0 $DIR/$tdir ||
25684                 error "delete $tdir default stripe failed"
25685         for i in $(seq 11 20); do
25686                 local f=$DIR/$tdir/$tfile.$i
25687                 touch $f || error "touch $f failed"
25688                 local count=$($LFS getstripe -c $f)
25689                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25690                 local offset=$($LFS getstripe -i $f)
25691                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25692                 local size=$($LFS getstripe -S $f)
25693                 [ $size -eq $def_stripe_size ] ||
25694                         error "$f stripe size $size != $def_stripe_size"
25695                 local pool=$($LFS getstripe -p $f)
25696                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25697         done
25698
25699         unlinkmany $DIR/$tdir/$tfile. 1 20
25700
25701         local f=$DIR/$tdir/$tfile
25702         pool_remove_all_targets $test_pool $f
25703         pool_remove $test_pool $f
25704 }
25705 run_test 406 "DNE support fs default striping"
25706
25707 test_407() {
25708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25709         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25710                 skip "Need MDS version at least 2.8.55"
25711         remote_mds_nodsh && skip "remote MDS with nodsh"
25712
25713         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25714                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25715         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25716                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25717         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25718
25719         #define OBD_FAIL_DT_TXN_STOP    0x2019
25720         for idx in $(seq $MDSCOUNT); do
25721                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25722         done
25723         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25724         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25725                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25726         true
25727 }
25728 run_test 407 "transaction fail should cause operation fail"
25729
25730 test_408() {
25731         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25732
25733         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25734         lctl set_param fail_loc=0x8000040a
25735         # let ll_prepare_partial_page() fail
25736         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25737
25738         rm -f $DIR/$tfile
25739
25740         # create at least 100 unused inodes so that
25741         # shrink_icache_memory(0) should not return 0
25742         touch $DIR/$tfile-{0..100}
25743         rm -f $DIR/$tfile-{0..100}
25744         sync
25745
25746         echo 2 > /proc/sys/vm/drop_caches
25747 }
25748 run_test 408 "drop_caches should not hang due to page leaks"
25749
25750 test_409()
25751 {
25752         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25753
25754         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25755         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25756         touch $DIR/$tdir/guard || error "(2) Fail to create"
25757
25758         local PREFIX=$(str_repeat 'A' 128)
25759         echo "Create 1K hard links start at $(date)"
25760         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25761                 error "(3) Fail to hard link"
25762
25763         echo "Links count should be right although linkEA overflow"
25764         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25765         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25766         [ $linkcount -eq 1001 ] ||
25767                 error "(5) Unexpected hard links count: $linkcount"
25768
25769         echo "List all links start at $(date)"
25770         ls -l $DIR/$tdir/foo > /dev/null ||
25771                 error "(6) Fail to list $DIR/$tdir/foo"
25772
25773         echo "Unlink hard links start at $(date)"
25774         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25775                 error "(7) Fail to unlink"
25776         echo "Unlink hard links finished at $(date)"
25777 }
25778 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25779
25780 test_410()
25781 {
25782         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25783                 skip "Need client version at least 2.9.59"
25784         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25785                 skip "Need MODULES build"
25786
25787         # Create a file, and stat it from the kernel
25788         local testfile=$DIR/$tfile
25789         touch $testfile
25790
25791         local run_id=$RANDOM
25792         local my_ino=$(stat --format "%i" $testfile)
25793
25794         # Try to insert the module. This will always fail as the
25795         # module is designed to not be inserted.
25796         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25797             &> /dev/null
25798
25799         # Anything but success is a test failure
25800         dmesg | grep -q \
25801             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25802             error "no inode match"
25803 }
25804 run_test 410 "Test inode number returned from kernel thread"
25805
25806 cleanup_test411_cgroup() {
25807         trap 0
25808         rmdir "$1"
25809 }
25810
25811 test_411() {
25812         local cg_basedir=/sys/fs/cgroup/memory
25813         # LU-9966
25814         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25815                 skip "no setup for cgroup"
25816
25817         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25818                 error "test file creation failed"
25819         cancel_lru_locks osc
25820
25821         # Create a very small memory cgroup to force a slab allocation error
25822         local cgdir=$cg_basedir/osc_slab_alloc
25823         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25824         trap "cleanup_test411_cgroup $cgdir" EXIT
25825         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25826         echo 1M > $cgdir/memory.limit_in_bytes
25827
25828         # Should not LBUG, just be killed by oom-killer
25829         # dd will return 0 even allocation failure in some environment.
25830         # So don't check return value
25831         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25832         cleanup_test411_cgroup $cgdir
25833
25834         return 0
25835 }
25836 run_test 411 "Slab allocation error with cgroup does not LBUG"
25837
25838 test_412() {
25839         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25840         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25841                 skip "Need server version at least 2.10.55"
25842
25843         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25844                 error "mkdir failed"
25845         $LFS getdirstripe $DIR/$tdir
25846         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25847         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25848                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25849         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25850         [ $stripe_count -eq 2 ] ||
25851                 error "expect 2 get $stripe_count"
25852
25853         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25854
25855         local index
25856         local index2
25857
25858         # subdirs should be on the same MDT as parent
25859         for i in $(seq 0 $((MDSCOUNT - 1))); do
25860                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25861                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25862                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25863                 (( index == i )) || error "mdt$i/sub on MDT$index"
25864         done
25865
25866         # stripe offset -1, ditto
25867         for i in {1..10}; do
25868                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25869                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25870                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25871                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25872                 (( index == index2 )) ||
25873                         error "qos$i on MDT$index, sub on MDT$index2"
25874         done
25875
25876         local testdir=$DIR/$tdir/inherit
25877
25878         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25879         # inherit 2 levels
25880         for i in 1 2; do
25881                 testdir=$testdir/s$i
25882                 mkdir $testdir || error "mkdir $testdir failed"
25883                 index=$($LFS getstripe -m $testdir)
25884                 (( index == 1 )) ||
25885                         error "$testdir on MDT$index"
25886         done
25887
25888         # not inherit any more
25889         testdir=$testdir/s3
25890         mkdir $testdir || error "mkdir $testdir failed"
25891         getfattr -d -m dmv $testdir | grep dmv &&
25892                 error "default LMV set on $testdir" || true
25893 }
25894 run_test 412 "mkdir on specific MDTs"
25895
25896 TEST413_COUNT=${TEST413_COUNT:-200}
25897 generate_uneven_mdts() {
25898         local threshold=$1
25899         local lmv_qos_maxage
25900         local lod_qos_maxage
25901         local ffree
25902         local bavail
25903         local max
25904         local min
25905         local max_index
25906         local min_index
25907         local tmp
25908         local i
25909
25910         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25911         $LCTL set_param lmv.*.qos_maxage=1
25912         stack_trap "$LCTL set_param \
25913                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25914         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25915                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25916         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25917                 lod.*.mdt_qos_maxage=1
25918         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25919                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25920
25921         echo
25922         echo "Check for uneven MDTs: "
25923
25924         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25925         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25926         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25927
25928         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25929         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25930         max_index=0
25931         min_index=0
25932         for ((i = 1; i < ${#ffree[@]}; i++)); do
25933                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25934                 if [ $tmp -gt $max ]; then
25935                         max=$tmp
25936                         max_index=$i
25937                 fi
25938                 if [ $tmp -lt $min ]; then
25939                         min=$tmp
25940                         min_index=$i
25941                 fi
25942         done
25943
25944         (( ${ffree[min_index]} > 0 )) ||
25945                 skip "no free files in MDT$min_index"
25946         (( ${ffree[min_index]} < 10000000 )) ||
25947                 skip "too many free files in MDT$min_index"
25948
25949         # Check if we need to generate uneven MDTs
25950         local diff=$(((max - min) * 100 / min))
25951         local testdir=$DIR/$tdir-fillmdt
25952         local start
25953
25954         i=0
25955         while (( diff < threshold )); do
25956                 mkdir -p $testdir
25957                 # generate uneven MDTs, create till $threshold% diff
25958                 echo -n "weight diff=$diff% must be > $threshold% ..."
25959                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25960                 testdir=$DIR/$tdir-fillmdt/$i
25961                 [ -d $testdir ] && continue
25962                 $LFS mkdir -i $min_index $testdir ||
25963                         error "mkdir $testdir failed"
25964                 $LFS setstripe -E 1M -L mdt $testdir ||
25965                         error "setstripe $testdir failed"
25966                 start=$SECONDS
25967                 for ((F=0; F < TEST413_COUNT; F++)); do
25968                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25969                                 /dev/null 2>&1 || error "dd $F failed"
25970                 done
25971                 sync; sleep 1; sync
25972
25973                 # wait for QOS to update
25974                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25975
25976                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25977                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25978                 max=$(((${ffree[max_index]} >> 8) *
25979                         (${bavail[max_index]} * bsize >> 16)))
25980                 min=$(((${ffree[min_index]} >> 8) *
25981                         (${bavail[min_index]} * bsize >> 16)))
25982                 diff=$(((max - min) * 100 / min))
25983                 i=$((i + 1))
25984         done
25985
25986         echo "MDT filesfree available: ${ffree[*]}"
25987         echo "MDT blocks available: ${bavail[*]}"
25988         echo "weight diff=$diff%"
25989 }
25990
25991 test_qos_mkdir() {
25992         local mkdir_cmd=$1
25993         local stripe_count=$2
25994         local mdts=$(comma_list $(mdts_nodes))
25995
25996         local testdir
25997         local lmv_qos_prio_free
25998         local lmv_qos_threshold_rr
25999         local lmv_qos_maxage
26000         local lod_qos_prio_free
26001         local lod_qos_threshold_rr
26002         local lod_qos_maxage
26003         local count
26004         local i
26005
26006         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26007         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26008         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26009                 head -n1)
26010         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26011         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26012         stack_trap "$LCTL set_param \
26013                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26014         stack_trap "$LCTL set_param \
26015                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26016         stack_trap "$LCTL set_param \
26017                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26018
26019         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26020                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26021         lod_qos_prio_free=${lod_qos_prio_free%%%}
26022         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26023                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26024         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26025         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26026                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26027         stack_trap "do_nodes $mdts $LCTL set_param \
26028                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26029         stack_trap "do_nodes $mdts $LCTL set_param \
26030                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26031         stack_trap "do_nodes $mdts $LCTL set_param \
26032                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26033
26034         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26035         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26036
26037         testdir=$DIR/$tdir-s$stripe_count/rr
26038
26039         local stripe_index=$($LFS getstripe -m $testdir)
26040         local test_mkdir_rr=true
26041
26042         getfattr -d -m dmv -e hex $testdir | grep dmv
26043         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26044                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26045                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26046                         test_mkdir_rr=false
26047         fi
26048
26049         echo
26050         $test_mkdir_rr &&
26051                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26052                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26053
26054         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26055         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26056                 eval $mkdir_cmd $testdir/subdir$i ||
26057                         error "$mkdir_cmd subdir$i failed"
26058         done
26059
26060         for (( i = 0; i < $MDSCOUNT; i++ )); do
26061                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26062                 echo "$count directories created on MDT$i"
26063                 if $test_mkdir_rr; then
26064                         (( $count == 100 )) ||
26065                                 error "subdirs are not evenly distributed"
26066                 elif (( $i == $stripe_index )); then
26067                         (( $count == 100 * MDSCOUNT )) ||
26068                                 error "$count subdirs created on MDT$i"
26069                 else
26070                         (( $count == 0 )) ||
26071                                 error "$count subdirs created on MDT$i"
26072                 fi
26073
26074                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26075                         count=$($LFS getdirstripe $testdir/* |
26076                                 grep -c -P "^\s+$i\t")
26077                         echo "$count stripes created on MDT$i"
26078                         # deviation should < 5% of average
26079                         (( $count >= 95 * stripe_count &&
26080                            $count <= 105 * stripe_count)) ||
26081                                 error "stripes are not evenly distributed"
26082                 fi
26083         done
26084
26085         echo
26086         echo "Check for uneven MDTs: "
26087
26088         local ffree
26089         local bavail
26090         local max
26091         local min
26092         local max_index
26093         local min_index
26094         local tmp
26095
26096         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26097         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26098         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26099
26100         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26101         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26102         max_index=0
26103         min_index=0
26104         for ((i = 1; i < ${#ffree[@]}; i++)); do
26105                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26106                 if [ $tmp -gt $max ]; then
26107                         max=$tmp
26108                         max_index=$i
26109                 fi
26110                 if [ $tmp -lt $min ]; then
26111                         min=$tmp
26112                         min_index=$i
26113                 fi
26114         done
26115
26116         (( ${ffree[min_index]} > 0 )) ||
26117                 skip "no free files in MDT$min_index"
26118         (( ${ffree[min_index]} < 10000000 )) ||
26119                 skip "too many free files in MDT$min_index"
26120
26121         echo "MDT filesfree available: ${ffree[*]}"
26122         echo "MDT blocks available: ${bavail[*]}"
26123         echo "weight diff=$(((max - min) * 100 / min))%"
26124         echo
26125         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26126
26127         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26128         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26129         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26130         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26131         # decrease statfs age, so that it can be updated in time
26132         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26133         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26134
26135         sleep 1
26136
26137         testdir=$DIR/$tdir-s$stripe_count/qos
26138         local num=200
26139
26140         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26141         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26142                 eval $mkdir_cmd $testdir/subdir$i ||
26143                         error "$mkdir_cmd subdir$i failed"
26144         done
26145
26146         max=0
26147         for (( i = 0; i < $MDSCOUNT; i++ )); do
26148                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26149                 (( count > max )) && max=$count
26150                 echo "$count directories created on MDT$i"
26151         done
26152
26153         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26154
26155         # D-value should > 10% of averge
26156         (( max - min > num / 10 )) ||
26157                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26158
26159         # ditto for stripes
26160         if (( stripe_count > 1 )); then
26161                 max=0
26162                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26163                         count=$($LFS getdirstripe $testdir/* |
26164                                 grep -c -P "^\s+$i\t")
26165                         (( count > max )) && max=$count
26166                         echo "$count stripes created on MDT$i"
26167                 done
26168
26169                 min=$($LFS getdirstripe $testdir/* |
26170                         grep -c -P "^\s+$min_index\t")
26171                 (( max - min > num * stripe_count / 10 )) ||
26172                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26173         fi
26174 }
26175
26176 most_full_mdt() {
26177         local ffree
26178         local bavail
26179         local bsize
26180         local min
26181         local min_index
26182         local tmp
26183
26184         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26185         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26186         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26187
26188         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26189         min_index=0
26190         for ((i = 1; i < ${#ffree[@]}; i++)); do
26191                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26192                 (( tmp < min )) && min=$tmp && min_index=$i
26193         done
26194
26195         echo -n $min_index
26196 }
26197
26198 test_413a() {
26199         [ $MDSCOUNT -lt 2 ] &&
26200                 skip "We need at least 2 MDTs for this test"
26201
26202         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26203                 skip "Need server version at least 2.12.52"
26204
26205         local stripe_count
26206
26207         generate_uneven_mdts 100
26208         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26209                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26210                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26211                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26212                         error "mkdir failed"
26213                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26214         done
26215 }
26216 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26217
26218 test_413b() {
26219         [ $MDSCOUNT -lt 2 ] &&
26220                 skip "We need at least 2 MDTs for this test"
26221
26222         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26223                 skip "Need server version at least 2.12.52"
26224
26225         local testdir
26226         local stripe_count
26227
26228         generate_uneven_mdts 100
26229         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26230                 testdir=$DIR/$tdir-s$stripe_count
26231                 mkdir $testdir || error "mkdir $testdir failed"
26232                 mkdir $testdir/rr || error "mkdir rr failed"
26233                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26234                         error "mkdir qos failed"
26235                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26236                         $testdir/rr || error "setdirstripe rr failed"
26237                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26238                         error "setdirstripe failed"
26239                 test_qos_mkdir "mkdir" $stripe_count
26240         done
26241 }
26242 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26243
26244 test_413c() {
26245         (( $MDSCOUNT >= 2 )) ||
26246                 skip "We need at least 2 MDTs for this test"
26247
26248         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26249                 skip "Need server version at least 2.14.51"
26250
26251         local testdir
26252         local inherit
26253         local inherit_rr
26254
26255         testdir=$DIR/${tdir}-s1
26256         mkdir $testdir || error "mkdir $testdir failed"
26257         mkdir $testdir/rr || error "mkdir rr failed"
26258         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26259         # default max_inherit is -1, default max_inherit_rr is 0
26260         $LFS setdirstripe -D -c 1 $testdir/rr ||
26261                 error "setdirstripe rr failed"
26262         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26263                 error "setdirstripe qos failed"
26264         test_qos_mkdir "mkdir" 1
26265
26266         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26267         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26268         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26269         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26270         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26271
26272         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26273         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26274         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26275         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26276         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26277         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26278         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26279                 error "level2 shouldn't have default LMV" || true
26280 }
26281 run_test 413c "mkdir with default LMV max inherit rr"
26282
26283 test_413d() {
26284         (( MDSCOUNT >= 2 )) ||
26285                 skip "We need at least 2 MDTs for this test"
26286
26287         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26288                 skip "Need server version at least 2.14.51"
26289
26290         local lmv_qos_threshold_rr
26291
26292         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26293                 head -n1)
26294         stack_trap "$LCTL set_param \
26295                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26296
26297         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26298         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26299         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26300                 error "$tdir shouldn't have default LMV"
26301         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26302                 error "mkdir sub failed"
26303
26304         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26305
26306         (( count == 100 )) || error "$count subdirs on MDT0"
26307 }
26308 run_test 413d "inherit ROOT default LMV"
26309
26310 test_413e() {
26311         (( MDSCOUNT >= 2 )) ||
26312                 skip "We need at least 2 MDTs for this test"
26313         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26314                 skip "Need server version at least 2.14.55"
26315
26316         local testdir=$DIR/$tdir
26317         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26318         local max_inherit
26319         local sub_max_inherit
26320
26321         mkdir -p $testdir || error "failed to create $testdir"
26322
26323         # set default max-inherit to -1 if stripe count is 0 or 1
26324         $LFS setdirstripe -D -c 1 $testdir ||
26325                 error "failed to set default LMV"
26326         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26327         (( max_inherit == -1 )) ||
26328                 error "wrong max_inherit value $max_inherit"
26329
26330         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26331         $LFS setdirstripe -D -c -1 $testdir ||
26332                 error "failed to set default LMV"
26333         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26334         (( max_inherit > 0 )) ||
26335                 error "wrong max_inherit value $max_inherit"
26336
26337         # and the subdir will decrease the max_inherit by 1
26338         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26339         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26340         (( sub_max_inherit == max_inherit - 1)) ||
26341                 error "wrong max-inherit of subdir $sub_max_inherit"
26342
26343         # check specified --max-inherit and warning message
26344         stack_trap "rm -f $tmpfile"
26345         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26346                 error "failed to set default LMV"
26347         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26348         (( max_inherit == -1 )) ||
26349                 error "wrong max_inherit value $max_inherit"
26350
26351         # check the warning messages
26352         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26353                 error "failed to detect warning string"
26354         fi
26355 }
26356 run_test 413e "check default max-inherit value"
26357
26358 test_fs_dmv_inherit()
26359 {
26360         local testdir=$DIR/$tdir
26361
26362         local count
26363         local inherit
26364         local inherit_rr
26365
26366         for i in 1 2 3; do
26367                 mkdir $testdir || error "mkdir $testdir failed"
26368                 count=$($LFS getdirstripe -D -c $testdir)
26369                 (( count == 1 )) ||
26370                         error "$testdir default LMV count mismatch $count != 1"
26371                 inherit=$($LFS getdirstripe -D -X $testdir)
26372                 (( inherit == 3 - i )) ||
26373                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26374                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26375                 (( inherit_rr == 3 - i )) ||
26376                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26377                 testdir=$testdir/sub
26378         done
26379
26380         mkdir $testdir || error "mkdir $testdir failed"
26381         count=$($LFS getdirstripe -D -c $testdir)
26382         (( count == 0 )) ||
26383                 error "$testdir default LMV count not zero: $count"
26384 }
26385
26386 test_413f() {
26387         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26388
26389         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26390                 skip "Need server version at least 2.14.55"
26391
26392         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26393                 error "dump $DIR default LMV failed"
26394         stack_trap "setfattr --restore=$TMP/dmv.ea"
26395
26396         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26397                 error "set $DIR default LMV failed"
26398
26399         test_fs_dmv_inherit
26400 }
26401 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26402
26403 test_413g() {
26404         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26405
26406         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26407         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26408                 error "dump $DIR default LMV failed"
26409         stack_trap "setfattr --restore=$TMP/dmv.ea"
26410
26411         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26412                 error "set $DIR default LMV failed"
26413
26414         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26415                 error "mount $MOUNT2 failed"
26416         stack_trap "umount_client $MOUNT2"
26417
26418         local saved_DIR=$DIR
26419
26420         export DIR=$MOUNT2
26421
26422         stack_trap "export DIR=$saved_DIR"
26423
26424         # first check filesystem-wide default LMV inheritance
26425         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26426
26427         # then check subdirs are spread to all MDTs
26428         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26429
26430         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26431
26432         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26433 }
26434 run_test 413g "enforce ROOT default LMV on subdir mount"
26435
26436 test_413h() {
26437         (( MDSCOUNT >= 2 )) ||
26438                 skip "We need at least 2 MDTs for this test"
26439
26440         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26441                 skip "Need server version at least 2.15.50.6"
26442
26443         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26444
26445         stack_trap "$LCTL set_param \
26446                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26447         $LCTL set_param lmv.*.qos_maxage=1
26448
26449         local depth=5
26450         local rr_depth=4
26451         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26452         local count=$((MDSCOUNT * 20))
26453
26454         generate_uneven_mdts 50
26455
26456         mkdir -p $dir || error "mkdir $dir failed"
26457         stack_trap "rm -rf $dir"
26458         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26459                 --max-inherit-rr=$rr_depth $dir
26460
26461         for ((d=0; d < depth + 2; d++)); do
26462                 log "dir=$dir:"
26463                 for ((sub=0; sub < count; sub++)); do
26464                         mkdir $dir/d$sub
26465                 done
26466                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26467                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26468                 # subdirs within $rr_depth should be created round-robin
26469                 if (( d < rr_depth )); then
26470                         (( ${num[0]} != count )) ||
26471                                 error "all objects created on MDT ${num[1]}"
26472                 fi
26473
26474                 dir=$dir/d0
26475         done
26476 }
26477 run_test 413h "don't stick to parent for round-robin dirs"
26478
26479 test_413z() {
26480         local pids=""
26481         local subdir
26482         local pid
26483
26484         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26485                 unlinkmany $subdir/f. $TEST413_COUNT &
26486                 pids="$pids $!"
26487         done
26488
26489         for pid in $pids; do
26490                 wait $pid
26491         done
26492 }
26493 run_test 413z "413 test cleanup"
26494
26495 test_414() {
26496 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26497         $LCTL set_param fail_loc=0x80000521
26498         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26499         rm -f $DIR/$tfile
26500 }
26501 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26502
26503 test_415() {
26504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26505         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26506                 skip "Need server version at least 2.11.52"
26507
26508         # LU-11102
26509         local total
26510         local setattr_pid
26511         local start_time
26512         local end_time
26513         local duration
26514
26515         total=500
26516         # this test may be slow on ZFS
26517         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26518
26519         # though this test is designed for striped directory, let's test normal
26520         # directory too since lock is always saved as CoS lock.
26521         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26522         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26523
26524         (
26525                 while true; do
26526                         touch $DIR/$tdir
26527                 done
26528         ) &
26529         setattr_pid=$!
26530
26531         start_time=$(date +%s)
26532         for i in $(seq $total); do
26533                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26534                         > /dev/null
26535         done
26536         end_time=$(date +%s)
26537         duration=$((end_time - start_time))
26538
26539         kill -9 $setattr_pid
26540
26541         echo "rename $total files took $duration sec"
26542         [ $duration -lt 100 ] || error "rename took $duration sec"
26543 }
26544 run_test 415 "lock revoke is not missing"
26545
26546 test_416() {
26547         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26548                 skip "Need server version at least 2.11.55"
26549
26550         # define OBD_FAIL_OSD_TXN_START    0x19a
26551         do_facet mds1 lctl set_param fail_loc=0x19a
26552
26553         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26554
26555         true
26556 }
26557 run_test 416 "transaction start failure won't cause system hung"
26558
26559 cleanup_417() {
26560         trap 0
26561         do_nodes $(comma_list $(mdts_nodes)) \
26562                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26563         do_nodes $(comma_list $(mdts_nodes)) \
26564                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26565         do_nodes $(comma_list $(mdts_nodes)) \
26566                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26567 }
26568
26569 test_417() {
26570         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26571         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26572                 skip "Need MDS version at least 2.11.56"
26573
26574         trap cleanup_417 RETURN EXIT
26575
26576         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26577         do_nodes $(comma_list $(mdts_nodes)) \
26578                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26579         $LFS migrate -m 0 $DIR/$tdir.1 &&
26580                 error "migrate dir $tdir.1 should fail"
26581
26582         do_nodes $(comma_list $(mdts_nodes)) \
26583                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26584         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26585                 error "create remote dir $tdir.2 should fail"
26586
26587         do_nodes $(comma_list $(mdts_nodes)) \
26588                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26589         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26590                 error "create striped dir $tdir.3 should fail"
26591         true
26592 }
26593 run_test 417 "disable remote dir, striped dir and dir migration"
26594
26595 # Checks that the outputs of df [-i] and lfs df [-i] match
26596 #
26597 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26598 check_lfs_df() {
26599         local dir=$2
26600         local inodes
26601         local df_out
26602         local lfs_df_out
26603         local count
26604         local passed=false
26605
26606         # blocks or inodes
26607         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26608
26609         for count in {1..100}; do
26610                 do_nodes "$CLIENTS" \
26611                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26612                 sync; sleep 0.2
26613
26614                 # read the lines of interest
26615                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26616                         error "df $inodes $dir | tail -n +2 failed"
26617                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26618                         error "lfs df $inodes $dir | grep summary: failed"
26619
26620                 # skip first substrings of each output as they are different
26621                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26622                 # compare the two outputs
26623                 passed=true
26624                 #  skip "available" on MDT until LU-13997 is fixed.
26625                 #for i in {1..5}; do
26626                 for i in 1 2 4 5; do
26627                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26628                 done
26629                 $passed && break
26630         done
26631
26632         if ! $passed; then
26633                 df -P $inodes $dir
26634                 echo
26635                 lfs df $inodes $dir
26636                 error "df and lfs df $1 output mismatch: "      \
26637                       "df ${inodes}: ${df_out[*]}, "            \
26638                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26639         fi
26640 }
26641
26642 test_418() {
26643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26644
26645         local dir=$DIR/$tdir
26646         local numfiles=$((RANDOM % 4096 + 2))
26647         local numblocks=$((RANDOM % 256 + 1))
26648
26649         wait_delete_completed
26650         test_mkdir $dir
26651
26652         # check block output
26653         check_lfs_df blocks $dir
26654         # check inode output
26655         check_lfs_df inodes $dir
26656
26657         # create a single file and retest
26658         echo "Creating a single file and testing"
26659         createmany -o $dir/$tfile- 1 &>/dev/null ||
26660                 error "creating 1 file in $dir failed"
26661         check_lfs_df blocks $dir
26662         check_lfs_df inodes $dir
26663
26664         # create a random number of files
26665         echo "Creating $((numfiles - 1)) files and testing"
26666         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26667                 error "creating $((numfiles - 1)) files in $dir failed"
26668
26669         # write a random number of blocks to the first test file
26670         echo "Writing $numblocks 4K blocks and testing"
26671         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26672                 count=$numblocks &>/dev/null ||
26673                 error "dd to $dir/${tfile}-0 failed"
26674
26675         # retest
26676         check_lfs_df blocks $dir
26677         check_lfs_df inodes $dir
26678
26679         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26680                 error "unlinking $numfiles files in $dir failed"
26681 }
26682 run_test 418 "df and lfs df outputs match"
26683
26684 test_419()
26685 {
26686         local dir=$DIR/$tdir
26687
26688         mkdir -p $dir
26689         touch $dir/file
26690
26691         cancel_lru_locks mdc
26692
26693         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26694         $LCTL set_param fail_loc=0x1410
26695         cat $dir/file
26696         $LCTL set_param fail_loc=0
26697         rm -rf $dir
26698 }
26699 run_test 419 "Verify open file by name doesn't crash kernel"
26700
26701 test_420()
26702 {
26703         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26704                 skip "Need MDS version at least 2.12.53"
26705
26706         local SAVE_UMASK=$(umask)
26707         local dir=$DIR/$tdir
26708         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26709
26710         mkdir -p $dir
26711         umask 0000
26712         mkdir -m03777 $dir/testdir
26713         ls -dn $dir/testdir
26714         # Need to remove trailing '.' when SELinux is enabled
26715         local dirperms=$(ls -dn $dir/testdir |
26716                          awk '{ sub(/\.$/, "", $1); print $1}')
26717         [ $dirperms == "drwxrwsrwt" ] ||
26718                 error "incorrect perms on $dir/testdir"
26719
26720         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26721                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26722         ls -n $dir/testdir/testfile
26723         local fileperms=$(ls -n $dir/testdir/testfile |
26724                           awk '{ sub(/\.$/, "", $1); print $1}')
26725         [ $fileperms == "-rwxr-xr-x" ] ||
26726                 error "incorrect perms on $dir/testdir/testfile"
26727
26728         umask $SAVE_UMASK
26729 }
26730 run_test 420 "clear SGID bit on non-directories for non-members"
26731
26732 test_421a() {
26733         local cnt
26734         local fid1
26735         local fid2
26736
26737         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26738                 skip "Need MDS version at least 2.12.54"
26739
26740         test_mkdir $DIR/$tdir
26741         createmany -o $DIR/$tdir/f 3
26742         cnt=$(ls -1 $DIR/$tdir | wc -l)
26743         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26744
26745         fid1=$(lfs path2fid $DIR/$tdir/f1)
26746         fid2=$(lfs path2fid $DIR/$tdir/f2)
26747         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26748
26749         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26750         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26751
26752         cnt=$(ls -1 $DIR/$tdir | wc -l)
26753         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26754
26755         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26756         createmany -o $DIR/$tdir/f 3
26757         cnt=$(ls -1 $DIR/$tdir | wc -l)
26758         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26759
26760         fid1=$(lfs path2fid $DIR/$tdir/f1)
26761         fid2=$(lfs path2fid $DIR/$tdir/f2)
26762         echo "remove using fsname $FSNAME"
26763         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26764
26765         cnt=$(ls -1 $DIR/$tdir | wc -l)
26766         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26767 }
26768 run_test 421a "simple rm by fid"
26769
26770 test_421b() {
26771         local cnt
26772         local FID1
26773         local FID2
26774
26775         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26776                 skip "Need MDS version at least 2.12.54"
26777
26778         test_mkdir $DIR/$tdir
26779         createmany -o $DIR/$tdir/f 3
26780         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26781         MULTIPID=$!
26782
26783         FID1=$(lfs path2fid $DIR/$tdir/f1)
26784         FID2=$(lfs path2fid $DIR/$tdir/f2)
26785         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26786
26787         kill -USR1 $MULTIPID
26788         wait
26789
26790         cnt=$(ls $DIR/$tdir | wc -l)
26791         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26792 }
26793 run_test 421b "rm by fid on open file"
26794
26795 test_421c() {
26796         local cnt
26797         local FIDS
26798
26799         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26800                 skip "Need MDS version at least 2.12.54"
26801
26802         test_mkdir $DIR/$tdir
26803         createmany -o $DIR/$tdir/f 3
26804         touch $DIR/$tdir/$tfile
26805         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26806         cnt=$(ls -1 $DIR/$tdir | wc -l)
26807         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26808
26809         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26810         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26811
26812         cnt=$(ls $DIR/$tdir | wc -l)
26813         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26814 }
26815 run_test 421c "rm by fid against hardlinked files"
26816
26817 test_421d() {
26818         local cnt
26819         local FIDS
26820
26821         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26822                 skip "Need MDS version at least 2.12.54"
26823
26824         test_mkdir $DIR/$tdir
26825         createmany -o $DIR/$tdir/f 4097
26826         cnt=$(ls -1 $DIR/$tdir | wc -l)
26827         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26828
26829         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26830         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26831
26832         cnt=$(ls $DIR/$tdir | wc -l)
26833         rm -rf $DIR/$tdir
26834         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26835 }
26836 run_test 421d "rmfid en masse"
26837
26838 test_421e() {
26839         local cnt
26840         local FID
26841
26842         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26843         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26844                 skip "Need MDS version at least 2.12.54"
26845
26846         mkdir -p $DIR/$tdir
26847         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26848         createmany -o $DIR/$tdir/striped_dir/f 512
26849         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26850         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26851
26852         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26853                 sed "s/[/][^:]*://g")
26854         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26855
26856         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26857         rm -rf $DIR/$tdir
26858         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26859 }
26860 run_test 421e "rmfid in DNE"
26861
26862 test_421f() {
26863         local cnt
26864         local FID
26865
26866         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26867                 skip "Need MDS version at least 2.12.54"
26868
26869         test_mkdir $DIR/$tdir
26870         touch $DIR/$tdir/f
26871         cnt=$(ls -1 $DIR/$tdir | wc -l)
26872         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26873
26874         FID=$(lfs path2fid $DIR/$tdir/f)
26875         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26876         # rmfid should fail
26877         cnt=$(ls -1 $DIR/$tdir | wc -l)
26878         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26879
26880         chmod a+rw $DIR/$tdir
26881         ls -la $DIR/$tdir
26882         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26883         # rmfid should fail
26884         cnt=$(ls -1 $DIR/$tdir | wc -l)
26885         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26886
26887         rm -f $DIR/$tdir/f
26888         $RUNAS touch $DIR/$tdir/f
26889         FID=$(lfs path2fid $DIR/$tdir/f)
26890         echo "rmfid as root"
26891         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26892         cnt=$(ls -1 $DIR/$tdir | wc -l)
26893         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26894
26895         rm -f $DIR/$tdir/f
26896         $RUNAS touch $DIR/$tdir/f
26897         cnt=$(ls -1 $DIR/$tdir | wc -l)
26898         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26899         FID=$(lfs path2fid $DIR/$tdir/f)
26900         # rmfid w/o user_fid2path mount option should fail
26901         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26902         cnt=$(ls -1 $DIR/$tdir | wc -l)
26903         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26904
26905         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26906         stack_trap "rmdir $tmpdir"
26907         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26908                 error "failed to mount client'"
26909         stack_trap "umount_client $tmpdir"
26910
26911         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26912         # rmfid should succeed
26913         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26914         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26915
26916         # rmfid shouldn't allow to remove files due to dir's permission
26917         chmod a+rwx $tmpdir/$tdir
26918         touch $tmpdir/$tdir/f
26919         ls -la $tmpdir/$tdir
26920         FID=$(lfs path2fid $tmpdir/$tdir/f)
26921         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26922         return 0
26923 }
26924 run_test 421f "rmfid checks permissions"
26925
26926 test_421g() {
26927         local cnt
26928         local FIDS
26929
26930         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26931         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26932                 skip "Need MDS version at least 2.12.54"
26933
26934         mkdir -p $DIR/$tdir
26935         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26936         createmany -o $DIR/$tdir/striped_dir/f 512
26937         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26938         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26939
26940         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26941                 sed "s/[/][^:]*://g")
26942
26943         rm -f $DIR/$tdir/striped_dir/f1*
26944         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26945         removed=$((512 - cnt))
26946
26947         # few files have been just removed, so we expect
26948         # rmfid to fail on their fids
26949         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26950         [ $removed != $errors ] && error "$errors != $removed"
26951
26952         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26953         rm -rf $DIR/$tdir
26954         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26955 }
26956 run_test 421g "rmfid to return errors properly"
26957
26958 test_422() {
26959         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26960         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26961         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26962         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26963         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26964
26965         local amc=$(at_max_get client)
26966         local amo=$(at_max_get mds1)
26967         local timeout=`lctl get_param -n timeout`
26968
26969         at_max_set 0 client
26970         at_max_set 0 mds1
26971
26972 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26973         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26974                         fail_val=$(((2*timeout + 10)*1000))
26975         touch $DIR/$tdir/d3/file &
26976         sleep 2
26977 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26978         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26979                         fail_val=$((2*timeout + 5))
26980         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26981         local pid=$!
26982         sleep 1
26983         kill -9 $pid
26984         sleep $((2 * timeout))
26985         echo kill $pid
26986         kill -9 $pid
26987         lctl mark touch
26988         touch $DIR/$tdir/d2/file3
26989         touch $DIR/$tdir/d2/file4
26990         touch $DIR/$tdir/d2/file5
26991
26992         wait
26993         at_max_set $amc client
26994         at_max_set $amo mds1
26995
26996         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26997         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26998                 error "Watchdog is always throttled"
26999 }
27000 run_test 422 "kill a process with RPC in progress"
27001
27002 stat_test() {
27003     df -h $MOUNT &
27004     df -h $MOUNT &
27005     df -h $MOUNT &
27006     df -h $MOUNT &
27007     df -h $MOUNT &
27008     df -h $MOUNT &
27009 }
27010
27011 test_423() {
27012     local _stats
27013     # ensure statfs cache is expired
27014     sleep 2;
27015
27016     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27017     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27018
27019     return 0
27020 }
27021 run_test 423 "statfs should return a right data"
27022
27023 test_424() {
27024 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27025         $LCTL set_param fail_loc=0x80000522
27026         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27027         rm -f $DIR/$tfile
27028 }
27029 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27030
27031 test_425() {
27032         test_mkdir -c -1 $DIR/$tdir
27033         $LFS setstripe -c -1 $DIR/$tdir
27034
27035         lru_resize_disable "" 100
27036         stack_trap "lru_resize_enable" EXIT
27037
27038         sleep 5
27039
27040         for i in $(seq $((MDSCOUNT * 125))); do
27041                 local t=$DIR/$tdir/$tfile_$i
27042
27043                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27044                         error_noexit "Create file $t"
27045         done
27046         stack_trap "rm -rf $DIR/$tdir" EXIT
27047
27048         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27049                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27050                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27051
27052                 [ $lock_count -le $lru_size ] ||
27053                         error "osc lock count $lock_count > lru size $lru_size"
27054         done
27055
27056         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27057                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27058                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27059
27060                 [ $lock_count -le $lru_size ] ||
27061                         error "mdc lock count $lock_count > lru size $lru_size"
27062         done
27063 }
27064 run_test 425 "lock count should not exceed lru size"
27065
27066 test_426() {
27067         splice-test -r $DIR/$tfile
27068         splice-test -rd $DIR/$tfile
27069         splice-test $DIR/$tfile
27070         splice-test -d $DIR/$tfile
27071 }
27072 run_test 426 "splice test on Lustre"
27073
27074 test_427() {
27075         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27076         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27077                 skip "Need MDS version at least 2.12.4"
27078         local log
27079
27080         mkdir $DIR/$tdir
27081         mkdir $DIR/$tdir/1
27082         mkdir $DIR/$tdir/2
27083         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27084         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27085
27086         $LFS getdirstripe $DIR/$tdir/1/dir
27087
27088         #first setfattr for creating updatelog
27089         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27090
27091 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27092         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27093         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27094         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27095
27096         sleep 2
27097         fail mds2
27098         wait_recovery_complete mds2 $((2*TIMEOUT))
27099
27100         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27101         echo $log | grep "get update log failed" &&
27102                 error "update log corruption is detected" || true
27103 }
27104 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27105
27106 test_428() {
27107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27108         local cache_limit=$CACHE_MAX
27109
27110         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27111         $LCTL set_param -n llite.*.max_cached_mb=64
27112
27113         mkdir $DIR/$tdir
27114         $LFS setstripe -c 1 $DIR/$tdir
27115         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27116         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27117         #test write
27118         for f in $(seq 4); do
27119                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27120         done
27121         wait
27122
27123         cancel_lru_locks osc
27124         # Test read
27125         for f in $(seq 4); do
27126                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27127         done
27128         wait
27129 }
27130 run_test 428 "large block size IO should not hang"
27131
27132 test_429() { # LU-7915 / LU-10948
27133         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27134         local testfile=$DIR/$tfile
27135         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27136         local new_flag=1
27137         local first_rpc
27138         local second_rpc
27139         local third_rpc
27140
27141         $LCTL get_param $ll_opencache_threshold_count ||
27142                 skip "client does not have opencache parameter"
27143
27144         set_opencache $new_flag
27145         stack_trap "restore_opencache"
27146         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27147                 error "enable opencache failed"
27148         touch $testfile
27149         # drop MDC DLM locks
27150         cancel_lru_locks mdc
27151         # clear MDC RPC stats counters
27152         $LCTL set_param $mdc_rpcstats=clear
27153
27154         # According to the current implementation, we need to run 3 times
27155         # open & close file to verify if opencache is enabled correctly.
27156         # 1st, RPCs are sent for lookup/open and open handle is released on
27157         #      close finally.
27158         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27159         #      so open handle won't be released thereafter.
27160         # 3rd, No RPC is sent out.
27161         $MULTIOP $testfile oc || error "multiop failed"
27162         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27163         echo "1st: $first_rpc RPCs in flight"
27164
27165         $MULTIOP $testfile oc || error "multiop failed"
27166         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27167         echo "2nd: $second_rpc RPCs in flight"
27168
27169         $MULTIOP $testfile oc || error "multiop failed"
27170         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27171         echo "3rd: $third_rpc RPCs in flight"
27172
27173         #verify no MDC RPC is sent
27174         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27175 }
27176 run_test 429 "verify if opencache flag on client side does work"
27177
27178 lseek_test_430() {
27179         local offset
27180         local file=$1
27181
27182         # data at [200K, 400K)
27183         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27184                 error "256K->512K dd fails"
27185         # data at [2M, 3M)
27186         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27187                 error "2M->3M dd fails"
27188         # data at [4M, 5M)
27189         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27190                 error "4M->5M dd fails"
27191         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27192         # start at first component hole #1
27193         printf "Seeking hole from 1000 ... "
27194         offset=$(lseek_test -l 1000 $file)
27195         echo $offset
27196         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27197         printf "Seeking data from 1000 ... "
27198         offset=$(lseek_test -d 1000 $file)
27199         echo $offset
27200         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27201
27202         # start at first component data block
27203         printf "Seeking hole from 300000 ... "
27204         offset=$(lseek_test -l 300000 $file)
27205         echo $offset
27206         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27207         printf "Seeking data from 300000 ... "
27208         offset=$(lseek_test -d 300000 $file)
27209         echo $offset
27210         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27211
27212         # start at the first component but beyond end of object size
27213         printf "Seeking hole from 1000000 ... "
27214         offset=$(lseek_test -l 1000000 $file)
27215         echo $offset
27216         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27217         printf "Seeking data from 1000000 ... "
27218         offset=$(lseek_test -d 1000000 $file)
27219         echo $offset
27220         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27221
27222         # start at second component stripe 2 (empty file)
27223         printf "Seeking hole from 1500000 ... "
27224         offset=$(lseek_test -l 1500000 $file)
27225         echo $offset
27226         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27227         printf "Seeking data from 1500000 ... "
27228         offset=$(lseek_test -d 1500000 $file)
27229         echo $offset
27230         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27231
27232         # start at second component stripe 1 (all data)
27233         printf "Seeking hole from 3000000 ... "
27234         offset=$(lseek_test -l 3000000 $file)
27235         echo $offset
27236         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27237         printf "Seeking data from 3000000 ... "
27238         offset=$(lseek_test -d 3000000 $file)
27239         echo $offset
27240         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27241
27242         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27243                 error "2nd dd fails"
27244         echo "Add data block at 640K...1280K"
27245
27246         # start at before new data block, in hole
27247         printf "Seeking hole from 600000 ... "
27248         offset=$(lseek_test -l 600000 $file)
27249         echo $offset
27250         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27251         printf "Seeking data from 600000 ... "
27252         offset=$(lseek_test -d 600000 $file)
27253         echo $offset
27254         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27255
27256         # start at the first component new data block
27257         printf "Seeking hole from 1000000 ... "
27258         offset=$(lseek_test -l 1000000 $file)
27259         echo $offset
27260         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27261         printf "Seeking data from 1000000 ... "
27262         offset=$(lseek_test -d 1000000 $file)
27263         echo $offset
27264         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27265
27266         # start at second component stripe 2, new data
27267         printf "Seeking hole from 1200000 ... "
27268         offset=$(lseek_test -l 1200000 $file)
27269         echo $offset
27270         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27271         printf "Seeking data from 1200000 ... "
27272         offset=$(lseek_test -d 1200000 $file)
27273         echo $offset
27274         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27275
27276         # start beyond file end
27277         printf "Using offset > filesize ... "
27278         lseek_test -l 4000000 $file && error "lseek should fail"
27279         printf "Using offset > filesize ... "
27280         lseek_test -d 4000000 $file && error "lseek should fail"
27281
27282         printf "Done\n\n"
27283 }
27284
27285 test_430a() {
27286         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27287                 skip "MDT does not support SEEK_HOLE"
27288
27289         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27290                 skip "OST does not support SEEK_HOLE"
27291
27292         local file=$DIR/$tdir/$tfile
27293
27294         mkdir -p $DIR/$tdir
27295
27296         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27297         # OST stripe #1 will have continuous data at [1M, 3M)
27298         # OST stripe #2 is empty
27299         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27300         lseek_test_430 $file
27301         rm $file
27302         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27303         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27304         lseek_test_430 $file
27305         rm $file
27306         $LFS setstripe -c2 -S 512K $file
27307         echo "Two stripes, stripe size 512K"
27308         lseek_test_430 $file
27309         rm $file
27310         # FLR with stale mirror
27311         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27312                        -N -c2 -S 1M $file
27313         echo "Mirrored file:"
27314         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27315         echo "Plain 2 stripes 1M"
27316         lseek_test_430 $file
27317         rm $file
27318 }
27319 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27320
27321 test_430b() {
27322         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27323                 skip "OST does not support SEEK_HOLE"
27324
27325         local offset
27326         local file=$DIR/$tdir/$tfile
27327
27328         mkdir -p $DIR/$tdir
27329         # Empty layout lseek should fail
27330         $MCREATE $file
27331         # seek from 0
27332         printf "Seeking hole from 0 ... "
27333         lseek_test -l 0 $file && error "lseek should fail"
27334         printf "Seeking data from 0 ... "
27335         lseek_test -d 0 $file && error "lseek should fail"
27336         rm $file
27337
27338         # 1M-hole file
27339         $LFS setstripe -E 1M -c2 -E eof $file
27340         $TRUNCATE $file 1048576
27341         printf "Seeking hole from 1000000 ... "
27342         offset=$(lseek_test -l 1000000 $file)
27343         echo $offset
27344         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27345         printf "Seeking data from 1000000 ... "
27346         lseek_test -d 1000000 $file && error "lseek should fail"
27347         rm $file
27348
27349         # full component followed by non-inited one
27350         $LFS setstripe -E 1M -c2 -E eof $file
27351         dd if=/dev/urandom of=$file bs=1M count=1
27352         printf "Seeking hole from 1000000 ... "
27353         offset=$(lseek_test -l 1000000 $file)
27354         echo $offset
27355         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27356         printf "Seeking hole from 1048576 ... "
27357         lseek_test -l 1048576 $file && error "lseek should fail"
27358         # init second component and truncate back
27359         echo "123" >> $file
27360         $TRUNCATE $file 1048576
27361         printf "Seeking hole from 1000000 ... "
27362         offset=$(lseek_test -l 1000000 $file)
27363         echo $offset
27364         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27365         printf "Seeking hole from 1048576 ... "
27366         lseek_test -l 1048576 $file && error "lseek should fail"
27367         # boundary checks for big values
27368         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27369         offset=$(lseek_test -d 0 $file.10g)
27370         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27371         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27372         offset=$(lseek_test -d 0 $file.100g)
27373         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27374         return 0
27375 }
27376 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27377
27378 test_430c() {
27379         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27380                 skip "OST does not support SEEK_HOLE"
27381
27382         local file=$DIR/$tdir/$tfile
27383         local start
27384
27385         mkdir -p $DIR/$tdir
27386         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27387
27388         # cp version 8.33+ prefers lseek over fiemap
27389         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27390                 start=$SECONDS
27391                 time cp $file /dev/null
27392                 (( SECONDS - start < 5 )) ||
27393                         error "cp: too long runtime $((SECONDS - start))"
27394
27395         fi
27396         # tar version 1.29+ supports SEEK_HOLE/DATA
27397         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27398                 start=$SECONDS
27399                 time tar cS $file - | cat > /dev/null
27400                 (( SECONDS - start < 5 )) ||
27401                         error "tar: too long runtime $((SECONDS - start))"
27402         fi
27403 }
27404 run_test 430c "lseek: external tools check"
27405
27406 test_431() { # LU-14187
27407         local file=$DIR/$tdir/$tfile
27408
27409         mkdir -p $DIR/$tdir
27410         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27411         dd if=/dev/urandom of=$file bs=4k count=1
27412         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27413         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27414         #define OBD_FAIL_OST_RESTART_IO 0x251
27415         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27416         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27417         cp $file $file.0
27418         cancel_lru_locks
27419         sync_all_data
27420         echo 3 > /proc/sys/vm/drop_caches
27421         diff  $file $file.0 || error "data diff"
27422 }
27423 run_test 431 "Restart transaction for IO"
27424
27425 cleanup_test_432() {
27426         do_facet mgs $LCTL nodemap_activate 0
27427         wait_nm_sync active
27428 }
27429
27430 test_432() {
27431         local tmpdir=$TMP/dir432
27432
27433         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27434                 skip "Need MDS version at least 2.14.52"
27435
27436         stack_trap cleanup_test_432 EXIT
27437         mkdir $DIR/$tdir
27438         mkdir $tmpdir
27439
27440         do_facet mgs $LCTL nodemap_activate 1
27441         wait_nm_sync active
27442         do_facet mgs $LCTL nodemap_modify --name default \
27443                 --property admin --value 1
27444         do_facet mgs $LCTL nodemap_modify --name default \
27445                 --property trusted --value 1
27446         cancel_lru_locks mdc
27447         wait_nm_sync default admin_nodemap
27448         wait_nm_sync default trusted_nodemap
27449
27450         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27451                grep -ci "Operation not permitted") -ne 0 ]; then
27452                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27453         fi
27454 }
27455 run_test 432 "mv dir from outside Lustre"
27456
27457 test_433() {
27458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27459
27460         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27461                 skip "inode cache not supported"
27462
27463         $LCTL set_param llite.*.inode_cache=0
27464         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27465
27466         local count=256
27467         local before
27468         local after
27469
27470         cancel_lru_locks mdc
27471         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27472         createmany -m $DIR/$tdir/f $count
27473         createmany -d $DIR/$tdir/d $count
27474         ls -l $DIR/$tdir > /dev/null
27475         stack_trap "rm -rf $DIR/$tdir"
27476
27477         before=$(num_objects)
27478         cancel_lru_locks mdc
27479         after=$(num_objects)
27480
27481         # sometimes even @before is less than 2 * count
27482         while (( before - after < count )); do
27483                 sleep 1
27484                 after=$(num_objects)
27485                 wait=$((wait + 1))
27486                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27487                 if (( wait > 60 )); then
27488                         error "inode slab grew from $before to $after"
27489                 fi
27490         done
27491
27492         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27493 }
27494 run_test 433 "ldlm lock cancel releases dentries and inodes"
27495
27496 prep_801() {
27497         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27498         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27499                 skip "Need server version at least 2.9.55"
27500
27501         start_full_debug_logging
27502 }
27503
27504 post_801() {
27505         stop_full_debug_logging
27506 }
27507
27508 barrier_stat() {
27509         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27510                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27511                            awk '/The barrier for/ { print $7 }')
27512                 echo $st
27513         else
27514                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27515                 echo \'$st\'
27516         fi
27517 }
27518
27519 barrier_expired() {
27520         local expired
27521
27522         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27523                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27524                           awk '/will be expired/ { print $7 }')
27525         else
27526                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27527         fi
27528
27529         echo $expired
27530 }
27531
27532 test_801a() {
27533         prep_801
27534
27535         echo "Start barrier_freeze at: $(date)"
27536         #define OBD_FAIL_BARRIER_DELAY          0x2202
27537         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27538         # Do not reduce barrier time - See LU-11873
27539         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27540
27541         sleep 2
27542         local b_status=$(barrier_stat)
27543         echo "Got barrier status at: $(date)"
27544         [ "$b_status" = "'freezing_p1'" ] ||
27545                 error "(1) unexpected barrier status $b_status"
27546
27547         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27548         wait
27549         b_status=$(barrier_stat)
27550         [ "$b_status" = "'frozen'" ] ||
27551                 error "(2) unexpected barrier status $b_status"
27552
27553         local expired=$(barrier_expired)
27554         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27555         sleep $((expired + 3))
27556
27557         b_status=$(barrier_stat)
27558         [ "$b_status" = "'expired'" ] ||
27559                 error "(3) unexpected barrier status $b_status"
27560
27561         # Do not reduce barrier time - See LU-11873
27562         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27563                 error "(4) fail to freeze barrier"
27564
27565         b_status=$(barrier_stat)
27566         [ "$b_status" = "'frozen'" ] ||
27567                 error "(5) unexpected barrier status $b_status"
27568
27569         echo "Start barrier_thaw at: $(date)"
27570         #define OBD_FAIL_BARRIER_DELAY          0x2202
27571         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27572         do_facet mgs $LCTL barrier_thaw $FSNAME &
27573
27574         sleep 2
27575         b_status=$(barrier_stat)
27576         echo "Got barrier status at: $(date)"
27577         [ "$b_status" = "'thawing'" ] ||
27578                 error "(6) unexpected barrier status $b_status"
27579
27580         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27581         wait
27582         b_status=$(barrier_stat)
27583         [ "$b_status" = "'thawed'" ] ||
27584                 error "(7) unexpected barrier status $b_status"
27585
27586         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27587         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27588         do_facet mgs $LCTL barrier_freeze $FSNAME
27589
27590         b_status=$(barrier_stat)
27591         [ "$b_status" = "'failed'" ] ||
27592                 error "(8) unexpected barrier status $b_status"
27593
27594         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27595         do_facet mgs $LCTL barrier_thaw $FSNAME
27596
27597         post_801
27598 }
27599 run_test 801a "write barrier user interfaces and stat machine"
27600
27601 test_801b() {
27602         prep_801
27603
27604         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27605         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27606         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27607         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27608         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27609
27610         cancel_lru_locks mdc
27611
27612         # 180 seconds should be long enough
27613         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27614
27615         local b_status=$(barrier_stat)
27616         [ "$b_status" = "'frozen'" ] ||
27617                 error "(6) unexpected barrier status $b_status"
27618
27619         mkdir $DIR/$tdir/d0/d10 &
27620         mkdir_pid=$!
27621
27622         touch $DIR/$tdir/d1/f13 &
27623         touch_pid=$!
27624
27625         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27626         ln_pid=$!
27627
27628         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27629         mv_pid=$!
27630
27631         rm -f $DIR/$tdir/d4/f12 &
27632         rm_pid=$!
27633
27634         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27635
27636         # To guarantee taht the 'stat' is not blocked
27637         b_status=$(barrier_stat)
27638         [ "$b_status" = "'frozen'" ] ||
27639                 error "(8) unexpected barrier status $b_status"
27640
27641         # let above commands to run at background
27642         sleep 5
27643
27644         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27645         ps -p $touch_pid || error "(10) touch should be blocked"
27646         ps -p $ln_pid || error "(11) link should be blocked"
27647         ps -p $mv_pid || error "(12) rename should be blocked"
27648         ps -p $rm_pid || error "(13) unlink should be blocked"
27649
27650         b_status=$(barrier_stat)
27651         [ "$b_status" = "'frozen'" ] ||
27652                 error "(14) unexpected barrier status $b_status"
27653
27654         do_facet mgs $LCTL barrier_thaw $FSNAME
27655         b_status=$(barrier_stat)
27656         [ "$b_status" = "'thawed'" ] ||
27657                 error "(15) unexpected barrier status $b_status"
27658
27659         wait $mkdir_pid || error "(16) mkdir should succeed"
27660         wait $touch_pid || error "(17) touch should succeed"
27661         wait $ln_pid || error "(18) link should succeed"
27662         wait $mv_pid || error "(19) rename should succeed"
27663         wait $rm_pid || error "(20) unlink should succeed"
27664
27665         post_801
27666 }
27667 run_test 801b "modification will be blocked by write barrier"
27668
27669 test_801c() {
27670         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27671
27672         prep_801
27673
27674         stop mds2 || error "(1) Fail to stop mds2"
27675
27676         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27677
27678         local b_status=$(barrier_stat)
27679         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27680                 do_facet mgs $LCTL barrier_thaw $FSNAME
27681                 error "(2) unexpected barrier status $b_status"
27682         }
27683
27684         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27685                 error "(3) Fail to rescan barrier bitmap"
27686
27687         # Do not reduce barrier time - See LU-11873
27688         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27689
27690         b_status=$(barrier_stat)
27691         [ "$b_status" = "'frozen'" ] ||
27692                 error "(4) unexpected barrier status $b_status"
27693
27694         do_facet mgs $LCTL barrier_thaw $FSNAME
27695         b_status=$(barrier_stat)
27696         [ "$b_status" = "'thawed'" ] ||
27697                 error "(5) unexpected barrier status $b_status"
27698
27699         local devname=$(mdsdevname 2)
27700
27701         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27702
27703         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27704                 error "(7) Fail to rescan barrier bitmap"
27705
27706         post_801
27707 }
27708 run_test 801c "rescan barrier bitmap"
27709
27710 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27711 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27712 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27713 saved_MOUNT_OPTS=$MOUNT_OPTS
27714
27715 cleanup_802a() {
27716         trap 0
27717
27718         stopall
27719         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27720         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27721         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27722         MOUNT_OPTS=$saved_MOUNT_OPTS
27723         setupall
27724 }
27725
27726 test_802a() {
27727         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27728         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27729         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27730                 skip "Need server version at least 2.9.55"
27731
27732         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27733
27734         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27735
27736         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27737                 error "(2) Fail to copy"
27738
27739         trap cleanup_802a EXIT
27740
27741         # sync by force before remount as readonly
27742         sync; sync_all_data; sleep 3; sync_all_data
27743
27744         stopall
27745
27746         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27747         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27748         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27749
27750         echo "Mount the server as read only"
27751         setupall server_only || error "(3) Fail to start servers"
27752
27753         echo "Mount client without ro should fail"
27754         mount_client $MOUNT &&
27755                 error "(4) Mount client without 'ro' should fail"
27756
27757         echo "Mount client with ro should succeed"
27758         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27759         mount_client $MOUNT ||
27760                 error "(5) Mount client with 'ro' should succeed"
27761
27762         echo "Modify should be refused"
27763         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27764
27765         echo "Read should be allowed"
27766         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27767                 error "(7) Read should succeed under ro mode"
27768
27769         cleanup_802a
27770 }
27771 run_test 802a "simulate readonly device"
27772
27773 test_802b() {
27774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27775         remote_mds_nodsh && skip "remote MDS with nodsh"
27776
27777         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27778                 skip "readonly option not available"
27779
27780         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27781
27782         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27783                 error "(2) Fail to copy"
27784
27785         # write back all cached data before setting MDT to readonly
27786         cancel_lru_locks
27787         sync_all_data
27788
27789         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27790         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27791
27792         echo "Modify should be refused"
27793         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27794
27795         echo "Read should be allowed"
27796         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27797                 error "(7) Read should succeed under ro mode"
27798
27799         # disable readonly
27800         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27801 }
27802 run_test 802b "be able to set MDTs to readonly"
27803
27804 test_803a() {
27805         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27806         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27807                 skip "MDS needs to be newer than 2.10.54"
27808
27809         mkdir_on_mdt0 $DIR/$tdir
27810         # Create some objects on all MDTs to trigger related logs objects
27811         for idx in $(seq $MDSCOUNT); do
27812                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27813                         $DIR/$tdir/dir${idx} ||
27814                         error "Fail to create $DIR/$tdir/dir${idx}"
27815         done
27816
27817         wait_delete_completed # ensure old test cleanups are finished
27818         sleep 3
27819         echo "before create:"
27820         $LFS df -i $MOUNT
27821         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27822
27823         for i in {1..10}; do
27824                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27825                         error "Fail to create $DIR/$tdir/foo$i"
27826         done
27827
27828         # sync ZFS-on-MDS to refresh statfs data
27829         wait_zfs_commit mds1
27830         sleep 3
27831         echo "after create:"
27832         $LFS df -i $MOUNT
27833         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27834
27835         # allow for an llog to be cleaned up during the test
27836         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27837                 error "before ($before_used) + 10 > after ($after_used)"
27838
27839         for i in {1..10}; do
27840                 rm -rf $DIR/$tdir/foo$i ||
27841                         error "Fail to remove $DIR/$tdir/foo$i"
27842         done
27843
27844         # sync ZFS-on-MDS to refresh statfs data
27845         wait_zfs_commit mds1
27846         wait_delete_completed
27847         sleep 3 # avoid MDT return cached statfs
27848         echo "after unlink:"
27849         $LFS df -i $MOUNT
27850         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27851
27852         # allow for an llog to be created during the test
27853         [ $after_used -le $((before_used + 1)) ] ||
27854                 error "after ($after_used) > before ($before_used) + 1"
27855 }
27856 run_test 803a "verify agent object for remote object"
27857
27858 test_803b() {
27859         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27860         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27861                 skip "MDS needs to be newer than 2.13.56"
27862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27863
27864         for i in $(seq 0 $((MDSCOUNT - 1))); do
27865                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27866         done
27867
27868         local before=0
27869         local after=0
27870
27871         local tmp
27872
27873         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27874         for i in $(seq 0 $((MDSCOUNT - 1))); do
27875                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27876                         awk '/getattr/ { print $2 }')
27877                 before=$((before + tmp))
27878         done
27879         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27880         for i in $(seq 0 $((MDSCOUNT - 1))); do
27881                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27882                         awk '/getattr/ { print $2 }')
27883                 after=$((after + tmp))
27884         done
27885
27886         [ $before -eq $after ] || error "getattr count $before != $after"
27887 }
27888 run_test 803b "remote object can getattr from cache"
27889
27890 test_804() {
27891         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27892         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27893                 skip "MDS needs to be newer than 2.10.54"
27894         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27895
27896         mkdir -p $DIR/$tdir
27897         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27898                 error "Fail to create $DIR/$tdir/dir0"
27899
27900         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27901         local dev=$(mdsdevname 2)
27902
27903         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27904                 grep ${fid} || error "NOT found agent entry for dir0"
27905
27906         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27907                 error "Fail to create $DIR/$tdir/dir1"
27908
27909         touch $DIR/$tdir/dir1/foo0 ||
27910                 error "Fail to create $DIR/$tdir/dir1/foo0"
27911         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27912         local rc=0
27913
27914         for idx in $(seq $MDSCOUNT); do
27915                 dev=$(mdsdevname $idx)
27916                 do_facet mds${idx} \
27917                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27918                         grep ${fid} && rc=$idx
27919         done
27920
27921         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27922                 error "Fail to rename foo0 to foo1"
27923         if [ $rc -eq 0 ]; then
27924                 for idx in $(seq $MDSCOUNT); do
27925                         dev=$(mdsdevname $idx)
27926                         do_facet mds${idx} \
27927                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27928                         grep ${fid} && rc=$idx
27929                 done
27930         fi
27931
27932         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27933                 error "Fail to rename foo1 to foo2"
27934         if [ $rc -eq 0 ]; then
27935                 for idx in $(seq $MDSCOUNT); do
27936                         dev=$(mdsdevname $idx)
27937                         do_facet mds${idx} \
27938                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27939                         grep ${fid} && rc=$idx
27940                 done
27941         fi
27942
27943         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27944
27945         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27946                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27947         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27948                 error "Fail to rename foo2 to foo0"
27949         unlink $DIR/$tdir/dir1/foo0 ||
27950                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27951         rm -rf $DIR/$tdir/dir0 ||
27952                 error "Fail to rm $DIR/$tdir/dir0"
27953
27954         for idx in $(seq $MDSCOUNT); do
27955                 rc=0
27956
27957                 stop mds${idx}
27958                 dev=$(mdsdevname $idx)
27959                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27960                         rc=$?
27961                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27962                         error "mount mds$idx failed"
27963                 df $MOUNT > /dev/null 2>&1
27964
27965                 # e2fsck should not return error
27966                 [ $rc -eq 0 ] ||
27967                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27968         done
27969 }
27970 run_test 804 "verify agent entry for remote entry"
27971
27972 cleanup_805() {
27973         do_facet $SINGLEMDS zfs set quota=$old $fsset
27974         unlinkmany $DIR/$tdir/f- 1000000
27975         trap 0
27976 }
27977
27978 test_805() {
27979         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27980         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27981         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27982                 skip "netfree not implemented before 0.7"
27983         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27984                 skip "Need MDS version at least 2.10.57"
27985
27986         local fsset
27987         local freekb
27988         local usedkb
27989         local old
27990         local quota
27991         local pref="osd-zfs.$FSNAME-MDT0000."
27992
27993         # limit available space on MDS dataset to meet nospace issue
27994         # quickly. then ZFS 0.7.2 can use reserved space if asked
27995         # properly (using netfree flag in osd_declare_destroy()
27996         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27997         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27998                 gawk '{print $3}')
27999         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28000         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28001         let "usedkb=usedkb-freekb"
28002         let "freekb=freekb/2"
28003         if let "freekb > 5000"; then
28004                 let "freekb=5000"
28005         fi
28006         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28007         trap cleanup_805 EXIT
28008         mkdir_on_mdt0 $DIR/$tdir
28009         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28010                 error "Can't set PFL layout"
28011         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28012         rm -rf $DIR/$tdir || error "not able to remove"
28013         do_facet $SINGLEMDS zfs set quota=$old $fsset
28014         trap 0
28015 }
28016 run_test 805 "ZFS can remove from full fs"
28017
28018 # Size-on-MDS test
28019 check_lsom_data()
28020 {
28021         local file=$1
28022         local expect=$(stat -c %s $file)
28023
28024         check_lsom_size $1 $expect
28025
28026         local blocks=$($LFS getsom -b $file)
28027         expect=$(stat -c %b $file)
28028         [[ $blocks == $expect ]] ||
28029                 error "$file expected blocks: $expect, got: $blocks"
28030 }
28031
28032 check_lsom_size()
28033 {
28034         local size
28035         local expect=$2
28036
28037         cancel_lru_locks mdc
28038
28039         size=$($LFS getsom -s $1)
28040         [[ $size == $expect ]] ||
28041                 error "$file expected size: $expect, got: $size"
28042 }
28043
28044 test_806() {
28045         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28046                 skip "Need MDS version at least 2.11.52"
28047
28048         local bs=1048576
28049
28050         touch $DIR/$tfile || error "touch $tfile failed"
28051
28052         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28053         save_lustre_params client "llite.*.xattr_cache" > $save
28054         lctl set_param llite.*.xattr_cache=0
28055         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28056
28057         # single-threaded write
28058         echo "Test SOM for single-threaded write"
28059         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28060                 error "write $tfile failed"
28061         check_lsom_size $DIR/$tfile $bs
28062
28063         local num=32
28064         local size=$(($num * $bs))
28065         local offset=0
28066         local i
28067
28068         echo "Test SOM for single client multi-threaded($num) write"
28069         $TRUNCATE $DIR/$tfile 0
28070         for ((i = 0; i < $num; i++)); do
28071                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28072                 local pids[$i]=$!
28073                 offset=$((offset + $bs))
28074         done
28075         for (( i=0; i < $num; i++ )); do
28076                 wait ${pids[$i]}
28077         done
28078         check_lsom_size $DIR/$tfile $size
28079
28080         $TRUNCATE $DIR/$tfile 0
28081         for ((i = 0; i < $num; i++)); do
28082                 offset=$((offset - $bs))
28083                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28084                 local pids[$i]=$!
28085         done
28086         for (( i=0; i < $num; i++ )); do
28087                 wait ${pids[$i]}
28088         done
28089         check_lsom_size $DIR/$tfile $size
28090
28091         # multi-client writes
28092         num=$(get_node_count ${CLIENTS//,/ })
28093         size=$(($num * $bs))
28094         offset=0
28095         i=0
28096
28097         echo "Test SOM for multi-client ($num) writes"
28098         $TRUNCATE $DIR/$tfile 0
28099         for client in ${CLIENTS//,/ }; do
28100                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28101                 local pids[$i]=$!
28102                 i=$((i + 1))
28103                 offset=$((offset + $bs))
28104         done
28105         for (( i=0; i < $num; i++ )); do
28106                 wait ${pids[$i]}
28107         done
28108         check_lsom_size $DIR/$tfile $offset
28109
28110         i=0
28111         $TRUNCATE $DIR/$tfile 0
28112         for client in ${CLIENTS//,/ }; do
28113                 offset=$((offset - $bs))
28114                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28115                 local pids[$i]=$!
28116                 i=$((i + 1))
28117         done
28118         for (( i=0; i < $num; i++ )); do
28119                 wait ${pids[$i]}
28120         done
28121         check_lsom_size $DIR/$tfile $size
28122
28123         # verify truncate
28124         echo "Test SOM for truncate"
28125         $TRUNCATE $DIR/$tfile 1048576
28126         check_lsom_size $DIR/$tfile 1048576
28127         $TRUNCATE $DIR/$tfile 1234
28128         check_lsom_size $DIR/$tfile 1234
28129
28130         # verify SOM blocks count
28131         echo "Verify SOM block count"
28132         $TRUNCATE $DIR/$tfile 0
28133         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28134                 error "failed to write file $tfile"
28135         check_lsom_data $DIR/$tfile
28136 }
28137 run_test 806 "Verify Lazy Size on MDS"
28138
28139 test_807() {
28140         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28141         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28142                 skip "Need MDS version at least 2.11.52"
28143
28144         # Registration step
28145         changelog_register || error "changelog_register failed"
28146         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28147         changelog_users $SINGLEMDS | grep -q $cl_user ||
28148                 error "User $cl_user not found in changelog_users"
28149
28150         rm -rf $DIR/$tdir || error "rm $tdir failed"
28151         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28152         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28153         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28154         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28155                 error "truncate $tdir/trunc failed"
28156
28157         local bs=1048576
28158         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28159                 error "write $tfile failed"
28160
28161         # multi-client wirtes
28162         local num=$(get_node_count ${CLIENTS//,/ })
28163         local offset=0
28164         local i=0
28165
28166         echo "Test SOM for multi-client ($num) writes"
28167         touch $DIR/$tfile || error "touch $tfile failed"
28168         $TRUNCATE $DIR/$tfile 0
28169         for client in ${CLIENTS//,/ }; do
28170                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28171                 local pids[$i]=$!
28172                 i=$((i + 1))
28173                 offset=$((offset + $bs))
28174         done
28175         for (( i=0; i < $num; i++ )); do
28176                 wait ${pids[$i]}
28177         done
28178
28179         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28180         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28181         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28182         check_lsom_data $DIR/$tdir/trunc
28183         check_lsom_data $DIR/$tdir/single_dd
28184         check_lsom_data $DIR/$tfile
28185
28186         rm -rf $DIR/$tdir
28187         # Deregistration step
28188         changelog_deregister || error "changelog_deregister failed"
28189 }
28190 run_test 807 "verify LSOM syncing tool"
28191
28192 check_som_nologged()
28193 {
28194         local lines=$($LFS changelog $FSNAME-MDT0000 |
28195                 grep 'x=trusted.som' | wc -l)
28196         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28197 }
28198
28199 test_808() {
28200         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28201                 skip "Need MDS version at least 2.11.55"
28202
28203         # Registration step
28204         changelog_register || error "changelog_register failed"
28205
28206         touch $DIR/$tfile || error "touch $tfile failed"
28207         check_som_nologged
28208
28209         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28210                 error "write $tfile failed"
28211         check_som_nologged
28212
28213         $TRUNCATE $DIR/$tfile 1234
28214         check_som_nologged
28215
28216         $TRUNCATE $DIR/$tfile 1048576
28217         check_som_nologged
28218
28219         # Deregistration step
28220         changelog_deregister || error "changelog_deregister failed"
28221 }
28222 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28223
28224 check_som_nodata()
28225 {
28226         $LFS getsom $1
28227         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28228 }
28229
28230 test_809() {
28231         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28232                 skip "Need MDS version at least 2.11.56"
28233
28234         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28235                 error "failed to create DoM-only file $DIR/$tfile"
28236         touch $DIR/$tfile || error "touch $tfile failed"
28237         check_som_nodata $DIR/$tfile
28238
28239         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28240                 error "write $tfile failed"
28241         check_som_nodata $DIR/$tfile
28242
28243         $TRUNCATE $DIR/$tfile 1234
28244         check_som_nodata $DIR/$tfile
28245
28246         $TRUNCATE $DIR/$tfile 4097
28247         check_som_nodata $DIR/$file
28248 }
28249 run_test 809 "Verify no SOM xattr store for DoM-only files"
28250
28251 test_810() {
28252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28253         $GSS && skip_env "could not run with gss"
28254         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28255                 skip "OST < 2.12.58 doesn't align checksum"
28256
28257         set_checksums 1
28258         stack_trap "set_checksums $ORIG_CSUM" EXIT
28259         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28260
28261         local csum
28262         local before
28263         local after
28264         for csum in $CKSUM_TYPES; do
28265                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28266                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28267                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28268                         eval set -- $i
28269                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28270                         before=$(md5sum $DIR/$tfile)
28271                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28272                         after=$(md5sum $DIR/$tfile)
28273                         [ "$before" == "$after" ] ||
28274                                 error "$csum: $before != $after bs=$1 seek=$2"
28275                 done
28276         done
28277 }
28278 run_test 810 "partial page writes on ZFS (LU-11663)"
28279
28280 test_812a() {
28281         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28282                 skip "OST < 2.12.51 doesn't support this fail_loc"
28283
28284         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28285         # ensure ost1 is connected
28286         stat $DIR/$tfile >/dev/null || error "can't stat"
28287         wait_osc_import_state client ost1 FULL
28288         # no locks, no reqs to let the connection idle
28289         cancel_lru_locks osc
28290
28291         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28292 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28293         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28294         wait_osc_import_state client ost1 CONNECTING
28295         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28296
28297         stat $DIR/$tfile >/dev/null || error "can't stat file"
28298 }
28299 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28300
28301 test_812b() { # LU-12378
28302         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28303                 skip "OST < 2.12.51 doesn't support this fail_loc"
28304
28305         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28306         # ensure ost1 is connected
28307         stat $DIR/$tfile >/dev/null || error "can't stat"
28308         wait_osc_import_state client ost1 FULL
28309         # no locks, no reqs to let the connection idle
28310         cancel_lru_locks osc
28311
28312         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28313 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28314         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28315         wait_osc_import_state client ost1 CONNECTING
28316         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28317
28318         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28319         wait_osc_import_state client ost1 IDLE
28320 }
28321 run_test 812b "do not drop no resend request for idle connect"
28322
28323 test_812c() {
28324         local old
28325
28326         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28327
28328         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28329         $LFS getstripe $DIR/$tfile
28330         $LCTL set_param osc.*.idle_timeout=10
28331         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28332         # ensure ost1 is connected
28333         stat $DIR/$tfile >/dev/null || error "can't stat"
28334         wait_osc_import_state client ost1 FULL
28335         # no locks, no reqs to let the connection idle
28336         cancel_lru_locks osc
28337
28338 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28339         $LCTL set_param fail_loc=0x80000533
28340         sleep 15
28341         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28342 }
28343 run_test 812c "idle import vs lock enqueue race"
28344
28345 test_813() {
28346         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28347         [ -z "$file_heat_sav" ] && skip "no file heat support"
28348
28349         local readsample
28350         local writesample
28351         local readbyte
28352         local writebyte
28353         local readsample1
28354         local writesample1
28355         local readbyte1
28356         local writebyte1
28357
28358         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28359         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28360
28361         $LCTL set_param -n llite.*.file_heat=1
28362         echo "Turn on file heat"
28363         echo "Period second: $period_second, Decay percentage: $decay_pct"
28364
28365         echo "QQQQ" > $DIR/$tfile
28366         echo "QQQQ" > $DIR/$tfile
28367         echo "QQQQ" > $DIR/$tfile
28368         cat $DIR/$tfile > /dev/null
28369         cat $DIR/$tfile > /dev/null
28370         cat $DIR/$tfile > /dev/null
28371         cat $DIR/$tfile > /dev/null
28372
28373         local out=$($LFS heat_get $DIR/$tfile)
28374
28375         $LFS heat_get $DIR/$tfile
28376         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28377         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28378         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28379         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28380
28381         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28382         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28383         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28384         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28385
28386         sleep $((period_second + 3))
28387         echo "Sleep $((period_second + 3)) seconds..."
28388         # The recursion formula to calculate the heat of the file f is as
28389         # follow:
28390         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28391         # Where Hi is the heat value in the period between time points i*I and
28392         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28393         # to the weight of Ci.
28394         out=$($LFS heat_get $DIR/$tfile)
28395         $LFS heat_get $DIR/$tfile
28396         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28397         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28398         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28399         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28400
28401         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28402                 error "read sample ($readsample) is wrong"
28403         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28404                 error "write sample ($writesample) is wrong"
28405         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28406                 error "read bytes ($readbyte) is wrong"
28407         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28408                 error "write bytes ($writebyte) is wrong"
28409
28410         echo "QQQQ" > $DIR/$tfile
28411         echo "QQQQ" > $DIR/$tfile
28412         echo "QQQQ" > $DIR/$tfile
28413         cat $DIR/$tfile > /dev/null
28414         cat $DIR/$tfile > /dev/null
28415         cat $DIR/$tfile > /dev/null
28416         cat $DIR/$tfile > /dev/null
28417
28418         sleep $((period_second + 3))
28419         echo "Sleep $((period_second + 3)) seconds..."
28420
28421         out=$($LFS heat_get $DIR/$tfile)
28422         $LFS heat_get $DIR/$tfile
28423         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28424         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28425         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28426         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28427
28428         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28429                 4 * $decay_pct) / 100") -eq 1 ] ||
28430                 error "read sample ($readsample1) is wrong"
28431         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28432                 3 * $decay_pct) / 100") -eq 1 ] ||
28433                 error "write sample ($writesample1) is wrong"
28434         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28435                 20 * $decay_pct) / 100") -eq 1 ] ||
28436                 error "read bytes ($readbyte1) is wrong"
28437         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28438                 15 * $decay_pct) / 100") -eq 1 ] ||
28439                 error "write bytes ($writebyte1) is wrong"
28440
28441         echo "Turn off file heat for the file $DIR/$tfile"
28442         $LFS heat_set -o $DIR/$tfile
28443
28444         echo "QQQQ" > $DIR/$tfile
28445         echo "QQQQ" > $DIR/$tfile
28446         echo "QQQQ" > $DIR/$tfile
28447         cat $DIR/$tfile > /dev/null
28448         cat $DIR/$tfile > /dev/null
28449         cat $DIR/$tfile > /dev/null
28450         cat $DIR/$tfile > /dev/null
28451
28452         out=$($LFS heat_get $DIR/$tfile)
28453         $LFS heat_get $DIR/$tfile
28454         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28455         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28456         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28457         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28458
28459         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28460         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28461         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28462         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28463
28464         echo "Trun on file heat for the file $DIR/$tfile"
28465         $LFS heat_set -O $DIR/$tfile
28466
28467         echo "QQQQ" > $DIR/$tfile
28468         echo "QQQQ" > $DIR/$tfile
28469         echo "QQQQ" > $DIR/$tfile
28470         cat $DIR/$tfile > /dev/null
28471         cat $DIR/$tfile > /dev/null
28472         cat $DIR/$tfile > /dev/null
28473         cat $DIR/$tfile > /dev/null
28474
28475         out=$($LFS heat_get $DIR/$tfile)
28476         $LFS heat_get $DIR/$tfile
28477         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28478         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28479         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28480         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28481
28482         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28483         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28484         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28485         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28486
28487         $LFS heat_set -c $DIR/$tfile
28488         $LCTL set_param -n llite.*.file_heat=0
28489         echo "Turn off file heat support for the Lustre filesystem"
28490
28491         echo "QQQQ" > $DIR/$tfile
28492         echo "QQQQ" > $DIR/$tfile
28493         echo "QQQQ" > $DIR/$tfile
28494         cat $DIR/$tfile > /dev/null
28495         cat $DIR/$tfile > /dev/null
28496         cat $DIR/$tfile > /dev/null
28497         cat $DIR/$tfile > /dev/null
28498
28499         out=$($LFS heat_get $DIR/$tfile)
28500         $LFS heat_get $DIR/$tfile
28501         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28502         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28503         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28504         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28505
28506         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28507         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28508         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28509         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28510
28511         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28512         rm -f $DIR/$tfile
28513 }
28514 run_test 813 "File heat verfication"
28515
28516 test_814()
28517 {
28518         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28519         echo -n y >> $DIR/$tfile
28520         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28521         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28522 }
28523 run_test 814 "sparse cp works as expected (LU-12361)"
28524
28525 test_815()
28526 {
28527         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28528         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28529 }
28530 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28531
28532 test_816() {
28533         local ost1_imp=$(get_osc_import_name client ost1)
28534         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28535                          cut -d'.' -f2)
28536
28537         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28538         # ensure ost1 is connected
28539
28540         stat $DIR/$tfile >/dev/null || error "can't stat"
28541         wait_osc_import_state client ost1 FULL
28542         # no locks, no reqs to let the connection idle
28543         cancel_lru_locks osc
28544         lru_resize_disable osc
28545         local before
28546         local now
28547         before=$($LCTL get_param -n \
28548                  ldlm.namespaces.$imp_name.lru_size)
28549
28550         wait_osc_import_state client ost1 IDLE
28551         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28552         now=$($LCTL get_param -n \
28553               ldlm.namespaces.$imp_name.lru_size)
28554         [ $before == $now ] || error "lru_size changed $before != $now"
28555 }
28556 run_test 816 "do not reset lru_resize on idle reconnect"
28557
28558 cleanup_817() {
28559         umount $tmpdir
28560         exportfs -u localhost:$DIR/nfsexp
28561         rm -rf $DIR/nfsexp
28562 }
28563
28564 test_817() {
28565         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28566
28567         mkdir -p $DIR/nfsexp
28568         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28569                 error "failed to export nfs"
28570
28571         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28572         stack_trap cleanup_817 EXIT
28573
28574         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28575                 error "failed to mount nfs to $tmpdir"
28576
28577         cp /bin/true $tmpdir
28578         $DIR/nfsexp/true || error "failed to execute 'true' command"
28579 }
28580 run_test 817 "nfsd won't cache write lock for exec file"
28581
28582 test_818() {
28583         test_mkdir -i0 -c1 $DIR/$tdir
28584         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28585         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28586         stop $SINGLEMDS
28587
28588         # restore osp-syn threads
28589         stack_trap "fail $SINGLEMDS"
28590
28591         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28592         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28593         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28594                 error "start $SINGLEMDS failed"
28595         rm -rf $DIR/$tdir
28596
28597         local testid=$(echo $TESTNAME | tr '_' ' ')
28598
28599         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28600                 grep "run LFSCK" || error "run LFSCK is not suggested"
28601 }
28602 run_test 818 "unlink with failed llog"
28603
28604 test_819a() {
28605         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28606         cancel_lru_locks osc
28607         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28608         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28609         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28610         rm -f $TDIR/$tfile
28611 }
28612 run_test 819a "too big niobuf in read"
28613
28614 test_819b() {
28615         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28616         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28618         cancel_lru_locks osc
28619         sleep 1
28620         rm -f $TDIR/$tfile
28621 }
28622 run_test 819b "too big niobuf in write"
28623
28624
28625 function test_820_start_ost() {
28626         sleep 5
28627
28628         for num in $(seq $OSTCOUNT); do
28629                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28630         done
28631 }
28632
28633 test_820() {
28634         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28635
28636         mkdir $DIR/$tdir
28637         umount_client $MOUNT || error "umount failed"
28638         for num in $(seq $OSTCOUNT); do
28639                 stop ost$num
28640         done
28641
28642         # mount client with no active OSTs
28643         # so that the client can't initialize max LOV EA size
28644         # from OSC notifications
28645         mount_client $MOUNT || error "mount failed"
28646         # delay OST starting to keep this 0 max EA size for a while
28647         test_820_start_ost &
28648
28649         # create a directory on MDS2
28650         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28651                 error "Failed to create directory"
28652         # open intent should update default EA size
28653         # see mdc_update_max_ea_from_body()
28654         # notice this is the very first RPC to MDS2
28655         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28656         ret=$?
28657         echo $out
28658         # With SSK, this situation can lead to -EPERM being returned.
28659         # In that case, simply retry.
28660         if [ $ret -ne 0 ] && $SHARED_KEY; then
28661                 if echo "$out" | grep -q "not permitted"; then
28662                         cp /etc/services $DIR/$tdir/mds2
28663                         ret=$?
28664                 fi
28665         fi
28666         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28667 }
28668 run_test 820 "update max EA from open intent"
28669
28670 test_823() {
28671         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28672         local OST_MAX_PRECREATE=20000
28673
28674         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28675                 skip "Need MDS version at least 2.14.56"
28676
28677         save_lustre_params mds1 \
28678                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28679         do_facet $SINGLEMDS "$LCTL set_param -n \
28680                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28681         do_facet $SINGLEMDS "$LCTL set_param -n \
28682                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28683
28684         stack_trap "restore_lustre_params < $p; rm $p"
28685
28686         do_facet $SINGLEMDS "$LCTL set_param -n \
28687                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28688
28689         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28690                       osp.$FSNAME-OST0000*MDT0000.create_count")
28691         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28692                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28693         local expect_count=$(((($max/2)/256) * 256))
28694
28695         log "setting create_count to 100200:"
28696         log " -result- count: $count with max: $max, expecting: $expect_count"
28697
28698         [[ $count -eq expect_count ]] ||
28699                 error "Create count not set to max precreate."
28700 }
28701 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28702
28703 test_831() {
28704         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28705                 skip "Need MDS version 2.14.56"
28706
28707         local sync_changes=$(do_facet $SINGLEMDS \
28708                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28709
28710         [ "$sync_changes" -gt 100 ] &&
28711                 skip "Sync changes $sync_changes > 100 already"
28712
28713         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28714
28715         $LFS mkdir -i 0 $DIR/$tdir
28716         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28717
28718         save_lustre_params mds1 \
28719                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28720         save_lustre_params mds1 \
28721                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28722
28723         do_facet mds1 "$LCTL set_param -n \
28724                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28725                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28726         stack_trap "restore_lustre_params < $p" EXIT
28727
28728         createmany -o $DIR/$tdir/f- 1000
28729         unlinkmany $DIR/$tdir/f- 1000 &
28730         local UNLINK_PID=$!
28731
28732         while sleep 1; do
28733                 sync_changes=$(do_facet mds1 \
28734                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28735                 # the check in the code is racy, fail the test
28736                 # if the value above the limit by 10.
28737                 [ $sync_changes -gt 110 ] && {
28738                         kill -2 $UNLINK_PID
28739                         wait
28740                         error "osp changes throttling failed, $sync_changes>110"
28741                 }
28742                 kill -0 $UNLINK_PID 2> /dev/null || break
28743         done
28744         wait
28745 }
28746 run_test 831 "throttling unlink/setattr queuing on OSP"
28747
28748 #
28749 # tests that do cleanup/setup should be run at the end
28750 #
28751
28752 test_900() {
28753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28754         local ls
28755
28756         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28757         $LCTL set_param fail_loc=0x903
28758
28759         cancel_lru_locks MGC
28760
28761         FAIL_ON_ERROR=true cleanup
28762         FAIL_ON_ERROR=true setup
28763 }
28764 run_test 900 "umount should not race with any mgc requeue thread"
28765
28766 # LUS-6253/LU-11185
28767 test_901() {
28768         local old
28769         local count
28770         local oldc
28771         local newc
28772         local olds
28773         local news
28774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28775
28776         # some get_param have a bug to handle dot in param name
28777         cancel_lru_locks MGC
28778         old=$(mount -t lustre | wc -l)
28779         # 1 config+sptlrpc
28780         # 2 params
28781         # 3 nodemap
28782         # 4 IR
28783         old=$((old * 4))
28784         oldc=0
28785         count=0
28786         while [ $old -ne $oldc ]; do
28787                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28788                 sleep 1
28789                 ((count++))
28790                 if [ $count -ge $TIMEOUT ]; then
28791                         error "too large timeout"
28792                 fi
28793         done
28794         umount_client $MOUNT || error "umount failed"
28795         mount_client $MOUNT || error "mount failed"
28796         cancel_lru_locks MGC
28797         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28798
28799         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28800
28801         return 0
28802 }
28803 run_test 901 "don't leak a mgc lock on client umount"
28804
28805 # LU-13377
28806 test_902() {
28807         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28808                 skip "client does not have LU-13377 fix"
28809         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28810         $LCTL set_param fail_loc=0x1415
28811         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28812         cancel_lru_locks osc
28813         rm -f $DIR/$tfile
28814 }
28815 run_test 902 "test short write doesn't hang lustre"
28816
28817 # LU-14711
28818 test_903() {
28819         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28820         echo "blah" > $DIR/${tfile}-2
28821         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28822         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28823         $LCTL set_param fail_loc=0x417 fail_val=20
28824
28825         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28826         sleep 1 # To start the destroy
28827         wait_destroy_complete 150 || error "Destroy taking too long"
28828         cat $DIR/$tfile > /dev/null || error "Evicted"
28829 }
28830 run_test 903 "Test long page discard does not cause evictions"
28831
28832 test_904() {
28833         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28834         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28835                 grep -q project || skip "skip project quota not supported"
28836
28837         local testfile="$DIR/$tdir/$tfile"
28838         local xattr="trusted.projid"
28839         local projid
28840         local mdts=$(comma_list $(mdts_nodes))
28841         local saved=$(do_facet mds1 $LCTL get_param -n \
28842                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28843
28844         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28845         stack_trap "do_nodes $mdts $LCTL set_param \
28846                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28847
28848         mkdir -p $DIR/$tdir
28849         touch $testfile
28850         #hide projid xattr on server
28851         $LFS project -p 1 $testfile ||
28852                 error "set $testfile project id failed"
28853         getfattr -m - $testfile | grep $xattr &&
28854                 error "do not show trusted.projid when disabled on server"
28855         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28856         #should be hidden when projid is 0
28857         $LFS project -p 0 $testfile ||
28858                 error "set $testfile project id failed"
28859         getfattr -m - $testfile | grep $xattr &&
28860                 error "do not show trusted.projid with project ID 0"
28861
28862         #still can getxattr explicitly
28863         projid=$(getfattr -n $xattr $testfile |
28864                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28865         [ $projid == "0" ] ||
28866                 error "projid expected 0 not $projid"
28867
28868         #set the projid via setxattr
28869         setfattr -n $xattr -v "1000" $testfile ||
28870                 error "setattr failed with $?"
28871         projid=($($LFS project $testfile))
28872         [ ${projid[0]} == "1000" ] ||
28873                 error "projid expected 1000 not $projid"
28874
28875         #check the new projid via getxattr
28876         $LFS project -p 1001 $testfile ||
28877                 error "set $testfile project id failed"
28878         getfattr -m - $testfile | grep $xattr ||
28879                 error "should show trusted.projid when project ID != 0"
28880         projid=$(getfattr -n $xattr $testfile |
28881                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28882         [ $projid == "1001" ] ||
28883                 error "projid expected 1001 not $projid"
28884
28885         #try to set invalid projid
28886         setfattr -n $xattr -v "4294967295" $testfile &&
28887                 error "set invalid projid should fail"
28888
28889         #remove the xattr means setting projid to 0
28890         setfattr -x $xattr $testfile ||
28891                 error "setfattr failed with $?"
28892         projid=($($LFS project $testfile))
28893         [ ${projid[0]} == "0" ] ||
28894                 error "projid expected 0 not $projid"
28895
28896         #should be hidden when parent has inherit flag and same projid
28897         $LFS project -srp 1002 $DIR/$tdir ||
28898                 error "set $tdir project id failed"
28899         getfattr -m - $testfile | grep $xattr &&
28900                 error "do not show trusted.projid with inherit flag"
28901
28902         #still can getxattr explicitly
28903         projid=$(getfattr -n $xattr $testfile |
28904                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28905         [ $projid == "1002" ] ||
28906                 error "projid expected 1002 not $projid"
28907 }
28908 run_test 904 "virtual project ID xattr"
28909
28910 # LU-8582
28911 test_905() {
28912         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28913                 skip "lustre < 2.8.54 does not support ladvise"
28914
28915         remote_ost_nodsh && skip "remote OST with nodsh"
28916         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28917
28918         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28919
28920         #define OBD_FAIL_OST_OPCODE 0x253
28921         # OST_LADVISE = 21
28922         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28923         $LFS ladvise -a willread $DIR/$tfile &&
28924                 error "unexpected success of ladvise with fault injection"
28925         $LFS ladvise -a willread $DIR/$tfile |&
28926                 grep -q "Operation not supported"
28927         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28928 }
28929 run_test 905 "bad or new opcode should not stuck client"
28930
28931 test_906() {
28932         grep -q io_uring_setup /proc/kallsyms ||
28933                 skip "Client OS does not support io_uring I/O engine"
28934         io_uring_probe || skip "kernel does not support io_uring fully"
28935         which fio || skip_env "no fio installed"
28936         fio --enghelp | grep -q io_uring ||
28937                 skip_env "fio does not support io_uring I/O engine"
28938
28939         local file=$DIR/$tfile
28940         local ioengine="io_uring"
28941         local numjobs=2
28942         local size=50M
28943
28944         fio --name=seqwrite --ioengine=$ioengine        \
28945                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28946                 --iodepth=64 --size=$size --filename=$file --rw=write ||
28947                 error "fio seqwrite $file failed"
28948
28949         fio --name=seqread --ioengine=$ioengine \
28950                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28951                 --iodepth=64 --size=$size --filename=$file --rw=read ||
28952                 error "fio seqread $file failed"
28953
28954         rm -f $file || error "rm -f $file failed"
28955 }
28956 run_test 906 "Simple test for io_uring I/O engine via fio"
28957
28958 complete $SECONDS
28959 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28960 check_and_cleanup_lustre
28961 if [ "$I_MOUNTED" != "yes" ]; then
28962         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28963 fi
28964 exit_status