Whamcloud - gitweb
25762f10e593779f0b9a15fcff7081ffc945b285
[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 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
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27d() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1716                 error "setstripe failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719 }
1720 run_test 27d "create file with default settings"
1721
1722 test_27e() {
1723         # LU-5839 adds check for existed layout before setting it
1724         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1725                 skip "Need MDS version at least 2.7.56"
1726
1727         test_mkdir $DIR/$tdir
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1729         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1730         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1731 }
1732 run_test 27e "setstripe existing file (should return error)"
1733
1734 test_27f() {
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1737                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1738         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1739                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1741         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1742 }
1743 run_test 27f "setstripe with bad stripe size (should return error)"
1744
1745 test_27g() {
1746         test_mkdir $DIR/$tdir
1747         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1748         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1749                 error "$DIR/$tdir/$tfile has object"
1750 }
1751 run_test 27g "$LFS getstripe with no objects"
1752
1753 test_27ga() {
1754         test_mkdir $DIR/$tdir
1755         touch $DIR/$tdir/$tfile || error "touch failed"
1756         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1757         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1758         local rc=$?
1759         (( rc == 2 )) || error "getstripe did not return ENOENT"
1760 }
1761 run_test 27ga "$LFS getstripe with missing file (should return error)"
1762
1763 test_27i() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1767                 error "missing objects"
1768 }
1769 run_test 27i "$LFS getstripe with some objects"
1770
1771 test_27j() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1774                 error "setstripe failed" || true
1775 }
1776 run_test 27j "setstripe with bad stripe offset (should return error)"
1777
1778 test_27k() { # bug 2844
1779         test_mkdir $DIR/$tdir
1780         local file=$DIR/$tdir/$tfile
1781         local ll_max_blksize=$((4 * 1024 * 1024))
1782         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1783         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1784         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1785         dd if=/dev/zero of=$file bs=4k count=1
1786         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1787         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1788 }
1789 run_test 27k "limit i_blksize for broken user apps"
1790
1791 test_27l() {
1792         mcreate $DIR/$tfile || error "creating file"
1793         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1794                 error "setstripe should have failed" || true
1795 }
1796 run_test 27l "check setstripe permissions (should return error)"
1797
1798 test_27m() {
1799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1800
1801         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1802                 skip_env "multiple clients -- skipping"
1803
1804         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1805                    head -n1)
1806         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1807                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1808         fi
1809         stack_trap simple_cleanup_common
1810         test_mkdir $DIR/$tdir
1811         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1813                 error "dd should fill OST0"
1814         i=2
1815         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1816                 i=$((i + 1))
1817                 [ $i -gt 256 ] && break
1818         done
1819         i=$((i + 1))
1820         touch $DIR/$tdir/$tfile.$i
1821         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1822             awk '{print $1}'| grep -w "0") ] &&
1823                 error "OST0 was full but new created file still use it"
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it" || true
1829 }
1830 run_test 27m "create file while OST0 was full"
1831
1832 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1833 # if the OST isn't full anymore.
1834 reset_enospc() {
1835         local ostidx=${1:-""}
1836         local delay
1837         local ready
1838         local get_prealloc
1839
1840         local list=$(comma_list $(osts_nodes))
1841         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1842
1843         do_nodes $list lctl set_param fail_loc=0
1844         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1845         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1846                 awk '{print $1 * 2;exit;}')
1847         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1848                         grep -v \"^0$\""
1849         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1850 }
1851
1852 test_27n() {
1853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1855         remote_mds_nodsh && skip "remote MDS with nodsh"
1856         remote_ost_nodsh && skip "remote OST with nodsh"
1857
1858         reset_enospc
1859         rm -f $DIR/$tdir/$tfile
1860         exhaust_precreations 0 0x80000215
1861         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1862         touch $DIR/$tdir/$tfile || error "touch failed"
1863         $LFS getstripe $DIR/$tdir/$tfile
1864         reset_enospc
1865 }
1866 run_test 27n "create file with some full OSTs"
1867
1868 test_27o() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876         exhaust_all_precreations 0x215
1877
1878         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1879
1880         reset_enospc
1881         rm -rf $DIR/$tdir/*
1882 }
1883 run_test 27o "create file with all full OSTs (should error)"
1884
1885 function create_and_checktime() {
1886         local fname=$1
1887         local loops=$2
1888         local i
1889
1890         for ((i=0; i < $loops; i++)); do
1891                 local start=$SECONDS
1892                 multiop $fname-$i Oc
1893                 ((SECONDS-start < TIMEOUT)) ||
1894                         error "creation took " $((SECONDS-$start)) && return 1
1895         done
1896 }
1897
1898 test_27oo() {
1899         local mdts=$(comma_list $(mdts_nodes))
1900
1901         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1902                 skip "Need MDS version at least 2.13.57"
1903
1904         local f0=$DIR/${tfile}-0
1905         local f1=$DIR/${tfile}-1
1906
1907         wait_delete_completed
1908
1909         # refill precreated objects
1910         $LFS setstripe -i0 -c1 $f0
1911
1912         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1913         # force QoS allocation policy
1914         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1915         stack_trap "do_nodes $mdts $LCTL set_param \
1916                 lov.*.qos_threshold_rr=$saved" EXIT
1917         sleep_maxage
1918
1919         # one OST is unavailable, but still have few objects preallocated
1920         stop ost1
1921         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1922                 rm -rf $f1 $DIR/$tdir*" EXIT
1923
1924         for ((i=0; i < 7; i++)); do
1925                 mkdir $DIR/$tdir$i || error "can't create dir"
1926                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1927                         error "can't set striping"
1928         done
1929         for ((i=0; i < 7; i++)); do
1930                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1931         done
1932         wait
1933 }
1934 run_test 27oo "don't let few threads to reserve too many objects"
1935
1936 test_27p() {
1937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1939         remote_mds_nodsh && skip "remote MDS with nodsh"
1940         remote_ost_nodsh && skip "remote OST with nodsh"
1941
1942         reset_enospc
1943         rm -f $DIR/$tdir/$tfile
1944         test_mkdir $DIR/$tdir
1945
1946         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1947         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1948         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1949
1950         exhaust_precreations 0 0x80000215
1951         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1952         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1953         $LFS getstripe $DIR/$tdir/$tfile
1954
1955         reset_enospc
1956 }
1957 run_test 27p "append to a truncated file with some full OSTs"
1958
1959 test_27q() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967
1968         mkdir_on_mdt0 $DIR/$tdir
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1971                 error "truncate $DIR/$tdir/$tfile failed"
1972         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1973
1974         exhaust_all_precreations 0x215
1975
1976         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1978
1979         reset_enospc
1980 }
1981 run_test 27q "append to truncated file with all OSTs full (should error)"
1982
1983 test_27r() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         exhaust_precreations 0 0x80000215
1992
1993         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1994
1995         reset_enospc
1996 }
1997 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1998
1999 test_27s() { # bug 10725
2000         test_mkdir $DIR/$tdir
2001         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2002         local stripe_count=0
2003         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2004         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2005                 error "stripe width >= 2^32 succeeded" || true
2006
2007 }
2008 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2009
2010 test_27t() { # bug 10864
2011         WDIR=$(pwd)
2012         WLFS=$(which lfs)
2013         cd $DIR
2014         touch $tfile
2015         $WLFS getstripe $tfile
2016         cd $WDIR
2017 }
2018 run_test 27t "check that utils parse path correctly"
2019
2020 test_27u() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023
2024         local index
2025         local list=$(comma_list $(mdts_nodes))
2026
2027 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2028         do_nodes $list $LCTL set_param fail_loc=0x139
2029         test_mkdir -p $DIR/$tdir
2030         stack_trap "simple_cleanup_common 1000"
2031         createmany -o $DIR/$tdir/$tfile 1000
2032         do_nodes $list $LCTL set_param fail_loc=0
2033
2034         TLOG=$TMP/$tfile.getstripe
2035         $LFS getstripe $DIR/$tdir > $TLOG
2036         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2037         [[ $OBJS -gt 0 ]] &&
2038                 error "$OBJS objects created on OST-0. See $TLOG" ||
2039                 rm -f $TLOG
2040 }
2041 run_test 27u "skip object creation on OSC w/o objects"
2042
2043 test_27v() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2046         remote_mds_nodsh && skip "remote MDS with nodsh"
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048
2049         exhaust_all_precreations 0x215
2050         reset_enospc
2051
2052         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2053
2054         touch $DIR/$tdir/$tfile
2055         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2056         # all except ost1
2057         for (( i=1; i < OSTCOUNT; i++ )); do
2058                 do_facet ost$i lctl set_param fail_loc=0x705
2059         done
2060         local START=`date +%s`
2061         createmany -o $DIR/$tdir/$tfile 32
2062
2063         local FINISH=`date +%s`
2064         local TIMEOUT=`lctl get_param -n timeout`
2065         local PROCESS=$((FINISH - START))
2066         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2067                error "$FINISH - $START >= $TIMEOUT / 2"
2068         sleep $((TIMEOUT / 2 - PROCESS))
2069         reset_enospc
2070 }
2071 run_test 27v "skip object creation on slow OST"
2072
2073 test_27w() { # bug 10997
2074         test_mkdir $DIR/$tdir
2075         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2076         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2077                 error "stripe size $size != 65536" || true
2078         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2079                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2080 }
2081 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2082
2083 test_27wa() {
2084         [[ $OSTCOUNT -lt 2 ]] &&
2085                 skip_env "skipping multiple stripe count/offset test"
2086
2087         test_mkdir $DIR/$tdir
2088         for i in $(seq 1 $OSTCOUNT); do
2089                 offset=$((i - 1))
2090                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2091                         error "setstripe -c $i -i $offset failed"
2092                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2093                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2094                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2095                 [ $index -ne $offset ] &&
2096                         error "stripe offset $index != $offset" || true
2097         done
2098 }
2099 run_test 27wa "check $LFS setstripe -c -i options"
2100
2101 test_27x() {
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         OFFSET=$(($OSTCOUNT - 1))
2107         OSTIDX=0
2108         local OST=$(ostname_from_index $OSTIDX)
2109
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2112         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2113         sleep_maxage
2114         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2115         for i in $(seq 0 $OFFSET); do
2116                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2117                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2118                 error "OST0 was degraded but new created file still use it"
2119         done
2120         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2121 }
2122 run_test 27x "create files while OST0 is degraded"
2123
2124 test_27y() {
2125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2126         remote_mds_nodsh && skip "remote MDS with nodsh"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2129
2130         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2131         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2132                 osp.$mdtosc.prealloc_last_id)
2133         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2134                 osp.$mdtosc.prealloc_next_id)
2135         local fcount=$((last_id - next_id))
2136         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2137         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2138
2139         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2140                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2141         local OST_DEACTIVE_IDX=-1
2142         local OSC
2143         local OSTIDX
2144         local OST
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2150                         OST_DEACTIVE_IDX=$OSTIDX
2151                 fi
2152                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2153                         echo $OSC "is Deactivated:"
2154                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2155                 fi
2156         done
2157
2158         OSTIDX=$(index_from_ostuuid $OST)
2159         test_mkdir $DIR/$tdir
2160         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2161
2162         for OSC in $MDS_OSCS; do
2163                 OST=$(osc_to_ost $OSC)
2164                 OSTIDX=$(index_from_ostuuid $OST)
2165                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2166                         echo $OST "is degraded:"
2167                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2168                                                 obdfilter.$OST.degraded=1
2169                 fi
2170         done
2171
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $fcount
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is recovered from degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=0
2182                 else
2183                         do_facet $SINGLEMDS lctl --device %$OSC activate
2184                 fi
2185         done
2186
2187         # all osp devices get activated, hence -1 stripe count restored
2188         local stripe_count=0
2189
2190         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2191         # devices get activated.
2192         sleep_maxage
2193         $LFS setstripe -c -1 $DIR/$tfile
2194         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2195         rm -f $DIR/$tfile
2196         [ $stripe_count -ne $OSTCOUNT ] &&
2197                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2198         return 0
2199 }
2200 run_test 27y "create files while OST0 is degraded and the rest inactive"
2201
2202 check_seq_oid()
2203 {
2204         log "check file $1"
2205
2206         lmm_count=$($LFS getstripe -c $1)
2207         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2208         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2209
2210         local old_ifs="$IFS"
2211         IFS=$'[:]'
2212         fid=($($LFS path2fid $1))
2213         IFS="$old_ifs"
2214
2215         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2216         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2217
2218         # compare lmm_seq and lu_fid->f_seq
2219         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2220         # compare lmm_object_id and lu_fid->oid
2221         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2222
2223         # check the trusted.fid attribute of the OST objects of the file
2224         local have_obdidx=false
2225         local stripe_nr=0
2226         $LFS getstripe $1 | while read obdidx oid hex seq; do
2227                 # skip lines up to and including "obdidx"
2228                 [ -z "$obdidx" ] && break
2229                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2230                 $have_obdidx || continue
2231
2232                 local ost=$((obdidx + 1))
2233                 local dev=$(ostdevname $ost)
2234                 local oid_hex
2235
2236                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2237
2238                 seq=$(echo $seq | sed -e "s/^0x//g")
2239                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2240                         oid_hex=$(echo $oid)
2241                 else
2242                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2243                 fi
2244                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2245
2246                 local ff=""
2247                 #
2248                 # Don't unmount/remount the OSTs if we don't need to do that.
2249                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2250                 # update too, until that use mount/ll_decode_filter_fid/mount.
2251                 # Re-enable when debugfs will understand new filter_fid.
2252                 #
2253                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2254                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2255                                 $dev 2>/dev/null" | grep "parent=")
2256                 fi
2257                 if [ -z "$ff" ]; then
2258                         stop ost$ost
2259                         mount_fstype ost$ost
2260                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2261                                 $(facet_mntpt ost$ost)/$obj_file)
2262                         unmount_fstype ost$ost
2263                         start ost$ost $dev $OST_MOUNT_OPTS
2264                         clients_up
2265                 fi
2266
2267                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2268
2269                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2270
2271                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2272                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2273                 #
2274                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2275                 #       stripe_size=1048576 component_id=1 component_start=0 \
2276                 #       component_end=33554432
2277                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2278                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2279                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2280                 local ff_pstripe
2281                 if grep -q 'stripe=' <<<$ff; then
2282                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2283                 else
2284                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2285                         # into f_ver in this case.  See comment on ff_parent.
2286                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2287                 fi
2288
2289                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2290                 [ $ff_pseq = $lmm_seq ] ||
2291                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2292                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2293                 [ $ff_poid = $lmm_oid ] ||
2294                         error "FF parent OID $ff_poid != $lmm_oid"
2295                 (($ff_pstripe == $stripe_nr)) ||
2296                         error "FF stripe $ff_pstripe != $stripe_nr"
2297
2298                 stripe_nr=$((stripe_nr + 1))
2299                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2300                         continue
2301                 if grep -q 'stripe_count=' <<<$ff; then
2302                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2303                                             -e 's/ .*//' <<<$ff)
2304                         [ $lmm_count = $ff_scnt ] ||
2305                                 error "FF stripe count $lmm_count != $ff_scnt"
2306                 fi
2307         done
2308 }
2309
2310 test_27z() {
2311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2312         remote_ost_nodsh && skip "remote OST with nodsh"
2313
2314         test_mkdir $DIR/$tdir
2315         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2316                 { error "setstripe -c -1 failed"; return 1; }
2317         # We need to send a write to every object to get parent FID info set.
2318         # This _should_ also work for setattr, but does not currently.
2319         # touch $DIR/$tdir/$tfile-1 ||
2320         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2321                 { error "dd $tfile-1 failed"; return 2; }
2322         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2323                 { error "setstripe -c -1 failed"; return 3; }
2324         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2325                 { error "dd $tfile-2 failed"; return 4; }
2326
2327         # make sure write RPCs have been sent to OSTs
2328         sync; sleep 5; sync
2329
2330         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2331         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2332 }
2333 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2334
2335 test_27A() { # b=19102
2336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2337
2338         save_layout_restore_at_exit $MOUNT
2339         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2340         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2341                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2342         local default_size=$($LFS getstripe -S $MOUNT)
2343         local default_offset=$($LFS getstripe -i $MOUNT)
2344         local dsize=$(do_facet $SINGLEMDS \
2345                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2346         [ $default_size -eq $dsize ] ||
2347                 error "stripe size $default_size != $dsize"
2348         [ $default_offset -eq -1 ] ||
2349                 error "stripe offset $default_offset != -1"
2350 }
2351 run_test 27A "check filesystem-wide default LOV EA values"
2352
2353 test_27B() { # LU-2523
2354         test_mkdir $DIR/$tdir
2355         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2356         touch $DIR/$tdir/f0
2357         # open f1 with O_LOV_DELAY_CREATE
2358         # rename f0 onto f1
2359         # call setstripe ioctl on open file descriptor for f1
2360         # close
2361         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2362                 $DIR/$tdir/f0
2363
2364         rm -f $DIR/$tdir/f1
2365         # open f1 with O_LOV_DELAY_CREATE
2366         # unlink f1
2367         # call setstripe ioctl on open file descriptor for f1
2368         # close
2369         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2370
2371         # Allow multiop to fail in imitation of NFS's busted semantics.
2372         true
2373 }
2374 run_test 27B "call setstripe on open unlinked file/rename victim"
2375
2376 # 27C family tests full striping and overstriping
2377 test_27Ca() { #LU-2871
2378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2379
2380         declare -a ost_idx
2381         local index
2382         local found
2383         local i
2384         local j
2385
2386         test_mkdir $DIR/$tdir
2387         cd $DIR/$tdir
2388         for i in $(seq 0 $((OSTCOUNT - 1))); do
2389                 # set stripe across all OSTs starting from OST$i
2390                 $LFS setstripe -i $i -c -1 $tfile$i
2391                 # get striping information
2392                 ost_idx=($($LFS getstripe $tfile$i |
2393                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2394                 echo "OST Index: ${ost_idx[*]}"
2395
2396                 # check the layout
2397                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2398                         error "${#ost_idx[@]} != $OSTCOUNT"
2399
2400                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2401                         found=0
2402                         for j in "${ost_idx[@]}"; do
2403                                 if [ $index -eq $j ]; then
2404                                         found=1
2405                                         break
2406                                 fi
2407                         done
2408                         [ $found = 1 ] ||
2409                                 error "Can not find $index in ${ost_idx[*]}"
2410                 done
2411         done
2412 }
2413 run_test 27Ca "check full striping across all OSTs"
2414
2415 test_27Cb() {
2416         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2417                 skip "server does not support overstriping"
2418         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2419                 skip_env "too many osts, skipping"
2420
2421         test_mkdir -p $DIR/$tdir
2422         local setcount=$(($OSTCOUNT * 2))
2423         [ $setcount -lt 160 ] || large_xattr_enabled ||
2424                 skip_env "ea_inode feature disabled"
2425
2426         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2427                 error "setstripe failed"
2428
2429         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2430         [ $count -eq $setcount ] ||
2431                 error "stripe count $count, should be $setcount"
2432
2433         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2434                 error "overstriped should be set in pattern"
2435
2436         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2437                 error "dd failed"
2438 }
2439 run_test 27Cb "more stripes than OSTs with -C"
2440
2441 test_27Cc() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2445
2446         test_mkdir -p $DIR/$tdir
2447         local setcount=$(($OSTCOUNT - 1))
2448
2449         [ $setcount -lt 160 ] || large_xattr_enabled ||
2450                 skip_env "ea_inode feature disabled"
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2460                 error "overstriped should not be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464 }
2465 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2466
2467 test_27Cd() {
2468         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2469                 skip "server does not support overstriping"
2470         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2471         large_xattr_enabled || skip_env "ea_inode feature disabled"
2472
2473         test_mkdir -p $DIR/$tdir
2474         local setcount=$LOV_MAX_STRIPE_COUNT
2475
2476         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2477                 error "setstripe failed"
2478
2479         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2480         [ $count -eq $setcount ] ||
2481                 error "stripe count $count, should be $setcount"
2482
2483         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2484                 error "overstriped should be set in pattern"
2485
2486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2487                 error "dd failed"
2488
2489         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2490 }
2491 run_test 27Cd "test maximum stripe count"
2492
2493 test_27Ce() {
2494         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2495                 skip "server does not support overstriping"
2496         test_mkdir -p $DIR/$tdir
2497
2498         pool_add $TESTNAME || error "Pool creation failed"
2499         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2500
2501         local setcount=8
2502
2503         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2504                 error "setstripe failed"
2505
2506         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2507         [ $count -eq $setcount ] ||
2508                 error "stripe count $count, should be $setcount"
2509
2510         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2511                 error "overstriped should be set in pattern"
2512
2513         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2514                 error "dd failed"
2515
2516         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2517 }
2518 run_test 27Ce "test pool with overstriping"
2519
2520 test_27Cf() {
2521         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2522                 skip "server does not support overstriping"
2523         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2524                 skip_env "too many osts, skipping"
2525
2526         test_mkdir -p $DIR/$tdir
2527
2528         local setcount=$(($OSTCOUNT * 2))
2529         [ $setcount -lt 160 ] || large_xattr_enabled ||
2530                 skip_env "ea_inode feature disabled"
2531
2532         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2533                 error "setstripe failed"
2534
2535         echo 1 > $DIR/$tdir/$tfile
2536
2537         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2538         [ $count -eq $setcount ] ||
2539                 error "stripe count $count, should be $setcount"
2540
2541         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2542                 error "overstriped should be set in pattern"
2543
2544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2545                 error "dd failed"
2546
2547         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2548 }
2549 run_test 27Cf "test default inheritance with overstriping"
2550
2551 test_27D() {
2552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2553         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2554         remote_mds_nodsh && skip "remote MDS with nodsh"
2555
2556         local POOL=${POOL:-testpool}
2557         local first_ost=0
2558         local last_ost=$(($OSTCOUNT - 1))
2559         local ost_step=1
2560         local ost_list=$(seq $first_ost $ost_step $last_ost)
2561         local ost_range="$first_ost $last_ost $ost_step"
2562
2563         test_mkdir $DIR/$tdir
2564         pool_add $POOL || error "pool_add failed"
2565         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2566
2567         local skip27D
2568         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2569                 skip27D+="-s 29"
2570         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2571                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2572                         skip27D+=" -s 30,31"
2573         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2574           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2575                 skip27D+=" -s 32,33"
2576         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2577                 skip27D+=" -s 34"
2578         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2579                 error "llapi_layout_test failed"
2580
2581         destroy_test_pools || error "destroy test pools failed"
2582 }
2583 run_test 27D "validate llapi_layout API"
2584
2585 # Verify that default_easize is increased from its initial value after
2586 # accessing a widely striped file.
2587 test_27E() {
2588         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2589         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2590                 skip "client does not have LU-3338 fix"
2591
2592         # 72 bytes is the minimum space required to store striping
2593         # information for a file striped across one OST:
2594         # (sizeof(struct lov_user_md_v3) +
2595         #  sizeof(struct lov_user_ost_data_v1))
2596         local min_easize=72
2597         $LCTL set_param -n llite.*.default_easize $min_easize ||
2598                 error "lctl set_param failed"
2599         local easize=$($LCTL get_param -n llite.*.default_easize)
2600
2601         [ $easize -eq $min_easize ] ||
2602                 error "failed to set default_easize"
2603
2604         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2605                 error "setstripe failed"
2606         # In order to ensure stat() call actually talks to MDS we need to
2607         # do something drastic to this file to shake off all lock, e.g.
2608         # rename it (kills lookup lock forcing cache cleaning)
2609         mv $DIR/$tfile $DIR/${tfile}-1
2610         ls -l $DIR/${tfile}-1
2611         rm $DIR/${tfile}-1
2612
2613         easize=$($LCTL get_param -n llite.*.default_easize)
2614
2615         [ $easize -gt $min_easize ] ||
2616                 error "default_easize not updated"
2617 }
2618 run_test 27E "check that default extended attribute size properly increases"
2619
2620 test_27F() { # LU-5346/LU-7975
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2623         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2624                 skip "Need MDS version at least 2.8.51"
2625         remote_ost_nodsh && skip "remote OST with nodsh"
2626
2627         test_mkdir $DIR/$tdir
2628         rm -f $DIR/$tdir/f0
2629         $LFS setstripe -c 2 $DIR/$tdir
2630
2631         # stop all OSTs to reproduce situation for LU-7975 ticket
2632         for num in $(seq $OSTCOUNT); do
2633                 stop ost$num
2634         done
2635
2636         # open/create f0 with O_LOV_DELAY_CREATE
2637         # truncate f0 to a non-0 size
2638         # close
2639         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2640
2641         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2642         # open/write it again to force delayed layout creation
2643         cat /etc/hosts > $DIR/$tdir/f0 &
2644         catpid=$!
2645
2646         # restart OSTs
2647         for num in $(seq $OSTCOUNT); do
2648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2649                         error "ost$num failed to start"
2650         done
2651
2652         wait $catpid || error "cat failed"
2653
2654         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2655         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2656                 error "wrong stripecount"
2657
2658 }
2659 run_test 27F "Client resend delayed layout creation with non-zero size"
2660
2661 test_27G() { #LU-10629
2662         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2663                 skip "Need MDS version at least 2.11.51"
2664         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2665         remote_mds_nodsh && skip "remote MDS with nodsh"
2666         local POOL=${POOL:-testpool}
2667         local ostrange="0 0 1"
2668
2669         test_mkdir $DIR/$tdir
2670         touch $DIR/$tdir/$tfile.nopool
2671         pool_add $POOL || error "pool_add failed"
2672         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2673         $LFS setstripe -p $POOL $DIR/$tdir
2674
2675         local pool=$($LFS getstripe -p $DIR/$tdir)
2676
2677         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2678         touch $DIR/$tdir/$tfile.default
2679         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2680         $LFS find $DIR/$tdir -type f --pool $POOL
2681         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2682         [[ "$found" == "2" ]] ||
2683                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2684
2685         $LFS setstripe -d $DIR/$tdir
2686
2687         pool=$($LFS getstripe -p -d $DIR/$tdir)
2688
2689         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2690 }
2691 run_test 27G "Clear OST pool from stripe"
2692
2693 test_27H() {
2694         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2695                 skip "Need MDS version newer than 2.11.54"
2696         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2699         touch $DIR/$tdir/$tfile
2700         $LFS getstripe -c $DIR/$tdir/$tfile
2701         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2702                 error "two-stripe file doesn't have two stripes"
2703
2704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2705         $LFS getstripe -y $DIR/$tdir/$tfile
2706         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2707              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2708                 error "expected l_ost_idx: [02]$ not matched"
2709
2710         # make sure ost list has been cleared
2711         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2712         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2713                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2714         touch $DIR/$tdir/f3
2715         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2716 }
2717 run_test 27H "Set specific OSTs stripe"
2718
2719 test_27I() {
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2723                 skip "Need MDS version newer than 2.12.52"
2724         local pool=$TESTNAME
2725         local ostrange="1 1 1"
2726
2727         save_layout_restore_at_exit $MOUNT
2728         $LFS setstripe -c 2 -i 0 $MOUNT
2729         pool_add $pool || error "pool_add failed"
2730         pool_add_targets $pool $ostrange ||
2731                 error "pool_add_targets failed"
2732         test_mkdir $DIR/$tdir
2733         $LFS setstripe -p $pool $DIR/$tdir
2734         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2735         $LFS getstripe $DIR/$tdir/$tfile
2736 }
2737 run_test 27I "check that root dir striping does not break parent dir one"
2738
2739 test_27J() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2741                 skip "Need MDS version newer than 2.12.51"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign file (raw way)
2748         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2749                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2750
2751         ! $LFS setstripe --foreign --flags foo \
2752                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2753                         error "creating $tfile with '--flags foo' should fail"
2754
2755         ! $LFS setstripe --foreign --flags 0xffffffff \
2756                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2757                         error "creating $tfile w/ 0xffffffff flags should fail"
2758
2759         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2760                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2761
2762         # verify foreign file (raw way)
2763         parse_foreign_file -f $DIR/$tdir/$tfile |
2764                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2765                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2766         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2767                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_size: 73" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2771         parse_foreign_file -f $DIR/$tdir/$tfile |
2772                 grep "lov_foreign_type: 1" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_flags: 0x0000DA08" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2777         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_value: 0x" |
2779                 sed -e 's/lov_foreign_value: 0x//')
2780         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2781         [[ $lov = ${lov2// /} ]] ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2783
2784         # create foreign file (lfs + API)
2785         $LFS setstripe --foreign=none --flags 0xda08 \
2786                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: create failed"
2788
2789         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2790                 grep "lfm_magic:.*0x0BD70BD0" ||
2791                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2792         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2793         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2794                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2797         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2798                 grep "lfm_flags:.*0x0000DA08" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2800         $LFS getstripe $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2803
2804         # modify striping should fail
2805         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2806                 error "$DIR/$tdir/$tfile: setstripe should fail"
2807         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2808                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2809
2810         # R/W should fail
2811         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2812         cat $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: read should fail"
2814         cat /etc/passwd > $DIR/$tdir/$tfile &&
2815                 error "$DIR/$tdir/$tfile: write should fail"
2816         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2817                 error "$DIR/$tdir/${tfile}2: write should fail"
2818
2819         # chmod should work
2820         chmod 222 $DIR/$tdir/$tfile ||
2821                 error "$DIR/$tdir/$tfile: chmod failed"
2822         chmod 222 $DIR/$tdir/${tfile}2 ||
2823                 error "$DIR/$tdir/${tfile}2: chmod failed"
2824
2825         # chown should work
2826         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chown failed"
2828         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chown failed"
2830
2831         # rename should work
2832         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2833                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2834         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2835                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2836
2837         #remove foreign file
2838         rm $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2840         rm $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2842 }
2843 run_test 27J "basic ops on file with foreign LOV"
2844
2845 test_27K() {
2846         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2847                 skip "Need MDS version newer than 2.12.49"
2848
2849         test_mkdir $DIR/$tdir
2850         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2851         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2852
2853         # create foreign dir (raw way)
2854         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2855                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2856
2857         ! $LFS setdirstripe --foreign --flags foo \
2858                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2859                         error "creating $tdir with '--flags foo' should fail"
2860
2861         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2862                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2863                         error "creating $tdir w/ 0xffffffff flags should fail"
2864
2865         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2866                 error "create_foreign_dir FAILED"
2867
2868         # verify foreign dir (raw way)
2869         parse_foreign_dir -d $DIR/$tdir/$tdir |
2870                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2871                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2872         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2873                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2874         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2875                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_flags: 55813$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2879         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2880                 grep "lmv_foreign_value: 0x" |
2881                 sed 's/lmv_foreign_value: 0x//')
2882         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2883                 sed 's/ //g')
2884         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2885
2886         # create foreign dir (lfs + API)
2887         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2888                 $DIR/$tdir/${tdir}2 ||
2889                 error "$DIR/$tdir/${tdir}2: create failed"
2890
2891         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2892
2893         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2894                 grep "lfm_magic:.*0x0CD50CD0" ||
2895                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2896         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2897         # - sizeof(lfm_type) - sizeof(lfm_flags)
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2900         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_flags:.*0x0000DA05" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2905         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2908
2909         # file create in dir should fail
2910         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2911         touch $DIR/$tdir/${tdir}2/$tfile &&
2912                 error "$DIR/${tdir}2: file create should fail"
2913
2914         # chmod should work
2915         chmod 777 $DIR/$tdir/$tdir ||
2916                 error "$DIR/$tdir: chmod failed"
2917         chmod 777 $DIR/$tdir/${tdir}2 ||
2918                 error "$DIR/${tdir}2: chmod failed"
2919
2920         # chown should work
2921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chown failed"
2923         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chown failed"
2925
2926         # rename should work
2927         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2928                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2929         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2930                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2931
2932         #remove foreign dir
2933         rmdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2935         rmdir $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2937 }
2938 run_test 27K "basic ops on dir with foreign LMV"
2939
2940 test_27L() {
2941         remote_mds_nodsh && skip "remote MDS with nodsh"
2942
2943         local POOL=${POOL:-$TESTNAME}
2944
2945         pool_add $POOL || error "pool_add failed"
2946
2947         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2948                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2949                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2950 }
2951 run_test 27L "lfs pool_list gives correct pool name"
2952
2953 test_27M() {
2954         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2955                 skip "Need MDS version >= than 2.12.57"
2956         remote_mds_nodsh && skip "remote MDS with nodsh"
2957         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2958
2959         # Set default striping on directory
2960         local setcount=4
2961         local stripe_opt
2962         local mdts=$(comma_list $(mdts_nodes))
2963
2964         # if we run against a 2.12 server which lacks overstring support
2965         # then the connect_flag will not report overstriping, even if client
2966         # is 2.14+
2967         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2968                 stripe_opt="-C $setcount"
2969         elif (( $OSTCOUNT >= $setcount )); then
2970                 stripe_opt="-c $setcount"
2971         else
2972                 skip "server does not support overstriping"
2973         fi
2974
2975         test_mkdir $DIR/$tdir
2976
2977         # Validate existing append_* params and ensure restore
2978         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2979         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2980         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2981
2982         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2983         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2985
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         pool_add $TESTNAME || error "pool creation failed"
3071         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3072         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27T() {
3377         [ $(facet_host client) == $(facet_host ost1) ] &&
3378                 skip "need ost1 and client on different nodes"
3379
3380 #define OBD_FAIL_OSC_NO_GRANT            0x411
3381         $LCTL set_param fail_loc=0x20000411 fail_val=1
3382 #define OBD_FAIL_OST_ENOSPC              0x215
3383         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3385         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3386                 error "multiop failed"
3387 }
3388 run_test 27T "no eio on close on partial write due to enosp"
3389
3390 test_27U() {
3391         local dir=$DIR/$tdir
3392         local file=$dir/$tfile
3393         local append_pool=${TESTNAME}-append
3394         local normal_pool=${TESTNAME}-normal
3395         local pool
3396         local stripe_count
3397         local stripe_count2
3398         local mdts=$(comma_list $(mdts_nodes))
3399
3400         # FIMXE
3401         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3402         #       skip "Need MDS version at least 2.15.42"
3403
3404         # Validate existing append_* params and ensure restore
3405         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3406         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3407         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3408
3409         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3410         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3411         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3412
3413         pool_add $append_pool || error "pool creation failed"
3414         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3415
3416         pool_add $normal_pool || error "pool creation failed"
3417         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3418
3419         test_mkdir $dir
3420         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3421
3422         echo XXX >> $file.1
3423         $LFS getstripe $file.1
3424
3425         pool=$($LFS getstripe -p $file.1)
3426         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3427
3428         stripe_count2=$($LFS getstripe -c $file.1)
3429         ((stripe_count2 == stripe_count)) ||
3430                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3431
3432         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3433
3434         echo XXX >> $file.2
3435         $LFS getstripe $file.2
3436
3437         pool=$($LFS getstripe -p $file.2)
3438         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3439
3440         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3441
3442         echo XXX >> $file.3
3443         $LFS getstripe $file.3
3444
3445         stripe_count2=$($LFS getstripe -c $file.3)
3446         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3447 }
3448 run_test 27U "append pool and stripe count work with composite default layout"
3449
3450 # createtest also checks that device nodes are created and
3451 # then visible correctly (#2091)
3452 test_28() { # bug 2091
3453         test_mkdir $DIR/d28
3454         $CREATETEST $DIR/d28/ct || error "createtest failed"
3455 }
3456 run_test 28 "create/mknod/mkdir with bad file types ============"
3457
3458 test_29() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3462                 disable_opencache
3463                 stack_trap "restore_opencache"
3464         }
3465
3466         sync; sleep 1; sync # flush out any dirty pages from previous tests
3467         cancel_lru_locks
3468         test_mkdir $DIR/d29
3469         touch $DIR/d29/foo
3470         log 'first d29'
3471         ls -l $DIR/d29
3472
3473         declare -i LOCKCOUNTORIG=0
3474         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3475                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3476         done
3477         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3478
3479         declare -i LOCKUNUSEDCOUNTORIG=0
3480         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3481                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3482         done
3483
3484         log 'second d29'
3485         ls -l $DIR/d29
3486         log 'done'
3487
3488         declare -i LOCKCOUNTCURRENT=0
3489         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3490                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3491         done
3492
3493         declare -i LOCKUNUSEDCOUNTCURRENT=0
3494         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3495                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3496         done
3497
3498         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3499                 $LCTL set_param -n ldlm.dump_namespaces ""
3500                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3501                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3502                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3503                 return 2
3504         fi
3505         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3506                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3507                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3508                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3509                 return 3
3510         fi
3511 }
3512 run_test 29 "IT_GETATTR regression  ============================"
3513
3514 test_30a() { # was test_30
3515         cp $(which ls) $DIR || cp /bin/ls $DIR
3516         $DIR/ls / || error "Can't execute binary from lustre"
3517         rm $DIR/ls
3518 }
3519 run_test 30a "execute binary from Lustre (execve) =============="
3520
3521 test_30b() {
3522         cp `which ls` $DIR || cp /bin/ls $DIR
3523         chmod go+rx $DIR/ls
3524         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3525         rm $DIR/ls
3526 }
3527 run_test 30b "execute binary from Lustre as non-root ==========="
3528
3529 test_30c() { # b=22376
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         cp $(which ls) $DIR || cp /bin/ls $DIR
3533         chmod a-rw $DIR/ls
3534         cancel_lru_locks mdc
3535         cancel_lru_locks osc
3536         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3537         rm -f $DIR/ls
3538 }
3539 run_test 30c "execute binary from Lustre without read perms ===="
3540
3541 test_30d() {
3542         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3543
3544         for i in {1..10}; do
3545                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3546                 local PID=$!
3547                 sleep 1
3548                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3549                 wait $PID || error "executing dd from Lustre failed"
3550                 rm -f $DIR/$tfile
3551         done
3552
3553         rm -f $DIR/dd
3554 }
3555 run_test 30d "execute binary from Lustre while clear locks"
3556
3557 test_31a() {
3558         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3559         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3560 }
3561 run_test 31a "open-unlink file =================================="
3562
3563 test_31b() {
3564         touch $DIR/f31 || error "touch $DIR/f31 failed"
3565         ln $DIR/f31 $DIR/f31b || error "ln failed"
3566         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3567         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3568 }
3569 run_test 31b "unlink file with multiple links while open ======="
3570
3571 test_31c() {
3572         touch $DIR/f31 || error "touch $DIR/f31 failed"
3573         ln $DIR/f31 $DIR/f31c || error "ln failed"
3574         multiop_bg_pause $DIR/f31 O_uc ||
3575                 error "multiop_bg_pause for $DIR/f31 failed"
3576         MULTIPID=$!
3577         $MULTIOP $DIR/f31c Ouc
3578         kill -USR1 $MULTIPID
3579         wait $MULTIPID
3580 }
3581 run_test 31c "open-unlink file with multiple links ============="
3582
3583 test_31d() {
3584         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3585         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3586 }
3587 run_test 31d "remove of open directory ========================="
3588
3589 test_31e() { # bug 2904
3590         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3591 }
3592 run_test 31e "remove of open non-empty directory ==============="
3593
3594 test_31f() { # bug 4554
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         set -vx
3598         test_mkdir $DIR/d31f
3599         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3600         cp /etc/hosts $DIR/d31f
3601         ls -l $DIR/d31f
3602         $LFS getstripe $DIR/d31f/hosts
3603         multiop_bg_pause $DIR/d31f D_c || return 1
3604         MULTIPID=$!
3605
3606         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3607         test_mkdir $DIR/d31f
3608         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3609         cp /etc/hosts $DIR/d31f
3610         ls -l $DIR/d31f
3611         $LFS getstripe $DIR/d31f/hosts
3612         multiop_bg_pause $DIR/d31f D_c || return 1
3613         MULTIPID2=$!
3614
3615         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3616         wait $MULTIPID || error "first opendir $MULTIPID failed"
3617
3618         sleep 6
3619
3620         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3621         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3622         set +vx
3623 }
3624 run_test 31f "remove of open directory with open-unlink file ==="
3625
3626 test_31g() {
3627         echo "-- cross directory link --"
3628         test_mkdir -c1 $DIR/${tdir}ga
3629         test_mkdir -c1 $DIR/${tdir}gb
3630         touch $DIR/${tdir}ga/f
3631         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3632         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3633         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3634         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3635         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3636 }
3637 run_test 31g "cross directory link==============="
3638
3639 test_31h() {
3640         echo "-- cross directory link --"
3641         test_mkdir -c1 $DIR/${tdir}
3642         test_mkdir -c1 $DIR/${tdir}/dir
3643         touch $DIR/${tdir}/f
3644         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3645         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3646         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3647         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3648         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3649 }
3650 run_test 31h "cross directory link under child==============="
3651
3652 test_31i() {
3653         echo "-- cross directory link --"
3654         test_mkdir -c1 $DIR/$tdir
3655         test_mkdir -c1 $DIR/$tdir/dir
3656         touch $DIR/$tdir/dir/f
3657         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3658         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3659         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3660         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3661         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3662 }
3663 run_test 31i "cross directory link under parent==============="
3664
3665 test_31j() {
3666         test_mkdir -c1 -p $DIR/$tdir
3667         test_mkdir -c1 -p $DIR/$tdir/dir1
3668         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3669         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3671         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3672         return 0
3673 }
3674 run_test 31j "link for directory==============="
3675
3676 test_31k() {
3677         test_mkdir -c1 -p $DIR/$tdir
3678         touch $DIR/$tdir/s
3679         touch $DIR/$tdir/exist
3680         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3681         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3682         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3683         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3684         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3686         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3687         return 0
3688 }
3689 run_test 31k "link to file: the same, non-existing, dir==============="
3690
3691 test_31m() {
3692         mkdir $DIR/d31m
3693         touch $DIR/d31m/s
3694         mkdir $DIR/d31m2
3695         touch $DIR/d31m2/exist
3696         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3697         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3698         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3699         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3701         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3702         return 0
3703 }
3704 run_test 31m "link to file: the same, non-existing, dir==============="
3705
3706 test_31n() {
3707         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3708         nlink=$(stat --format=%h $DIR/$tfile)
3709         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3710         local fd=$(free_fd)
3711         local cmd="exec $fd<$DIR/$tfile"
3712         eval $cmd
3713         cmd="exec $fd<&-"
3714         trap "eval $cmd" EXIT
3715         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3716         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3717         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3718         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3719         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3720         eval $cmd
3721 }
3722 run_test 31n "check link count of unlinked file"
3723
3724 link_one() {
3725         local tempfile=$(mktemp $1_XXXXXX)
3726         mlink $tempfile $1 2> /dev/null &&
3727                 echo "$BASHPID: link $tempfile to $1 succeeded"
3728         munlink $tempfile
3729 }
3730
3731 test_31o() { # LU-2901
3732         test_mkdir $DIR/$tdir
3733         for LOOP in $(seq 100); do
3734                 rm -f $DIR/$tdir/$tfile*
3735                 for THREAD in $(seq 8); do
3736                         link_one $DIR/$tdir/$tfile.$LOOP &
3737                 done
3738                 wait
3739                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3740                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3741                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3742                         break || true
3743         done
3744 }
3745 run_test 31o "duplicate hard links with same filename"
3746
3747 test_31p() {
3748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3752         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3753
3754         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3755                 error "open unlink test1 failed"
3756         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3757                 error "open unlink test2 failed"
3758
3759         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3760                 error "test1 still exists"
3761         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3762                 error "test2 still exists"
3763 }
3764 run_test 31p "remove of open striped directory"
3765
3766 test_31q() {
3767         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3768
3769         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3770         index=$($LFS getdirstripe -i $DIR/$tdir)
3771         [ $index -eq 3 ] || error "first stripe index $index != 3"
3772         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3773         [ $index -eq 1 ] || error "second stripe index $index != 1"
3774
3775         # when "-c <stripe_count>" is set, the number of MDTs specified after
3776         # "-i" should equal to the stripe count
3777         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3778 }
3779 run_test 31q "create striped directory on specific MDTs"
3780
3781 #LU-14949
3782 test_31r() {
3783         touch $DIR/$tfile.target
3784         touch $DIR/$tfile.source
3785
3786         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3787         $LCTL set_param fail_loc=0x1419 fail_val=3
3788         cat $DIR/$tfile.target &
3789         CATPID=$!
3790
3791         # Guarantee open is waiting before we get here
3792         sleep 1
3793         mv $DIR/$tfile.source $DIR/$tfile.target
3794
3795         wait $CATPID
3796         RC=$?
3797         if [[ $RC -ne 0 ]]; then
3798                 error "open with cat failed, rc=$RC"
3799         fi
3800 }
3801 run_test 31r "open-rename(replace) race"
3802
3803 cleanup_test32_mount() {
3804         local rc=0
3805         trap 0
3806         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3807         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3808         losetup -d $loopdev || true
3809         rm -rf $DIR/$tdir
3810         return $rc
3811 }
3812
3813 test_32a() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         echo "== more mountpoints and symlinks ================="
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3823                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3824         cleanup_test32_mount
3825 }
3826 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3827
3828 test_32b() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3837                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3838         cleanup_test32_mount
3839 }
3840 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3841
3842 test_32c() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2/test_dir
3851         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3852                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3853         cleanup_test32_mount
3854 }
3855 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3856
3857 test_32d() {
3858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3859
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         test_mkdir -p $DIR/$tdir/d2/test_dir
3866         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3868         cleanup_test32_mount
3869 }
3870 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3871
3872 test_32e() {
3873         rm -fr $DIR/$tdir
3874         test_mkdir -p $DIR/$tdir/tmp
3875         local tmp_dir=$DIR/$tdir/tmp
3876         ln -s $DIR/$tdir $tmp_dir/symlink11
3877         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3878         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3879         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3880 }
3881 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3882
3883 test_32f() {
3884         rm -fr $DIR/$tdir
3885         test_mkdir -p $DIR/$tdir/tmp
3886         local tmp_dir=$DIR/$tdir/tmp
3887         ln -s $DIR/$tdir $tmp_dir/symlink11
3888         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3889         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3890         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3891 }
3892 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3893
3894 test_32g() {
3895         local tmp_dir=$DIR/$tdir/tmp
3896         test_mkdir -p $tmp_dir
3897         test_mkdir $DIR/${tdir}2
3898         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3899         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3900         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3901         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3902         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3903         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3904 }
3905 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3906
3907 test_32h() {
3908         rm -fr $DIR/$tdir $DIR/${tdir}2
3909         tmp_dir=$DIR/$tdir/tmp
3910         test_mkdir -p $tmp_dir
3911         test_mkdir $DIR/${tdir}2
3912         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3913         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3914         ls $tmp_dir/symlink12 || error "listing symlink12"
3915         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3916 }
3917 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3918
3919 test_32i() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         touch $DIR/$tdir/test_file
3928         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3929                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3930         cleanup_test32_mount
3931 }
3932 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3933
3934 test_32j() {
3935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3936
3937         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3938         trap cleanup_test32_mount EXIT
3939         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3940         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3941                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3942         touch $DIR/$tdir/test_file
3943         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3948
3949 test_32k() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         test_mkdir -p $DIR/$tdir/d2
3958         touch $DIR/$tdir/d2/test_file || error "touch failed"
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3964
3965 test_32l() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         test_mkdir -p $DIR/$tdir/d2
3974         touch $DIR/$tdir/d2/test_file || error "touch failed"
3975         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3976                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3977         cleanup_test32_mount
3978 }
3979 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3980
3981 test_32m() {
3982         rm -fr $DIR/d32m
3983         test_mkdir -p $DIR/d32m/tmp
3984         TMP_DIR=$DIR/d32m/tmp
3985         ln -s $DIR $TMP_DIR/symlink11
3986         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3987         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3988                 error "symlink11 not a link"
3989         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3990                 error "symlink01 not a link"
3991 }
3992 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3993
3994 test_32n() {
3995         rm -fr $DIR/d32n
3996         test_mkdir -p $DIR/d32n/tmp
3997         TMP_DIR=$DIR/d32n/tmp
3998         ln -s $DIR $TMP_DIR/symlink11
3999         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4000         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4001         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4002 }
4003 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4004
4005 test_32o() {
4006         touch $DIR/$tfile
4007         test_mkdir -p $DIR/d32o/tmp
4008         TMP_DIR=$DIR/d32o/tmp
4009         ln -s $DIR/$tfile $TMP_DIR/symlink12
4010         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4011         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4012                 error "symlink12 not a link"
4013         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4014         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4015                 error "$DIR/d32o/tmp/symlink12 not file type"
4016         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4017                 error "$DIR/d32o/symlink02 not file type"
4018 }
4019 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4020
4021 test_32p() {
4022         log 32p_1
4023         rm -fr $DIR/d32p
4024         log 32p_2
4025         rm -f $DIR/$tfile
4026         log 32p_3
4027         touch $DIR/$tfile
4028         log 32p_4
4029         test_mkdir -p $DIR/d32p/tmp
4030         log 32p_5
4031         TMP_DIR=$DIR/d32p/tmp
4032         log 32p_6
4033         ln -s $DIR/$tfile $TMP_DIR/symlink12
4034         log 32p_7
4035         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4036         log 32p_8
4037         cat $DIR/d32p/tmp/symlink12 ||
4038                 error "Can't open $DIR/d32p/tmp/symlink12"
4039         log 32p_9
4040         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4041         log 32p_10
4042 }
4043 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4044
4045 test_32q() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4055         cleanup_test32_mount
4056 }
4057 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4058
4059 test_32r() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4069         cleanup_test32_mount
4070 }
4071 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4072
4073 test_33aa() {
4074         rm -f $DIR/$tfile
4075         touch $DIR/$tfile
4076         chmod 444 $DIR/$tfile
4077         chown $RUNAS_ID $DIR/$tfile
4078         log 33_1
4079         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4080         log 33_2
4081 }
4082 run_test 33aa "write file with mode 444 (should return error)"
4083
4084 test_33a() {
4085         rm -fr $DIR/$tdir
4086         test_mkdir $DIR/$tdir
4087         chown $RUNAS_ID $DIR/$tdir
4088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4089                 error "$RUNAS create $tdir/$tfile failed"
4090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4091                 error "open RDWR" || true
4092 }
4093 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4094
4095 test_33b() {
4096         rm -fr $DIR/$tdir
4097         test_mkdir $DIR/$tdir
4098         chown $RUNAS_ID $DIR/$tdir
4099         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4100 }
4101 run_test 33b "test open file with malformed flags (No panic)"
4102
4103 test_33c() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105         remote_ost_nodsh && skip "remote OST with nodsh"
4106
4107         local ostnum
4108         local ostname
4109         local write_bytes
4110         local all_zeros
4111
4112         all_zeros=true
4113         test_mkdir $DIR/$tdir
4114         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4115
4116         sync
4117         for ostnum in $(seq $OSTCOUNT); do
4118                 # test-framework's OST numbering is one-based, while Lustre's
4119                 # is zero-based
4120                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4121                 # check if at least some write_bytes stats are counted
4122                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4123                               obdfilter.$ostname.stats |
4124                               awk '/^write_bytes/ {print $7}' )
4125                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4126                 if (( ${write_bytes:-0} > 0 )); then
4127                         all_zeros=false
4128                         break
4129                 fi
4130         done
4131
4132         $all_zeros || return 0
4133
4134         # Write four bytes
4135         echo foo > $DIR/$tdir/bar
4136         # Really write them
4137         sync
4138
4139         # Total up write_bytes after writing.  We'd better find non-zeros.
4140         for ostnum in $(seq $OSTCOUNT); do
4141                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4142                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4143                               obdfilter/$ostname/stats |
4144                               awk '/^write_bytes/ {print $7}' )
4145                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4146                 if (( ${write_bytes:-0} > 0 )); then
4147                         all_zeros=false
4148                         break
4149                 fi
4150         done
4151
4152         if $all_zeros; then
4153                 for ostnum in $(seq $OSTCOUNT); do
4154                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4155                         echo "Check write_bytes is in obdfilter.*.stats:"
4156                         do_facet ost$ostnum lctl get_param -n \
4157                                 obdfilter.$ostname.stats
4158                 done
4159                 error "OST not keeping write_bytes stats (b=22312)"
4160         fi
4161 }
4162 run_test 33c "test write_bytes stats"
4163
4164 test_33d() {
4165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4167
4168         local MDTIDX=1
4169         local remote_dir=$DIR/$tdir/remote_dir
4170
4171         test_mkdir $DIR/$tdir
4172         $LFS mkdir -i $MDTIDX $remote_dir ||
4173                 error "create remote directory failed"
4174
4175         touch $remote_dir/$tfile
4176         chmod 444 $remote_dir/$tfile
4177         chown $RUNAS_ID $remote_dir/$tfile
4178
4179         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4180
4181         chown $RUNAS_ID $remote_dir
4182         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4183                                         error "create" || true
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4185                                     error "open RDWR" || true
4186         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4187 }
4188 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4189
4190 test_33e() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192
4193         mkdir $DIR/$tdir
4194
4195         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4196         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4197         mkdir $DIR/$tdir/local_dir
4198
4199         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4200         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4201         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4202
4203         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4204                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4205
4206         rmdir $DIR/$tdir/* || error "rmdir failed"
4207
4208         umask 777
4209         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4210         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4211         mkdir $DIR/$tdir/local_dir
4212
4213         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4214         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4215         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4216
4217         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4218                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4219
4220         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4221
4222         umask 000
4223         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4224         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4225         mkdir $DIR/$tdir/local_dir
4226
4227         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4228         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4229         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4230
4231         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4232                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4233 }
4234 run_test 33e "mkdir and striped directory should have same mode"
4235
4236 cleanup_33f() {
4237         trap 0
4238         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4239 }
4240
4241 test_33f() {
4242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4243         remote_mds_nodsh && skip "remote MDS with nodsh"
4244
4245         mkdir $DIR/$tdir
4246         chmod go+rwx $DIR/$tdir
4247         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4248         trap cleanup_33f EXIT
4249
4250         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4251                 error "cannot create striped directory"
4252
4253         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4254                 error "cannot create files in striped directory"
4255
4256         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4257                 error "cannot remove files in striped directory"
4258
4259         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4260                 error "cannot remove striped directory"
4261
4262         cleanup_33f
4263 }
4264 run_test 33f "nonroot user can create, access, and remove a striped directory"
4265
4266 test_33g() {
4267         mkdir -p $DIR/$tdir/dir2
4268
4269         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4270         echo $err
4271         [[ $err =~ "exists" ]] || error "Not exists error"
4272 }
4273 run_test 33g "nonroot user create already existing root created file"
4274
4275 sub_33h() {
4276         local hash_type=$1
4277         local count=250
4278
4279         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4280                 error "lfs mkdir -H $hash_type $tdir failed"
4281         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4282
4283         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4284         local index2
4285         local fname
4286
4287         for fname in $DIR/$tdir/$tfile.bak \
4288                      $DIR/$tdir/$tfile.SAV \
4289                      $DIR/$tdir/$tfile.orig \
4290                      $DIR/$tdir/$tfile~; do
4291                 touch $fname || error "touch $fname failed"
4292                 index2=$($LFS getstripe -m $fname)
4293                 (( $index == $index2 )) ||
4294                         error "$fname MDT index mismatch $index != $index2"
4295         done
4296
4297         local failed=0
4298         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4299         local pattern
4300
4301         for pattern in ${patterns[*]}; do
4302                 echo "pattern $pattern"
4303                 fname=$DIR/$tdir/$pattern
4304                 for (( i = 0; i < $count; i++ )); do
4305                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4306                                 error "mktemp $DIR/$tdir/$pattern failed"
4307                         index2=$($LFS getstripe -m $fname)
4308                         (( $index == $index2 )) && continue
4309
4310                         failed=$((failed + 1))
4311                         echo "$fname MDT index mismatch $index != $index2"
4312                 done
4313         done
4314
4315         echo "$failed/$count MDT index mismatches, expect ~2-4"
4316         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4317
4318         local same=0
4319         local expect
4320
4321         # verify that "crush" is still broken with all files on same MDT,
4322         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4323         [[ "$hash_type" == "crush" ]] && expect=$count ||
4324                 expect=$((count / MDSCOUNT))
4325
4326         # crush2 doesn't put all-numeric suffixes on the same MDT,
4327         # filename like $tfile.12345678 should *not* be considered temp
4328         for pattern in ${patterns[*]}; do
4329                 local base=${pattern%%X*}
4330                 local suff=${pattern#$base}
4331
4332                 echo "pattern $pattern"
4333                 for (( i = 0; i < $count; i++ )); do
4334                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4335                         touch $fname || error "touch $fname failed"
4336                         index2=$($LFS getstripe -m $fname)
4337                         (( $index != $index2 )) && continue
4338
4339                         same=$((same + 1))
4340                 done
4341         done
4342
4343         # the number of "bad" hashes is random, as it depends on the random
4344         # filenames generated by "mktemp".  Allow some margin in the results.
4345         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4346         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4347            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4348                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4349         same=0
4350
4351         # crush2 doesn't put suffixes with special characters on the same MDT
4352         # filename like $tfile.txt.1234 should *not* be considered temp
4353         for pattern in ${patterns[*]}; do
4354                 local base=${pattern%%X*}
4355                 local suff=${pattern#$base}
4356
4357                 pattern=$base...${suff/XXX}
4358                 echo "pattern=$pattern"
4359                 for (( i = 0; i < $count; i++ )); do
4360                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4361                                 error "touch $fname failed"
4362                         index2=$($LFS getstripe -m $fname)
4363                         (( $index != $index2 )) && continue
4364
4365                         same=$((same + 1))
4366                 done
4367         done
4368
4369         # the number of "bad" hashes is random, as it depends on the random
4370         # filenames generated by "mktemp".  Allow some margin in the results.
4371         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4372         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4373            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4374                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4375 }
4376
4377 test_33h() {
4378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4379         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4380                 skip "Need MDS version at least 2.13.50"
4381
4382         sub_33h crush
4383 }
4384 run_test 33h "temp file is located on the same MDT as target (crush)"
4385
4386 test_33hh() {
4387         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4388         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4389         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4390                 skip "Need MDS version at least 2.15.0 for crush2"
4391
4392         sub_33h crush2
4393 }
4394 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4395
4396 test_33i()
4397 {
4398         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4399
4400         local FNAME=$(str_repeat 'f' 250)
4401
4402         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4403         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4404
4405         local count
4406         local total
4407
4408         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4409
4410         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4411
4412         lctl --device %$MDC deactivate
4413         stack_trap "lctl --device %$MDC activate"
4414         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4415         total=$(\ls -l $DIR/$tdir | wc -l)
4416         # "ls -l" will list total in the first line
4417         total=$((total - 1))
4418         (( total + count == 1000 )) ||
4419                 error "ls list $total files, $count files on MDT1"
4420 }
4421 run_test 33i "striped directory can be accessed when one MDT is down"
4422
4423 test_33j() {
4424         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4425
4426         mkdir -p $DIR/$tdir/
4427
4428         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4429                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4430
4431         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4432                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4433
4434         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4435                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4436
4437         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4438                 error "-D was not specified, but still failed"
4439 }
4440 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4441
4442 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4443 test_34a() {
4444         rm -f $DIR/f34
4445         $MCREATE $DIR/f34 || error "mcreate failed"
4446         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4447                 error "getstripe failed"
4448         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4449         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4450                 error "getstripe failed"
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453 }
4454 run_test 34a "truncate file that has not been opened ==========="
4455
4456 test_34b() {
4457         [ ! -f $DIR/f34 ] && test_34a
4458         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4459                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4460         $OPENFILE -f O_RDONLY $DIR/f34
4461         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4462                 error "getstripe failed"
4463         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4464                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4465 }
4466 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4467
4468 test_34c() {
4469         [ ! -f $DIR/f34 ] && test_34a
4470         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4471                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4472         $OPENFILE -f O_RDWR $DIR/f34
4473         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4474                 error "$LFS getstripe failed"
4475         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4476                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4477 }
4478 run_test 34c "O_RDWR opening file-with-size works =============="
4479
4480 test_34d() {
4481         [ ! -f $DIR/f34 ] && test_34a
4482         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4483                 error "dd failed"
4484         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4485                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4486         rm $DIR/f34
4487 }
4488 run_test 34d "write to sparse file ============================="
4489
4490 test_34e() {
4491         rm -f $DIR/f34e
4492         $MCREATE $DIR/f34e || error "mcreate failed"
4493         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4494         $CHECKSTAT -s 1000 $DIR/f34e ||
4495                 error "Size of $DIR/f34e not equal to 1000 bytes"
4496         $OPENFILE -f O_RDWR $DIR/f34e
4497         $CHECKSTAT -s 1000 $DIR/f34e ||
4498                 error "Size of $DIR/f34e not equal to 1000 bytes"
4499 }
4500 run_test 34e "create objects, some with size and some without =="
4501
4502 test_34f() { # bug 6242, 6243
4503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4504
4505         SIZE34F=48000
4506         rm -f $DIR/f34f
4507         $MCREATE $DIR/f34f || error "mcreate failed"
4508         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4509         dd if=$DIR/f34f of=$TMP/f34f
4510         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4511         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4512         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4513         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4514         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4515 }
4516 run_test 34f "read from a file with no objects until EOF ======="
4517
4518 test_34g() {
4519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4520
4521         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4522                 error "dd failed"
4523         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4524         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4525                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4526         cancel_lru_locks osc
4527         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4528                 error "wrong size after lock cancel"
4529
4530         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4531         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4532                 error "expanding truncate failed"
4533         cancel_lru_locks osc
4534         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4535                 error "wrong expanded size after lock cancel"
4536 }
4537 run_test 34g "truncate long file ==============================="
4538
4539 test_34h() {
4540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4541
4542         local gid=10
4543         local sz=1000
4544
4545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4546         sync # Flush the cache so that multiop below does not block on cache
4547              # flush when getting the group lock
4548         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4549         MULTIPID=$!
4550
4551         # Since just timed wait is not good enough, let's do a sync write
4552         # that way we are sure enough time for a roundtrip + processing
4553         # passed + 2 seconds of extra margin.
4554         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4555         rm $DIR/${tfile}-1
4556         sleep 2
4557
4558         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4559                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4560                 kill -9 $MULTIPID
4561         fi
4562         wait $MULTIPID
4563         local nsz=`stat -c %s $DIR/$tfile`
4564         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4565 }
4566 run_test 34h "ftruncate file under grouplock should not block"
4567
4568 test_35a() {
4569         cp /bin/sh $DIR/f35a
4570         chmod 444 $DIR/f35a
4571         chown $RUNAS_ID $DIR/f35a
4572         $RUNAS $DIR/f35a && error || true
4573         rm $DIR/f35a
4574 }
4575 run_test 35a "exec file with mode 444 (should return and not leak)"
4576
4577 test_36a() {
4578         rm -f $DIR/f36
4579         utime $DIR/f36 || error "utime failed for MDS"
4580 }
4581 run_test 36a "MDS utime check (mknod, utime)"
4582
4583 test_36b() {
4584         echo "" > $DIR/f36
4585         utime $DIR/f36 || error "utime failed for OST"
4586 }
4587 run_test 36b "OST utime check (open, utime)"
4588
4589 test_36c() {
4590         rm -f $DIR/d36/f36
4591         test_mkdir $DIR/d36
4592         chown $RUNAS_ID $DIR/d36
4593         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4594 }
4595 run_test 36c "non-root MDS utime check (mknod, utime)"
4596
4597 test_36d() {
4598         [ ! -d $DIR/d36 ] && test_36c
4599         echo "" > $DIR/d36/f36
4600         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4601 }
4602 run_test 36d "non-root OST utime check (open, utime)"
4603
4604 test_36e() {
4605         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4606
4607         test_mkdir $DIR/$tdir
4608         touch $DIR/$tdir/$tfile
4609         $RUNAS utime $DIR/$tdir/$tfile &&
4610                 error "utime worked, expected failure" || true
4611 }
4612 run_test 36e "utime on non-owned file (should return error)"
4613
4614 subr_36fh() {
4615         local fl="$1"
4616         local LANG_SAVE=$LANG
4617         local LC_LANG_SAVE=$LC_LANG
4618         export LANG=C LC_LANG=C # for date language
4619
4620         DATESTR="Dec 20  2000"
4621         test_mkdir $DIR/$tdir
4622         lctl set_param fail_loc=$fl
4623         date; date +%s
4624         cp /etc/hosts $DIR/$tdir/$tfile
4625         sync & # write RPC generated with "current" inode timestamp, but delayed
4626         sleep 1
4627         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4628         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4629         cancel_lru_locks $OSC
4630         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4631         date; date +%s
4632         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4633                 echo "BEFORE: $LS_BEFORE" && \
4634                 echo "AFTER : $LS_AFTER" && \
4635                 echo "WANT  : $DATESTR" && \
4636                 error "$DIR/$tdir/$tfile timestamps changed" || true
4637
4638         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4639 }
4640
4641 test_36f() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643
4644         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4645         subr_36fh "0x80000214"
4646 }
4647 run_test 36f "utime on file racing with OST BRW write =========="
4648
4649 test_36g() {
4650         remote_ost_nodsh && skip "remote OST with nodsh"
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4653                 skip "Need MDS version at least 2.12.51"
4654
4655         local fmd_max_age
4656         local fmd
4657         local facet="ost1"
4658         local tgt="obdfilter"
4659
4660         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4661
4662         test_mkdir $DIR/$tdir
4663         fmd_max_age=$(do_facet $facet \
4664                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4665                 head -n 1")
4666
4667         echo "FMD max age: ${fmd_max_age}s"
4668         touch $DIR/$tdir/$tfile
4669         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4670                 gawk '{cnt=cnt+$1}  END{print cnt}')
4671         echo "FMD before: $fmd"
4672         [[ $fmd == 0 ]] &&
4673                 error "FMD wasn't create by touch"
4674         sleep $((fmd_max_age + 12))
4675         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4676                 gawk '{cnt=cnt+$1}  END{print cnt}')
4677         echo "FMD after: $fmd"
4678         [[ $fmd == 0 ]] ||
4679                 error "FMD wasn't expired by ping"
4680 }
4681 run_test 36g "FMD cache expiry ====================="
4682
4683 test_36h() {
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685
4686         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4687         subr_36fh "0x80000227"
4688 }
4689 run_test 36h "utime on file racing with OST BRW write =========="
4690
4691 test_36i() {
4692         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4693
4694         test_mkdir $DIR/$tdir
4695         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4696
4697         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4698         local new_mtime=$((mtime + 200))
4699
4700         #change Modify time of striped dir
4701         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4702                         error "change mtime failed"
4703
4704         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4705
4706         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4707 }
4708 run_test 36i "change mtime on striped directory"
4709
4710 # test_37 - duplicate with tests 32q 32r
4711
4712 test_38() {
4713         local file=$DIR/$tfile
4714         touch $file
4715         openfile -f O_DIRECTORY $file
4716         local RC=$?
4717         local ENOTDIR=20
4718         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4719         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4720 }
4721 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4722
4723 test_39a() { # was test_39
4724         touch $DIR/$tfile
4725         touch $DIR/${tfile}2
4726 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4727 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4728 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4729         sleep 2
4730         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4731         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4732                 echo "mtime"
4733                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4734                 echo "atime"
4735                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4736                 echo "ctime"
4737                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4738                 error "O_TRUNC didn't change timestamps"
4739         fi
4740 }
4741 run_test 39a "mtime changed on create"
4742
4743 test_39b() {
4744         test_mkdir -c1 $DIR/$tdir
4745         cp -p /etc/passwd $DIR/$tdir/fopen
4746         cp -p /etc/passwd $DIR/$tdir/flink
4747         cp -p /etc/passwd $DIR/$tdir/funlink
4748         cp -p /etc/passwd $DIR/$tdir/frename
4749         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4750
4751         sleep 1
4752         echo "aaaaaa" >> $DIR/$tdir/fopen
4753         echo "aaaaaa" >> $DIR/$tdir/flink
4754         echo "aaaaaa" >> $DIR/$tdir/funlink
4755         echo "aaaaaa" >> $DIR/$tdir/frename
4756
4757         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4758         local link_new=`stat -c %Y $DIR/$tdir/flink`
4759         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4760         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4761
4762         cat $DIR/$tdir/fopen > /dev/null
4763         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4764         rm -f $DIR/$tdir/funlink2
4765         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4766
4767         for (( i=0; i < 2; i++ )) ; do
4768                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4769                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4770                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4771                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4772
4773                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4774                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4775                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4776                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4777
4778                 cancel_lru_locks $OSC
4779                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4780         done
4781 }
4782 run_test 39b "mtime change on open, link, unlink, rename  ======"
4783
4784 # this should be set to past
4785 TEST_39_MTIME=`date -d "1 year ago" +%s`
4786
4787 # bug 11063
4788 test_39c() {
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local mtime0=`stat -c %Y $DIR1/$tfile`
4792
4793         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4794         local mtime1=`stat -c %Y $DIR1/$tfile`
4795         [ "$mtime1" = $TEST_39_MTIME ] || \
4796                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4797
4798         local d1=`date +%s`
4799         echo hello >> $DIR1/$tfile
4800         local d2=`date +%s`
4801         local mtime2=`stat -c %Y $DIR1/$tfile`
4802         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4803                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4804
4805         mv $DIR1/$tfile $DIR1/$tfile-1
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4809                 [ "$mtime2" = "$mtime3" ] || \
4810                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39c "mtime change on rename ==========================="
4817
4818 # bug 21114
4819 test_39d() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4824
4825         for (( i=0; i < 2; i++ )) ; do
4826                 local mtime=`stat -c %Y $DIR1/$tfile`
4827                 [ $mtime = $TEST_39_MTIME ] || \
4828                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4829
4830                 cancel_lru_locks $OSC
4831                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4832         done
4833 }
4834 run_test 39d "create, utime, stat =============================="
4835
4836 # bug 21114
4837 test_39e() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         touch $DIR1/$tfile
4841         local mtime1=`stat -c %Y $DIR1/$tfile`
4842
4843         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4844
4845         for (( i=0; i < 2; i++ )) ; do
4846                 local mtime2=`stat -c %Y $DIR1/$tfile`
4847                 [ $mtime2 = $TEST_39_MTIME ] || \
4848                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4849
4850                 cancel_lru_locks $OSC
4851                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4852         done
4853 }
4854 run_test 39e "create, stat, utime, stat ========================"
4855
4856 # bug 21114
4857 test_39f() {
4858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4859
4860         touch $DIR1/$tfile
4861         mtime1=`stat -c %Y $DIR1/$tfile`
4862
4863         sleep 2
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865
4866         for (( i=0; i < 2; i++ )) ; do
4867                 local mtime2=`stat -c %Y $DIR1/$tfile`
4868                 [ $mtime2 = $TEST_39_MTIME ] || \
4869                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4870
4871                 cancel_lru_locks $OSC
4872                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4873         done
4874 }
4875 run_test 39f "create, stat, sleep, utime, stat ================="
4876
4877 # bug 11063
4878 test_39g() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         echo hello >> $DIR1/$tfile
4882         local mtime1=`stat -c %Y $DIR1/$tfile`
4883
4884         sleep 2
4885         chmod o+r $DIR1/$tfile
4886
4887         for (( i=0; i < 2; i++ )) ; do
4888                 local mtime2=`stat -c %Y $DIR1/$tfile`
4889                 [ "$mtime1" = "$mtime2" ] || \
4890                         error "lost mtime: $mtime2, should be $mtime1"
4891
4892                 cancel_lru_locks $OSC
4893                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4894         done
4895 }
4896 run_test 39g "write, chmod, stat ==============================="
4897
4898 # bug 11063
4899 test_39h() {
4900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4901
4902         touch $DIR1/$tfile
4903         sleep 1
4904
4905         local d1=`date`
4906         echo hello >> $DIR1/$tfile
4907         local mtime1=`stat -c %Y $DIR1/$tfile`
4908
4909         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4910         local d2=`date`
4911         if [ "$d1" != "$d2" ]; then
4912                 echo "write and touch not within one second"
4913         else
4914                 for (( i=0; i < 2; i++ )) ; do
4915                         local mtime2=`stat -c %Y $DIR1/$tfile`
4916                         [ "$mtime2" = $TEST_39_MTIME ] || \
4917                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4918
4919                         cancel_lru_locks $OSC
4920                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4921                 done
4922         fi
4923 }
4924 run_test 39h "write, utime within one second, stat ============="
4925
4926 test_39i() {
4927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4928
4929         touch $DIR1/$tfile
4930         sleep 1
4931
4932         echo hello >> $DIR1/$tfile
4933         local mtime1=`stat -c %Y $DIR1/$tfile`
4934
4935         mv $DIR1/$tfile $DIR1/$tfile-1
4936
4937         for (( i=0; i < 2; i++ )) ; do
4938                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4939
4940                 [ "$mtime1" = "$mtime2" ] || \
4941                         error "lost mtime: $mtime2, should be $mtime1"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39i "write, rename, stat =============================="
4948
4949 test_39j() {
4950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4951
4952         start_full_debug_logging
4953         touch $DIR1/$tfile
4954         sleep 1
4955
4956         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4957         lctl set_param fail_loc=0x80000412
4958         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4959                 error "multiop failed"
4960         local multipid=$!
4961         local mtime1=`stat -c %Y $DIR1/$tfile`
4962
4963         mv $DIR1/$tfile $DIR1/$tfile-1
4964
4965         kill -USR1 $multipid
4966         wait $multipid || error "multiop close failed"
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4970                 [ "$mtime1" = "$mtime2" ] ||
4971                         error "mtime is lost on close: $mtime2, " \
4972                               "should be $mtime1"
4973
4974                 cancel_lru_locks
4975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4976         done
4977         lctl set_param fail_loc=0
4978         stop_full_debug_logging
4979 }
4980 run_test 39j "write, rename, close, stat ======================="
4981
4982 test_39k() {
4983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4984
4985         touch $DIR1/$tfile
4986         sleep 1
4987
4988         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4989         local multipid=$!
4990         local mtime1=`stat -c %Y $DIR1/$tfile`
4991
4992         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4993
4994         kill -USR1 $multipid
4995         wait $multipid || error "multiop close failed"
4996
4997         for (( i=0; i < 2; i++ )) ; do
4998                 local mtime2=`stat -c %Y $DIR1/$tfile`
4999
5000                 [ "$mtime2" = $TEST_39_MTIME ] || \
5001                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5002
5003                 cancel_lru_locks
5004                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5005         done
5006 }
5007 run_test 39k "write, utime, close, stat ========================"
5008
5009 # this should be set to future
5010 TEST_39_ATIME=`date -d "1 year" +%s`
5011
5012 test_39l() {
5013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5014         remote_mds_nodsh && skip "remote MDS with nodsh"
5015
5016         local atime_diff=$(do_facet $SINGLEMDS \
5017                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5018         rm -rf $DIR/$tdir
5019         mkdir_on_mdt0 $DIR/$tdir
5020
5021         # test setting directory atime to future
5022         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5023         local atime=$(stat -c %X $DIR/$tdir)
5024         [ "$atime" = $TEST_39_ATIME ] ||
5025                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5026
5027         # test setting directory atime from future to now
5028         local now=$(date +%s)
5029         touch -a -d @$now $DIR/$tdir
5030
5031         atime=$(stat -c %X $DIR/$tdir)
5032         [ "$atime" -eq "$now"  ] ||
5033                 error "atime is not updated from future: $atime, $now"
5034
5035         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5036         sleep 3
5037
5038         # test setting directory atime when now > dir atime + atime_diff
5039         local d1=$(date +%s)
5040         ls $DIR/$tdir
5041         local d2=$(date +%s)
5042         cancel_lru_locks mdc
5043         atime=$(stat -c %X $DIR/$tdir)
5044         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5045                 error "atime is not updated  : $atime, should be $d2"
5046
5047         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5048         sleep 3
5049
5050         # test not setting directory atime when now < dir atime + atime_diff
5051         ls $DIR/$tdir
5052         cancel_lru_locks mdc
5053         atime=$(stat -c %X $DIR/$tdir)
5054         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5055                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5056
5057         do_facet $SINGLEMDS \
5058                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5059 }
5060 run_test 39l "directory atime update ==========================="
5061
5062 test_39m() {
5063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5064
5065         touch $DIR1/$tfile
5066         sleep 2
5067         local far_past_mtime=$(date -d "May 29 1953" +%s)
5068         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5069
5070         touch -m -d @$far_past_mtime $DIR1/$tfile
5071         touch -a -d @$far_past_atime $DIR1/$tfile
5072
5073         for (( i=0; i < 2; i++ )) ; do
5074                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5075                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5076                         error "atime or mtime set incorrectly"
5077
5078                 cancel_lru_locks $OSC
5079                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5080         done
5081 }
5082 run_test 39m "test atime and mtime before 1970"
5083
5084 test_39n() { # LU-3832
5085         remote_mds_nodsh && skip "remote MDS with nodsh"
5086
5087         local atime_diff=$(do_facet $SINGLEMDS \
5088                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5089         local atime0
5090         local atime1
5091         local atime2
5092
5093         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5094
5095         rm -rf $DIR/$tfile
5096         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5097         atime0=$(stat -c %X $DIR/$tfile)
5098
5099         sleep 5
5100         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5101         atime1=$(stat -c %X $DIR/$tfile)
5102
5103         sleep 5
5104         cancel_lru_locks mdc
5105         cancel_lru_locks osc
5106         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5107         atime2=$(stat -c %X $DIR/$tfile)
5108
5109         do_facet $SINGLEMDS \
5110                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5111
5112         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5113         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5114 }
5115 run_test 39n "check that O_NOATIME is honored"
5116
5117 test_39o() {
5118         TESTDIR=$DIR/$tdir/$tfile
5119         [ -e $TESTDIR ] && rm -rf $TESTDIR
5120         mkdir -p $TESTDIR
5121         cd $TESTDIR
5122         links1=2
5123         ls
5124         mkdir a b
5125         ls
5126         links2=$(stat -c %h .)
5127         [ $(($links1 + 2)) != $links2 ] &&
5128                 error "wrong links count $(($links1 + 2)) != $links2"
5129         rmdir b
5130         links3=$(stat -c %h .)
5131         [ $(($links1 + 1)) != $links3 ] &&
5132                 error "wrong links count $links1 != $links3"
5133         return 0
5134 }
5135 run_test 39o "directory cached attributes updated after create"
5136
5137 test_39p() {
5138         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5139
5140         local MDTIDX=1
5141         TESTDIR=$DIR/$tdir/$tdir
5142         [ -e $TESTDIR ] && rm -rf $TESTDIR
5143         test_mkdir -p $TESTDIR
5144         cd $TESTDIR
5145         links1=2
5146         ls
5147         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5148         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5149         ls
5150         links2=$(stat -c %h .)
5151         [ $(($links1 + 2)) != $links2 ] &&
5152                 error "wrong links count $(($links1 + 2)) != $links2"
5153         rmdir remote_dir2
5154         links3=$(stat -c %h .)
5155         [ $(($links1 + 1)) != $links3 ] &&
5156                 error "wrong links count $links1 != $links3"
5157         return 0
5158 }
5159 run_test 39p "remote directory cached attributes updated after create ========"
5160
5161 test_39r() {
5162         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5163                 skip "no atime update on old OST"
5164         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5165                 skip_env "ldiskfs only test"
5166         fi
5167
5168         local saved_adiff
5169         saved_adiff=$(do_facet ost1 \
5170                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5171         stack_trap "do_facet ost1 \
5172                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5173
5174         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5175
5176         $LFS setstripe -i 0 $DIR/$tfile
5177         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5178                 error "can't write initial file"
5179         cancel_lru_locks osc
5180
5181         # exceed atime_diff and access file
5182         sleep 10
5183         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5184                 error "can't udpate atime"
5185
5186         local atime_cli=$(stat -c %X $DIR/$tfile)
5187         echo "client atime: $atime_cli"
5188         # allow atime update to be written to device
5189         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5190         sleep 5
5191
5192         local ostdev=$(ostdevname 1)
5193         local fid=($(lfs getstripe -y $DIR/$tfile |
5194                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5195         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5196         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5197
5198         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5199         local atime_ost=$(do_facet ost1 "$cmd" |&
5200                           awk -F'[: ]' '/atime:/ { print $4 }')
5201         (( atime_cli == atime_ost )) ||
5202                 error "atime on client $atime_cli != ost $atime_ost"
5203 }
5204 run_test 39r "lazy atime update on OST"
5205
5206 test_39q() { # LU-8041
5207         local testdir=$DIR/$tdir
5208         mkdir -p $testdir
5209         multiop_bg_pause $testdir D_c || error "multiop failed"
5210         local multipid=$!
5211         cancel_lru_locks mdc
5212         kill -USR1 $multipid
5213         local atime=$(stat -c %X $testdir)
5214         [ "$atime" -ne 0 ] || error "atime is zero"
5215 }
5216 run_test 39q "close won't zero out atime"
5217
5218 test_40() {
5219         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5220         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5221                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5222         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5223                 error "$tfile is not 4096 bytes in size"
5224 }
5225 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5226
5227 test_41() {
5228         # bug 1553
5229         small_write $DIR/f41 18
5230 }
5231 run_test 41 "test small file write + fstat ====================="
5232
5233 count_ost_writes() {
5234         lctl get_param -n ${OSC}.*.stats |
5235                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5236                         END { printf("%0.0f", writes) }'
5237 }
5238
5239 # decent default
5240 WRITEBACK_SAVE=500
5241 DIRTY_RATIO_SAVE=40
5242 MAX_DIRTY_RATIO=50
5243 BG_DIRTY_RATIO_SAVE=10
5244 MAX_BG_DIRTY_RATIO=25
5245
5246 start_writeback() {
5247         trap 0
5248         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5249         # dirty_ratio, dirty_background_ratio
5250         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5251                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5252                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5253                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5254         else
5255                 # if file not here, we are a 2.4 kernel
5256                 kill -CONT `pidof kupdated`
5257         fi
5258 }
5259
5260 stop_writeback() {
5261         # setup the trap first, so someone cannot exit the test at the
5262         # exact wrong time and mess up a machine
5263         trap start_writeback EXIT
5264         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5265         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5266                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5267                 sysctl -w vm.dirty_writeback_centisecs=0
5268                 sysctl -w vm.dirty_writeback_centisecs=0
5269                 # save and increase /proc/sys/vm/dirty_ratio
5270                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5271                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5272                 # save and increase /proc/sys/vm/dirty_background_ratio
5273                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5274                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5275         else
5276                 # if file not here, we are a 2.4 kernel
5277                 kill -STOP `pidof kupdated`
5278         fi
5279 }
5280
5281 # ensure that all stripes have some grant before we test client-side cache
5282 setup_test42() {
5283         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5284                 dd if=/dev/zero of=$i bs=4k count=1
5285                 rm $i
5286         done
5287 }
5288
5289 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5290 # file truncation, and file removal.
5291 test_42a() {
5292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5293
5294         setup_test42
5295         cancel_lru_locks $OSC
5296         stop_writeback
5297         sync; sleep 1; sync # just to be safe
5298         BEFOREWRITES=`count_ost_writes`
5299         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5300         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5301         AFTERWRITES=`count_ost_writes`
5302         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5303                 error "$BEFOREWRITES < $AFTERWRITES"
5304         start_writeback
5305 }
5306 run_test 42a "ensure that we don't flush on close"
5307
5308 test_42b() {
5309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5310
5311         setup_test42
5312         cancel_lru_locks $OSC
5313         stop_writeback
5314         sync
5315         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5316         BEFOREWRITES=$(count_ost_writes)
5317         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5318         AFTERWRITES=$(count_ost_writes)
5319         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5320                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5321         fi
5322         BEFOREWRITES=$(count_ost_writes)
5323         sync || error "sync: $?"
5324         AFTERWRITES=$(count_ost_writes)
5325         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5326                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5327         fi
5328         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5329         start_writeback
5330         return 0
5331 }
5332 run_test 42b "test destroy of file with cached dirty data ======"
5333
5334 # if these tests just want to test the effect of truncation,
5335 # they have to be very careful.  consider:
5336 # - the first open gets a {0,EOF}PR lock
5337 # - the first write conflicts and gets a {0, count-1}PW
5338 # - the rest of the writes are under {count,EOF}PW
5339 # - the open for truncate tries to match a {0,EOF}PR
5340 #   for the filesize and cancels the PWs.
5341 # any number of fixes (don't get {0,EOF} on open, match
5342 # composite locks, do smarter file size management) fix
5343 # this, but for now we want these tests to verify that
5344 # the cancellation with truncate intent works, so we
5345 # start the file with a full-file pw lock to match against
5346 # until the truncate.
5347 trunc_test() {
5348         test=$1
5349         file=$DIR/$test
5350         offset=$2
5351         cancel_lru_locks $OSC
5352         stop_writeback
5353         # prime the file with 0,EOF PW to match
5354         touch $file
5355         $TRUNCATE $file 0
5356         sync; sync
5357         # now the real test..
5358         dd if=/dev/zero of=$file bs=1024 count=100
5359         BEFOREWRITES=`count_ost_writes`
5360         $TRUNCATE $file $offset
5361         cancel_lru_locks $OSC
5362         AFTERWRITES=`count_ost_writes`
5363         start_writeback
5364 }
5365
5366 test_42c() {
5367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5368
5369         trunc_test 42c 1024
5370         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5371                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5372         rm $file
5373 }
5374 run_test 42c "test partial truncate of file with cached dirty data"
5375
5376 test_42d() {
5377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5378
5379         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5380         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5381         $LCTL set_param debug=+cache
5382
5383         trunc_test 42d 0
5384         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5385                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5386         rm $file
5387 }
5388 run_test 42d "test complete truncate of file with cached dirty data"
5389
5390 test_42e() { # bug22074
5391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5392
5393         local TDIR=$DIR/${tdir}e
5394         local pages=16 # hardcoded 16 pages, don't change it.
5395         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5396         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5397         local max_dirty_mb
5398         local warmup_files
5399
5400         test_mkdir $DIR/${tdir}e
5401         $LFS setstripe -c 1 $TDIR
5402         createmany -o $TDIR/f $files
5403
5404         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5405
5406         # we assume that with $OSTCOUNT files, at least one of them will
5407         # be allocated on OST0.
5408         warmup_files=$((OSTCOUNT * max_dirty_mb))
5409         createmany -o $TDIR/w $warmup_files
5410
5411         # write a large amount of data into one file and sync, to get good
5412         # avail_grant number from OST.
5413         for ((i=0; i<$warmup_files; i++)); do
5414                 idx=$($LFS getstripe -i $TDIR/w$i)
5415                 [ $idx -ne 0 ] && continue
5416                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5417                 break
5418         done
5419         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5420         sync
5421         $LCTL get_param $proc_osc0/cur_dirty_bytes
5422         $LCTL get_param $proc_osc0/cur_grant_bytes
5423
5424         # create as much dirty pages as we can while not to trigger the actual
5425         # RPCs directly. but depends on the env, VFS may trigger flush during this
5426         # period, hopefully we are good.
5427         for ((i=0; i<$warmup_files; i++)); do
5428                 idx=$($LFS getstripe -i $TDIR/w$i)
5429                 [ $idx -ne 0 ] && continue
5430                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5431         done
5432         $LCTL get_param $proc_osc0/cur_dirty_bytes
5433         $LCTL get_param $proc_osc0/cur_grant_bytes
5434
5435         # perform the real test
5436         $LCTL set_param $proc_osc0/rpc_stats 0
5437         for ((;i<$files; i++)); do
5438                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5439                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5440         done
5441         sync
5442         $LCTL get_param $proc_osc0/rpc_stats
5443
5444         local percent=0
5445         local have_ppr=false
5446         $LCTL get_param $proc_osc0/rpc_stats |
5447                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5448                         # skip lines until we are at the RPC histogram data
5449                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5450                         $have_ppr || continue
5451
5452                         # we only want the percent stat for < 16 pages
5453                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5454
5455                         percent=$((percent + WPCT))
5456                         if [[ $percent -gt 15 ]]; then
5457                                 error "less than 16-pages write RPCs" \
5458                                       "$percent% > 15%"
5459                                 break
5460                         fi
5461                 done
5462         rm -rf $TDIR
5463 }
5464 run_test 42e "verify sub-RPC writes are not done synchronously"
5465
5466 test_43A() { # was test_43
5467         test_mkdir $DIR/$tdir
5468         cp -p /bin/ls $DIR/$tdir/$tfile
5469         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5470         pid=$!
5471         # give multiop a chance to open
5472         sleep 1
5473
5474         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5475         kill -USR1 $pid
5476         # Wait for multiop to exit
5477         wait $pid
5478 }
5479 run_test 43A "execution of file opened for write should return -ETXTBSY"
5480
5481 test_43a() {
5482         test_mkdir $DIR/$tdir
5483         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5484         $DIR/$tdir/sleep 60 &
5485         SLEEP_PID=$!
5486         # Make sure exec of $tdir/sleep wins race with truncate
5487         sleep 1
5488         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5489         kill $SLEEP_PID
5490 }
5491 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5492
5493 test_43b() {
5494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5495
5496         test_mkdir $DIR/$tdir
5497         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5498         $DIR/$tdir/sleep 60 &
5499         SLEEP_PID=$!
5500         # Make sure exec of $tdir/sleep wins race with truncate
5501         sleep 1
5502         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5503         kill $SLEEP_PID
5504 }
5505 run_test 43b "truncate of file being executed should return -ETXTBSY"
5506
5507 test_43c() {
5508         local testdir="$DIR/$tdir"
5509         test_mkdir $testdir
5510         cp $SHELL $testdir/
5511         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5512                 ( cd $testdir && md5sum -c )
5513 }
5514 run_test 43c "md5sum of copy into lustre"
5515
5516 test_44A() { # was test_44
5517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5518
5519         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5520         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5521 }
5522 run_test 44A "zero length read from a sparse stripe"
5523
5524 test_44a() {
5525         local nstripe=$($LFS getstripe -c -d $DIR)
5526         [ -z "$nstripe" ] && skip "can't get stripe info"
5527         [[ $nstripe -gt $OSTCOUNT ]] &&
5528                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5529
5530         local stride=$($LFS getstripe -S -d $DIR)
5531         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5532                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5533         fi
5534
5535         OFFSETS="0 $((stride/2)) $((stride-1))"
5536         for offset in $OFFSETS; do
5537                 for i in $(seq 0 $((nstripe-1))); do
5538                         local GLOBALOFFSETS=""
5539                         # size in Bytes
5540                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5541                         local myfn=$DIR/d44a-$size
5542                         echo "--------writing $myfn at $size"
5543                         ll_sparseness_write $myfn $size ||
5544                                 error "ll_sparseness_write"
5545                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5546                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5547                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5548
5549                         for j in $(seq 0 $((nstripe-1))); do
5550                                 # size in Bytes
5551                                 size=$((((j + $nstripe )*$stride + $offset)))
5552                                 ll_sparseness_write $myfn $size ||
5553                                         error "ll_sparseness_write"
5554                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5555                         done
5556                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5557                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5558                         rm -f $myfn
5559                 done
5560         done
5561 }
5562 run_test 44a "test sparse pwrite ==============================="
5563
5564 dirty_osc_total() {
5565         tot=0
5566         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5567                 tot=$(($tot + $d))
5568         done
5569         echo $tot
5570 }
5571 do_dirty_record() {
5572         before=`dirty_osc_total`
5573         echo executing "\"$*\""
5574         eval $*
5575         after=`dirty_osc_total`
5576         echo before $before, after $after
5577 }
5578 test_45() {
5579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5580
5581         f="$DIR/f45"
5582         # Obtain grants from OST if it supports it
5583         echo blah > ${f}_grant
5584         stop_writeback
5585         sync
5586         do_dirty_record "echo blah > $f"
5587         [[ $before -eq $after ]] && error "write wasn't cached"
5588         do_dirty_record "> $f"
5589         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5590         do_dirty_record "echo blah > $f"
5591         [[ $before -eq $after ]] && error "write wasn't cached"
5592         do_dirty_record "sync"
5593         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5594         do_dirty_record "echo blah > $f"
5595         [[ $before -eq $after ]] && error "write wasn't cached"
5596         do_dirty_record "cancel_lru_locks osc"
5597         [[ $before -gt $after ]] ||
5598                 error "lock cancellation didn't lower dirty count"
5599         start_writeback
5600 }
5601 run_test 45 "osc io page accounting ============================"
5602
5603 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5604 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5605 # objects offset and an assert hit when an rpc was built with 1023's mapped
5606 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5607 test_46() {
5608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5609
5610         f="$DIR/f46"
5611         stop_writeback
5612         sync
5613         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5614         sync
5615         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5616         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5617         sync
5618         start_writeback
5619 }
5620 run_test 46 "dirtying a previously written page ================"
5621
5622 # test_47 is removed "Device nodes check" is moved to test_28
5623
5624 test_48a() { # bug 2399
5625         [ "$mds1_FSTYPE" = "zfs" ] &&
5626         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5627                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5628
5629         test_mkdir $DIR/$tdir
5630         cd $DIR/$tdir
5631         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5632         test_mkdir $DIR/$tdir
5633         touch foo || error "'touch foo' failed after recreating cwd"
5634         test_mkdir bar
5635         touch .foo || error "'touch .foo' failed after recreating cwd"
5636         test_mkdir .bar
5637         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5638         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5639         cd . || error "'cd .' failed after recreating cwd"
5640         mkdir . && error "'mkdir .' worked after recreating cwd"
5641         rmdir . && error "'rmdir .' worked after recreating cwd"
5642         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5643         cd .. || error "'cd ..' failed after recreating cwd"
5644 }
5645 run_test 48a "Access renamed working dir (should return errors)="
5646
5647 test_48b() { # bug 2399
5648         rm -rf $DIR/$tdir
5649         test_mkdir $DIR/$tdir
5650         cd $DIR/$tdir
5651         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5652         touch foo && error "'touch foo' worked after removing cwd"
5653         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         ls . > /dev/null && error "'ls .' worked after removing cwd"
5657         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5658         mkdir . && error "'mkdir .' worked after removing cwd"
5659         rmdir . && error "'rmdir .' worked after removing cwd"
5660         ln -s . foo && error "'ln -s .' worked after removing cwd"
5661         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5662 }
5663 run_test 48b "Access removed working dir (should return errors)="
5664
5665 test_48c() { # 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 touch foo && error "touch foo worked after removing cwd"
5673         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5674         touch .foo && error "touch .foo worked after removing cwd"
5675         mkdir .foo && error "mkdir .foo worked after removing cwd"
5676         $TRACE ls . && error "'ls .' worked after removing cwd"
5677         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5678         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5679         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5680         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5681         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5682 }
5683 run_test 48c "Access removed working subdir (should return errors)"
5684
5685 test_48d() { # bug 2350
5686         #lctl set_param debug=-1
5687         #set -vx
5688         rm -rf $DIR/$tdir
5689         test_mkdir -p $DIR/$tdir/dir
5690         cd $DIR/$tdir/dir
5691         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5692         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5693         $TRACE touch foo && error "'touch foo' worked after removing parent"
5694         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5695         touch .foo && error "'touch .foo' worked after removing parent"
5696         mkdir .foo && error "mkdir .foo worked after removing parent"
5697         $TRACE ls . && error "'ls .' worked after removing parent"
5698         $TRACE ls .. && error "'ls ..' worked after removing parent"
5699         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5700         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5701         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5702         true
5703 }
5704 run_test 48d "Access removed parent subdir (should return errors)"
5705
5706 test_48e() { # bug 4134
5707         #lctl set_param debug=-1
5708         #set -vx
5709         rm -rf $DIR/$tdir
5710         test_mkdir -p $DIR/$tdir/dir
5711         cd $DIR/$tdir/dir
5712         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5713         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5714         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5715         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5716         # On a buggy kernel addition of "touch foo" after cd .. will
5717         # produce kernel oops in lookup_hash_it
5718         touch ../foo && error "'cd ..' worked after recreate parent"
5719         cd $DIR
5720         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5721 }
5722 run_test 48e "Access to recreated parent subdir (should return errors)"
5723
5724 test_48f() {
5725         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5726                 skip "need MDS >= 2.13.55"
5727         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5728         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5729                 skip "needs different host for mdt1 mdt2"
5730         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5731
5732         $LFS mkdir -i0 $DIR/$tdir
5733         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5734
5735         for d in sub1 sub2 sub3; do
5736                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5737                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5738                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5739         done
5740
5741         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5742 }
5743 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5744
5745 test_49() { # LU-1030
5746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5747         remote_ost_nodsh && skip "remote OST with nodsh"
5748
5749         # get ost1 size - $FSNAME-OST0000
5750         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5751                 awk '{ print $4 }')
5752         # write 800M at maximum
5753         [[ $ost1_size -lt 2 ]] && ost1_size=2
5754         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5755
5756         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5757         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5758         local dd_pid=$!
5759
5760         # change max_pages_per_rpc while writing the file
5761         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5762         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5763         # loop until dd process exits
5764         while ps ax -opid | grep -wq $dd_pid; do
5765                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5766                 sleep $((RANDOM % 5 + 1))
5767         done
5768         # restore original max_pages_per_rpc
5769         $LCTL set_param $osc1_mppc=$orig_mppc
5770         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5771 }
5772 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5773
5774 test_50() {
5775         # bug 1485
5776         test_mkdir $DIR/$tdir
5777         cd $DIR/$tdir
5778         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5779 }
5780 run_test 50 "special situations: /proc symlinks  ==============="
5781
5782 test_51a() {    # was test_51
5783         # bug 1516 - create an empty entry right after ".." then split dir
5784         test_mkdir -c1 $DIR/$tdir
5785         touch $DIR/$tdir/foo
5786         $MCREATE $DIR/$tdir/bar
5787         rm $DIR/$tdir/foo
5788         createmany -m $DIR/$tdir/longfile 201
5789         FNUM=202
5790         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5791                 $MCREATE $DIR/$tdir/longfile$FNUM
5792                 FNUM=$(($FNUM + 1))
5793                 echo -n "+"
5794         done
5795         echo
5796         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5797 }
5798 run_test 51a "special situations: split htree with empty entry =="
5799
5800 cleanup_print_lfs_df () {
5801         trap 0
5802         $LFS df
5803         $LFS df -i
5804 }
5805
5806 test_51b() {
5807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5808
5809         local dir=$DIR/$tdir
5810         local nrdirs=$((65536 + 100))
5811
5812         # cleanup the directory
5813         rm -fr $dir
5814
5815         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5816
5817         $LFS df
5818         $LFS df -i
5819         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5820         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5821         [[ $numfree -lt $nrdirs ]] &&
5822                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5823
5824         # need to check free space for the directories as well
5825         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5826         numfree=$(( blkfree / $(fs_inode_ksize) ))
5827         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5828
5829         trap cleanup_print_lfs_df EXIT
5830
5831         # create files
5832         createmany -d $dir/d $nrdirs || {
5833                 unlinkmany $dir/d $nrdirs
5834                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5835         }
5836
5837         # really created :
5838         nrdirs=$(ls -U $dir | wc -l)
5839
5840         # unlink all but 100 subdirectories, then check it still works
5841         local left=100
5842         local delete=$((nrdirs - left))
5843
5844         $LFS df
5845         $LFS df -i
5846
5847         # for ldiskfs the nlink count should be 1, but this is OSD specific
5848         # and so this is listed for informational purposes only
5849         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5850         unlinkmany -d $dir/d $delete ||
5851                 error "unlink of first $delete subdirs failed"
5852
5853         echo "nlink between: $(stat -c %h $dir)"
5854         local found=$(ls -U $dir | wc -l)
5855         [ $found -ne $left ] &&
5856                 error "can't find subdirs: found only $found, expected $left"
5857
5858         unlinkmany -d $dir/d $delete $left ||
5859                 error "unlink of second $left subdirs failed"
5860         # regardless of whether the backing filesystem tracks nlink accurately
5861         # or not, the nlink count shouldn't be more than "." and ".." here
5862         local after=$(stat -c %h $dir)
5863         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5864                 echo "nlink after: $after"
5865
5866         cleanup_print_lfs_df
5867 }
5868 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5869
5870 test_51d_sub() {
5871         local stripecount=$1
5872         local nfiles=$2
5873
5874         log "create files with stripecount=$stripecount"
5875         $LFS setstripe -C $stripecount $DIR/$tdir
5876         createmany -o $DIR/$tdir/t- $nfiles
5877         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5878         for ((n = 0; n < $OSTCOUNT; n++)); do
5879                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5880                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5881                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5882                             '($1 == '$n') { objs += 1 } \
5883                             END { printf("%0.0f", objs) }')
5884                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5885         done
5886         unlinkmany $DIR/$tdir/t- $nfiles
5887         rm  -f $TMP/$tfile
5888
5889         local nlast
5890         local min=4
5891         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5892
5893         # For some combinations of stripecount and OSTCOUNT current code
5894         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5895         # than others. Rather than skipping this test entirely, check that
5896         # and keep testing to ensure imbalance does not get worse. LU-15282
5897         (( (OSTCOUNT == 6 && stripecount == 4) ||
5898            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5899            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5900         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5901                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5902                         { $LFS df && $LFS df -i &&
5903                         error "stripecount=$stripecount: " \
5904                               "OST $n has fewer objects vs. OST $nlast " \
5905                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5906                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5907                         { $LFS df && $LFS df -i &&
5908                         error "stripecount=$stripecount: " \
5909                               "OST $n has more objects vs. OST $nlast " \
5910                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5911
5912                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5913                         { $LFS df && $LFS df -i &&
5914                         error "stripecount=$stripecount: " \
5915                               "OST $n has fewer #0 objects vs. OST $nlast " \
5916                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5917                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5918                         { $LFS df && $LFS df -i &&
5919                         error "stripecount=$stripecount: " \
5920                               "OST $n has more #0 objects vs. OST $nlast " \
5921                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5922         done
5923 }
5924
5925 test_51d() {
5926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5927         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5928
5929         local stripecount
5930         local per_ost=100
5931         local nfiles=$((per_ost * OSTCOUNT))
5932         local mdts=$(comma_list $(mdts_nodes))
5933         local param="osp.*.create_count"
5934         local qos_old=$(do_facet mds1 \
5935                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5936
5937         do_nodes $mdts \
5938                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5939         stack_trap "do_nodes $mdts \
5940                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5941
5942         test_mkdir $DIR/$tdir
5943         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5944         (( dirstripes > 0 )) || dirstripes=1
5945
5946         # Ensure enough OST objects precreated for tests to pass without
5947         # running out of objects.  This is an LOV r-r OST algorithm test,
5948         # not an OST object precreation test.
5949         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5950         (( old >= nfiles )) ||
5951         {
5952                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5953
5954                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5955                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5956
5957                 # trigger precreation from all MDTs for all OSTs
5958                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5959                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5960                 done
5961         }
5962
5963         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5964                 sleep 8  # allow object precreation to catch up
5965                 test_51d_sub $stripecount $nfiles
5966         done
5967 }
5968 run_test 51d "check LOV round-robin OST object distribution"
5969
5970 test_51e() {
5971         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5972                 skip_env "ldiskfs only test"
5973         fi
5974
5975         test_mkdir -c1 $DIR/$tdir
5976         test_mkdir -c1 $DIR/$tdir/d0
5977
5978         touch $DIR/$tdir/d0/foo
5979         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5980                 error "file exceed 65000 nlink limit!"
5981         unlinkmany $DIR/$tdir/d0/f- 65001
5982         return 0
5983 }
5984 run_test 51e "check file nlink limit"
5985
5986 test_51f() {
5987         test_mkdir $DIR/$tdir
5988
5989         local max=100000
5990         local ulimit_old=$(ulimit -n)
5991         local spare=20 # number of spare fd's for scripts/libraries, etc.
5992         local mdt=$($LFS getstripe -m $DIR/$tdir)
5993         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5994
5995         echo "MDT$mdt numfree=$numfree, max=$max"
5996         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5997         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5998                 while ! ulimit -n $((numfree + spare)); do
5999                         numfree=$((numfree * 3 / 4))
6000                 done
6001                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6002         else
6003                 echo "left ulimit at $ulimit_old"
6004         fi
6005
6006         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6007                 unlinkmany $DIR/$tdir/f $numfree
6008                 error "create+open $numfree files in $DIR/$tdir failed"
6009         }
6010         ulimit -n $ulimit_old
6011
6012         # if createmany exits at 120s there will be fewer than $numfree files
6013         unlinkmany $DIR/$tdir/f $numfree || true
6014 }
6015 run_test 51f "check many open files limit"
6016
6017 test_52a() {
6018         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6019         test_mkdir $DIR/$tdir
6020         touch $DIR/$tdir/foo
6021         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6022         echo bar >> $DIR/$tdir/foo || error "append bar failed"
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 "append foo failed"
6028         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6029         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6030                                                      error "lsattr"
6031         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6032         cp -r $DIR/$tdir $TMP/
6033         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6034 }
6035 run_test 52a "append-only flag test (should return errors)"
6036
6037 test_52b() {
6038         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6039         test_mkdir $DIR/$tdir
6040         touch $DIR/$tdir/foo
6041         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6042         cat test > $DIR/$tdir/foo && error "cat test worked"
6043         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6044         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6045         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6046                                         error "link worked"
6047         echo foo >> $DIR/$tdir/foo && error "echo worked"
6048         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6049         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6050         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6051         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6052                                                         error "lsattr"
6053         chattr -i $DIR/$tdir/foo || error "chattr failed"
6054
6055         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6056 }
6057 run_test 52b "immutable flag test (should return errors) ======="
6058
6059 test_53() {
6060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6061         remote_mds_nodsh && skip "remote MDS with nodsh"
6062         remote_ost_nodsh && skip "remote OST with nodsh"
6063
6064         local param
6065         local param_seq
6066         local ostname
6067         local mds_last
6068         local mds_last_seq
6069         local ost_last
6070         local ost_last_seq
6071         local ost_last_id
6072         local ostnum
6073         local node
6074         local found=false
6075         local support_last_seq=true
6076
6077         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6078                 support_last_seq=false
6079
6080         # only test MDT0000
6081         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6082         local value
6083         for value in $(do_facet $SINGLEMDS \
6084                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6085                 param=$(echo ${value[0]} | cut -d "=" -f1)
6086                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6087
6088                 if $support_last_seq; then
6089                         param_seq=$(echo $param |
6090                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6091                         mds_last_seq=$(do_facet $SINGLEMDS \
6092                                        $LCTL get_param -n $param_seq)
6093                 fi
6094                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6095
6096                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6097                 node=$(facet_active_host ost$((ostnum+1)))
6098                 param="obdfilter.$ostname.last_id"
6099                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6100                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6101                         ost_last_id=$ost_last
6102
6103                         if $support_last_seq; then
6104                                 ost_last_id=$(echo $ost_last |
6105                                               awk -F':' '{print $2}' |
6106                                               sed -e "s/^0x//g")
6107                                 ost_last_seq=$(echo $ost_last |
6108                                                awk -F':' '{print $1}')
6109                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6110                         fi
6111
6112                         if [[ $ost_last_id != $mds_last ]]; then
6113                                 error "$ost_last_id != $mds_last"
6114                         else
6115                                 found=true
6116                                 break
6117                         fi
6118                 done
6119         done
6120         $found || error "can not match last_seq/last_id for $mdtosc"
6121         return 0
6122 }
6123 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6124
6125 test_54a() {
6126         perl -MSocket -e ';' || skip "no Socket perl module installed"
6127
6128         $SOCKETSERVER $DIR/socket ||
6129                 error "$SOCKETSERVER $DIR/socket failed: $?"
6130         $SOCKETCLIENT $DIR/socket ||
6131                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6132         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6133 }
6134 run_test 54a "unix domain socket test =========================="
6135
6136 test_54b() {
6137         f="$DIR/f54b"
6138         mknod $f c 1 3
6139         chmod 0666 $f
6140         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6141 }
6142 run_test 54b "char device works in lustre ======================"
6143
6144 find_loop_dev() {
6145         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6146         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6147         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6148
6149         for i in $(seq 3 7); do
6150                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6151                 LOOPDEV=$LOOPBASE$i
6152                 LOOPNUM=$i
6153                 break
6154         done
6155 }
6156
6157 cleanup_54c() {
6158         local rc=0
6159         loopdev="$DIR/loop54c"
6160
6161         trap 0
6162         $UMOUNT $DIR/$tdir || rc=$?
6163         losetup -d $loopdev || true
6164         losetup -d $LOOPDEV || true
6165         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6166         return $rc
6167 }
6168
6169 test_54c() {
6170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6171
6172         loopdev="$DIR/loop54c"
6173
6174         find_loop_dev
6175         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6176         trap cleanup_54c EXIT
6177         mknod $loopdev b 7 $LOOPNUM
6178         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6179         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6180         losetup $loopdev $DIR/$tfile ||
6181                 error "can't set up $loopdev for $DIR/$tfile"
6182         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6183         test_mkdir $DIR/$tdir
6184         mount -t ext2 $loopdev $DIR/$tdir ||
6185                 error "error mounting $loopdev on $DIR/$tdir"
6186         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6187                 error "dd write"
6188         df $DIR/$tdir
6189         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6190                 error "dd read"
6191         cleanup_54c
6192 }
6193 run_test 54c "block device works in lustre ====================="
6194
6195 test_54d() {
6196         local pipe="$DIR/$tfile.pipe"
6197         local string="aaaaaa"
6198
6199         mknod $pipe p
6200         echo -n "$string" > $pipe &
6201         local result=$(cat $pipe)
6202         [[ "$result" == "$string" ]] || error "$result != $string"
6203 }
6204 run_test 54d "fifo device works in lustre ======================"
6205
6206 test_54e() {
6207         f="$DIR/f54e"
6208         string="aaaaaa"
6209         cp -aL /dev/console $f
6210         echo $string > $f || error "echo $string to $f failed"
6211 }
6212 run_test 54e "console/tty device works in lustre ======================"
6213
6214 test_56a() {
6215         local numfiles=3
6216         local numdirs=2
6217         local dir=$DIR/$tdir
6218
6219         rm -rf $dir
6220         test_mkdir -p $dir/dir
6221         for i in $(seq $numfiles); do
6222                 touch $dir/file$i
6223                 touch $dir/dir/file$i
6224         done
6225
6226         local numcomp=$($LFS getstripe --component-count $dir)
6227
6228         [[ $numcomp == 0 ]] && numcomp=1
6229
6230         # test lfs getstripe with --recursive
6231         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6232
6233         [[ $filenum -eq $((numfiles * 2)) ]] ||
6234                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6235         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6236         [[ $filenum -eq $numfiles ]] ||
6237                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6238         echo "$LFS getstripe showed obdidx or l_ost_idx"
6239
6240         # test lfs getstripe with file instead of dir
6241         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6242         [[ $filenum -eq 1 ]] ||
6243                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6244         echo "$LFS getstripe file1 passed"
6245
6246         #test lfs getstripe with --verbose
6247         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6248         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6249                 error "$LFS getstripe --verbose $dir: "\
6250                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6251         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6252                 error "$LFS getstripe $dir: showed lmm_magic"
6253
6254         #test lfs getstripe with -v prints lmm_fid
6255         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6256         local countfids=$((numdirs + numfiles * numcomp))
6257         [[ $filenum -eq $countfids ]] ||
6258                 error "$LFS getstripe -v $dir: "\
6259                       "got $filenum want $countfids lmm_fid"
6260         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6261                 error "$LFS getstripe $dir: showed lmm_fid by default"
6262         echo "$LFS getstripe --verbose passed"
6263
6264         #check for FID information
6265         local fid1=$($LFS getstripe --fid $dir/file1)
6266         local fid2=$($LFS getstripe --verbose $dir/file1 |
6267                      awk '/lmm_fid: / { print $2; exit; }')
6268         local fid3=$($LFS path2fid $dir/file1)
6269
6270         [ "$fid1" != "$fid2" ] &&
6271                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6272         [ "$fid1" != "$fid3" ] &&
6273                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6274         echo "$LFS getstripe --fid passed"
6275
6276         #test lfs getstripe with --obd
6277         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6278                 error "$LFS getstripe --obd wrong_uuid: should return error"
6279
6280         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6281
6282         local ostidx=1
6283         local obduuid=$(ostuuid_from_index $ostidx)
6284         local found=$($LFS getstripe -r --obd $obduuid $dir |
6285                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6286
6287         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6288         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6289                 ((filenum--))
6290         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6291                 ((filenum--))
6292
6293         [[ $found -eq $filenum ]] ||
6294                 error "$LFS getstripe --obd: found $found expect $filenum"
6295         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6296                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6297                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6298                 error "$LFS getstripe --obd: should not show file on other obd"
6299         echo "$LFS getstripe --obd passed"
6300 }
6301 run_test 56a "check $LFS getstripe"
6302
6303 test_56b() {
6304         local dir=$DIR/$tdir
6305         local numdirs=3
6306
6307         test_mkdir $dir
6308         for i in $(seq $numdirs); do
6309                 test_mkdir $dir/dir$i
6310         done
6311
6312         # test lfs getdirstripe default mode is non-recursion, which is
6313         # different from lfs getstripe
6314         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6315
6316         [[ $dircnt -eq 1 ]] ||
6317                 error "$LFS getdirstripe: found $dircnt, not 1"
6318         dircnt=$($LFS getdirstripe --recursive $dir |
6319                 grep -c lmv_stripe_count)
6320         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6321                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6322 }
6323 run_test 56b "check $LFS getdirstripe"
6324
6325 test_56c() {
6326         remote_ost_nodsh && skip "remote OST with nodsh"
6327
6328         local ost_idx=0
6329         local ost_name=$(ostname_from_index $ost_idx)
6330         local old_status=$(ost_dev_status $ost_idx)
6331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6332
6333         [[ -z "$old_status" ]] ||
6334                 skip_env "OST $ost_name is in $old_status status"
6335
6336         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6337         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6338                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6339         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6340                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6341                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6342         fi
6343
6344         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6345                 error "$LFS df -v showing inactive devices"
6346         sleep_maxage
6347
6348         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6349
6350         [[ "$new_status" =~ "D" ]] ||
6351                 error "$ost_name status is '$new_status', missing 'D'"
6352         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6353                 [[ "$new_status" =~ "N" ]] ||
6354                         error "$ost_name status is '$new_status', missing 'N'"
6355         fi
6356         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6357                 [[ "$new_status" =~ "f" ]] ||
6358                         error "$ost_name status is '$new_status', missing 'f'"
6359         fi
6360
6361         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6362         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6363                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6364         [[ -z "$p" ]] && restore_lustre_params < $p || true
6365         sleep_maxage
6366
6367         new_status=$(ost_dev_status $ost_idx)
6368         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6369                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6370         # can't check 'f' as devices may actually be on flash
6371 }
6372 run_test 56c "check 'lfs df' showing device status"
6373
6374 test_56d() {
6375         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6376         local osts=$($LFS df -v $MOUNT | grep -c OST)
6377
6378         $LFS df $MOUNT
6379
6380         (( mdts == MDSCOUNT )) ||
6381                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6382         (( osts == OSTCOUNT )) ||
6383                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6384 }
6385 run_test 56d "'lfs df -v' prints only configured devices"
6386
6387 test_56e() {
6388         err_enoent=2 # No such file or directory
6389         err_eopnotsupp=95 # Operation not supported
6390
6391         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6392         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6393
6394         # Check for handling of path not exists
6395         output=$($LFS df $enoent_mnt 2>&1)
6396         ret=$?
6397
6398         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6399         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6400                 error "expect failure $err_enoent, not $ret"
6401
6402         # Check for handling of non-Lustre FS
6403         output=$($LFS df $notsup_mnt)
6404         ret=$?
6405
6406         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6407         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6408                 error "expect success $err_eopnotsupp, not $ret"
6409
6410         # Check for multiple LustreFS argument
6411         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6412         ret=$?
6413
6414         [[ $output -eq 3 && $ret -eq 0 ]] ||
6415                 error "expect success 3, not $output, rc = $ret"
6416
6417         # Check for correct non-Lustre FS handling among multiple
6418         # LustreFS argument
6419         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6420                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6421         ret=$?
6422
6423         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6424                 error "expect success 2, not $output, rc = $ret"
6425 }
6426 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6427
6428 NUMFILES=3
6429 NUMDIRS=3
6430 setup_56() {
6431         local local_tdir="$1"
6432         local local_numfiles="$2"
6433         local local_numdirs="$3"
6434         local dir_params="$4"
6435         local dir_stripe_params="$5"
6436
6437         if [ ! -d "$local_tdir" ] ; then
6438                 test_mkdir -p $dir_stripe_params $local_tdir
6439                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6440                 for i in $(seq $local_numfiles) ; do
6441                         touch $local_tdir/file$i
6442                 done
6443                 for i in $(seq $local_numdirs) ; do
6444                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6445                         for j in $(seq $local_numfiles) ; do
6446                                 touch $local_tdir/dir$i/file$j
6447                         done
6448                 done
6449         fi
6450 }
6451
6452 setup_56_special() {
6453         local local_tdir=$1
6454         local local_numfiles=$2
6455         local local_numdirs=$3
6456
6457         setup_56 $local_tdir $local_numfiles $local_numdirs
6458
6459         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6460                 for i in $(seq $local_numfiles) ; do
6461                         mknod $local_tdir/loop${i}b b 7 $i
6462                         mknod $local_tdir/null${i}c c 1 3
6463                         ln -s $local_tdir/file1 $local_tdir/link${i}
6464                 done
6465                 for i in $(seq $local_numdirs) ; do
6466                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6467                         mknod $local_tdir/dir$i/null${i}c c 1 3
6468                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6469                 done
6470         fi
6471 }
6472
6473 test_56g() {
6474         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6475         local expected=$(($NUMDIRS + 2))
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS
6478
6479         # test lfs find with -name
6480         for i in $(seq $NUMFILES) ; do
6481                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6482
6483                 [ $nums -eq $expected ] ||
6484                         error "lfs find -name '*$i' $dir wrong: "\
6485                               "found $nums, expected $expected"
6486         done
6487 }
6488 run_test 56g "check lfs find -name"
6489
6490 test_56h() {
6491         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6492         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6493
6494         setup_56 $dir $NUMFILES $NUMDIRS
6495
6496         # test lfs find with ! -name
6497         for i in $(seq $NUMFILES) ; do
6498                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6499
6500                 [ $nums -eq $expected ] ||
6501                         error "lfs find ! -name '*$i' $dir wrong: "\
6502                               "found $nums, expected $expected"
6503         done
6504 }
6505 run_test 56h "check lfs find ! -name"
6506
6507 test_56i() {
6508         local dir=$DIR/$tdir
6509
6510         test_mkdir $dir
6511
6512         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6513         local out=$($cmd)
6514
6515         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6516 }
6517 run_test 56i "check 'lfs find -ost UUID' skips directories"
6518
6519 test_56j() {
6520         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6521
6522         setup_56_special $dir $NUMFILES $NUMDIRS
6523
6524         local expected=$((NUMDIRS + 1))
6525         local cmd="$LFS find -type d $dir"
6526         local nums=$($cmd | wc -l)
6527
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530 }
6531 run_test 56j "check lfs find -type d"
6532
6533 test_56k() {
6534         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6535
6536         setup_56_special $dir $NUMFILES $NUMDIRS
6537
6538         local expected=$(((NUMDIRS + 1) * NUMFILES))
6539         local cmd="$LFS find -type f $dir"
6540         local nums=$($cmd | wc -l)
6541
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544 }
6545 run_test 56k "check lfs find -type f"
6546
6547 test_56l() {
6548         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6549
6550         setup_56_special $dir $NUMFILES $NUMDIRS
6551
6552         local expected=$((NUMDIRS + NUMFILES))
6553         local cmd="$LFS find -type b $dir"
6554         local nums=$($cmd | wc -l)
6555
6556         [ $nums -eq $expected ] ||
6557                 error "'$cmd' wrong: found $nums, expected $expected"
6558 }
6559 run_test 56l "check lfs find -type b"
6560
6561 test_56m() {
6562         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6563
6564         setup_56_special $dir $NUMFILES $NUMDIRS
6565
6566         local expected=$((NUMDIRS + NUMFILES))
6567         local cmd="$LFS find -type c $dir"
6568         local nums=$($cmd | wc -l)
6569         [ $nums -eq $expected ] ||
6570                 error "'$cmd' wrong: found $nums, expected $expected"
6571 }
6572 run_test 56m "check lfs find -type c"
6573
6574 test_56n() {
6575         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6576         setup_56_special $dir $NUMFILES $NUMDIRS
6577
6578         local expected=$((NUMDIRS + NUMFILES))
6579         local cmd="$LFS find -type l $dir"
6580         local nums=$($cmd | wc -l)
6581
6582         [ $nums -eq $expected ] ||
6583                 error "'$cmd' wrong: found $nums, expected $expected"
6584 }
6585 run_test 56n "check lfs find -type l"
6586
6587 test_56o() {
6588         local dir=$DIR/$tdir
6589
6590         setup_56 $dir $NUMFILES $NUMDIRS
6591         utime $dir/file1 > /dev/null || error "utime (1)"
6592         utime $dir/file2 > /dev/null || error "utime (2)"
6593         utime $dir/dir1 > /dev/null || error "utime (3)"
6594         utime $dir/dir2 > /dev/null || error "utime (4)"
6595         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6596         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6597
6598         local expected=4
6599         local nums=$($LFS find -mtime +0 $dir | wc -l)
6600
6601         [ $nums -eq $expected ] ||
6602                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6603
6604         expected=12
6605         cmd="$LFS find -mtime 0 $dir"
6606         nums=$($cmd | wc -l)
6607         [ $nums -eq $expected ] ||
6608                 error "'$cmd' wrong: found $nums, expected $expected"
6609 }
6610 run_test 56o "check lfs find -mtime for old files"
6611
6612 test_56ob() {
6613         local dir=$DIR/$tdir
6614         local expected=1
6615         local count=0
6616
6617         # just to make sure there is something that won't be found
6618         test_mkdir $dir
6619         touch $dir/$tfile.now
6620
6621         for age in year week day hour min; do
6622                 count=$((count + 1))
6623
6624                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6625                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6626                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6627
6628                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6629                 local nums=$($cmd | wc -l)
6630                 [ $nums -eq $expected ] ||
6631                         error "'$cmd' wrong: found $nums, expected $expected"
6632
6633                 cmd="$LFS find $dir -atime $count${age:0:1}"
6634                 nums=$($cmd | wc -l)
6635                 [ $nums -eq $expected ] ||
6636                         error "'$cmd' wrong: found $nums, expected $expected"
6637         done
6638
6639         sleep 2
6640         cmd="$LFS find $dir -ctime +1s -type f"
6641         nums=$($cmd | wc -l)
6642         (( $nums == $count * 2 + 1)) ||
6643                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6644 }
6645 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6646
6647 test_newerXY_base() {
6648         local x=$1
6649         local y=$2
6650         local dir=$DIR/$tdir
6651         local ref
6652         local negref
6653
6654         if [ $y == "t" ]; then
6655                 if [ $x == "b" ]; then
6656                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6657                 else
6658                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6659                 fi
6660         else
6661                 ref=$DIR/$tfile.newer.$x$y
6662                 touch $ref || error "touch $ref failed"
6663         fi
6664
6665         echo "before = $ref"
6666         sleep 2
6667         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6668         sleep 2
6669         if [ $y == "t" ]; then
6670                 if [ $x == "b" ]; then
6671                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6672                 else
6673                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6674                 fi
6675         else
6676                 negref=$DIR/$tfile.negnewer.$x$y
6677                 touch $negref || error "touch $negref failed"
6678         fi
6679
6680         echo "after = $negref"
6681         local cmd="$LFS find $dir -newer$x$y $ref"
6682         local nums=$(eval $cmd | wc -l)
6683         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6684
6685         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6686                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6687
6688         cmd="$LFS find $dir ! -newer$x$y $negref"
6689         nums=$(eval $cmd | wc -l)
6690         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6691                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6692
6693         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6694         nums=$(eval $cmd | wc -l)
6695         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6696                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6697
6698         rm -rf $DIR/*
6699 }
6700
6701 test_56oc() {
6702         test_newerXY_base "a" "a"
6703         test_newerXY_base "a" "m"
6704         test_newerXY_base "a" "c"
6705         test_newerXY_base "m" "a"
6706         test_newerXY_base "m" "m"
6707         test_newerXY_base "m" "c"
6708         test_newerXY_base "c" "a"
6709         test_newerXY_base "c" "m"
6710         test_newerXY_base "c" "c"
6711
6712         test_newerXY_base "a" "t"
6713         test_newerXY_base "m" "t"
6714         test_newerXY_base "c" "t"
6715
6716         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6717            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6718                 ! btime_supported && echo "btime unsupported" && return 0
6719
6720         test_newerXY_base "b" "b"
6721         test_newerXY_base "b" "t"
6722 }
6723 run_test 56oc "check lfs find -newerXY work"
6724
6725 btime_supported() {
6726         local dir=$DIR/$tdir
6727         local rc
6728
6729         mkdir -p $dir
6730         touch $dir/$tfile
6731         $LFS find $dir -btime -1d -type f
6732         rc=$?
6733         rm -rf $dir
6734         return $rc
6735 }
6736
6737 test_56od() {
6738         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6739                 ! btime_supported && skip "btime unsupported on MDS"
6740
6741         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6742                 ! btime_supported && skip "btime unsupported on clients"
6743
6744         local dir=$DIR/$tdir
6745         local ref=$DIR/$tfile.ref
6746         local negref=$DIR/$tfile.negref
6747
6748         mkdir $dir || error "mkdir $dir failed"
6749         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6750         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6751         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6752         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6753         touch $ref || error "touch $ref failed"
6754         # sleep 3 seconds at least
6755         sleep 3
6756
6757         local before=$(do_facet mds1 date +%s)
6758         local skew=$(($(date +%s) - before + 1))
6759
6760         if (( skew < 0 && skew > -5 )); then
6761                 sleep $((0 - skew + 1))
6762                 skew=0
6763         fi
6764
6765         # Set the dir stripe params to limit files all on MDT0,
6766         # otherwise we need to calc the max clock skew between
6767         # the client and MDTs.
6768         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6769         sleep 2
6770         touch $negref || error "touch $negref failed"
6771
6772         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6773         local nums=$($cmd | wc -l)
6774         local expected=$(((NUMFILES + 1) * NUMDIRS))
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778
6779         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6780         nums=$($cmd | wc -l)
6781         expected=$((NUMFILES + 1))
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784
6785         [ $skew -lt 0 ] && return
6786
6787         local after=$(do_facet mds1 date +%s)
6788         local age=$((after - before + 1 + skew))
6789
6790         cmd="$LFS find $dir -btime -${age}s -type f"
6791         nums=$($cmd | wc -l)
6792         expected=$(((NUMFILES + 1) * NUMDIRS))
6793
6794         echo "Clock skew between client and server: $skew, age:$age"
6795         [ $nums -eq $expected ] ||
6796                 error "'$cmd' wrong: found $nums, expected $expected"
6797
6798         expected=$(($NUMDIRS + 1))
6799         cmd="$LFS find $dir -btime -${age}s -type d"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803         rm -f $ref $negref || error "Failed to remove $ref $negref"
6804 }
6805 run_test 56od "check lfs find -btime with units"
6806
6807 test_56p() {
6808         [ $RUNAS_ID -eq $UID ] &&
6809                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6810
6811         local dir=$DIR/$tdir
6812
6813         setup_56 $dir $NUMFILES $NUMDIRS
6814         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6815
6816         local expected=$NUMFILES
6817         local cmd="$LFS find -uid $RUNAS_ID $dir"
6818         local nums=$($cmd | wc -l)
6819
6820         [ $nums -eq $expected ] ||
6821                 error "'$cmd' wrong: found $nums, expected $expected"
6822
6823         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6824         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6825         nums=$($cmd | wc -l)
6826         [ $nums -eq $expected ] ||
6827                 error "'$cmd' wrong: found $nums, expected $expected"
6828 }
6829 run_test 56p "check lfs find -uid and ! -uid"
6830
6831 test_56q() {
6832         [ $RUNAS_ID -eq $UID ] &&
6833                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6834
6835         local dir=$DIR/$tdir
6836
6837         setup_56 $dir $NUMFILES $NUMDIRS
6838         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6839
6840         local expected=$NUMFILES
6841         local cmd="$LFS find -gid $RUNAS_GID $dir"
6842         local nums=$($cmd | wc -l)
6843
6844         [ $nums -eq $expected ] ||
6845                 error "'$cmd' wrong: found $nums, expected $expected"
6846
6847         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6848         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6849         nums=$($cmd | wc -l)
6850         [ $nums -eq $expected ] ||
6851                 error "'$cmd' wrong: found $nums, expected $expected"
6852 }
6853 run_test 56q "check lfs find -gid and ! -gid"
6854
6855 test_56r() {
6856         local dir=$DIR/$tdir
6857
6858         setup_56 $dir $NUMFILES $NUMDIRS
6859
6860         local expected=12
6861         local cmd="$LFS find -size 0 -type f -lazy $dir"
6862         local nums=$($cmd | wc -l)
6863
6864         [ $nums -eq $expected ] ||
6865                 error "'$cmd' wrong: found $nums, expected $expected"
6866         cmd="$LFS find -size 0 -type f $dir"
6867         nums=$($cmd | wc -l)
6868         [ $nums -eq $expected ] ||
6869                 error "'$cmd' wrong: found $nums, expected $expected"
6870
6871         expected=0
6872         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6873         nums=$($cmd | wc -l)
6874         [ $nums -eq $expected ] ||
6875                 error "'$cmd' wrong: found $nums, expected $expected"
6876         cmd="$LFS find ! -size 0 -type f $dir"
6877         nums=$($cmd | wc -l)
6878         [ $nums -eq $expected ] ||
6879                 error "'$cmd' wrong: found $nums, expected $expected"
6880
6881         echo "test" > $dir/$tfile
6882         echo "test2" > $dir/$tfile.2 && sync
6883         expected=1
6884         cmd="$LFS find -size 5 -type f -lazy $dir"
6885         nums=$($cmd | wc -l)
6886         [ $nums -eq $expected ] ||
6887                 error "'$cmd' wrong: found $nums, expected $expected"
6888         cmd="$LFS find -size 5 -type f $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892
6893         expected=1
6894         cmd="$LFS find -size +5 -type f -lazy $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898         cmd="$LFS find -size +5 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] ||
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902
6903         expected=2
6904         cmd="$LFS find -size +0 -type f -lazy $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] ||
6907                 error "'$cmd' wrong: found $nums, expected $expected"
6908         cmd="$LFS find -size +0 -type f $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912
6913         expected=2
6914         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6915         nums=$($cmd | wc -l)
6916         [ $nums -eq $expected ] ||
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918         cmd="$LFS find ! -size -5 -type f $dir"
6919         nums=$($cmd | wc -l)
6920         [ $nums -eq $expected ] ||
6921                 error "'$cmd' wrong: found $nums, expected $expected"
6922
6923         expected=12
6924         cmd="$LFS find -size -5 -type f -lazy $dir"
6925         nums=$($cmd | wc -l)
6926         [ $nums -eq $expected ] ||
6927                 error "'$cmd' wrong: found $nums, expected $expected"
6928         cmd="$LFS find -size -5 -type f $dir"
6929         nums=$($cmd | wc -l)
6930         [ $nums -eq $expected ] ||
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932 }
6933 run_test 56r "check lfs find -size works"
6934
6935 test_56ra_sub() {
6936         local expected=$1
6937         local glimpses=$2
6938         local cmd="$3"
6939
6940         cancel_lru_locks $OSC
6941
6942         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6943         local nums=$($cmd | wc -l)
6944
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6949
6950         if (( rpcs_before + glimpses != rpcs_after )); then
6951                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6952                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6953
6954                 if [[ $glimpses == 0 ]]; then
6955                         error "'$cmd' should not send glimpse RPCs to OST"
6956                 else
6957                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6958                 fi
6959         fi
6960 }
6961
6962 test_56ra() {
6963         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6964                 skip "MDS < 2.12.58 doesn't return LSOM data"
6965         local dir=$DIR/$tdir
6966         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6967
6968         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6969
6970         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6971         $LCTL set_param -n llite.*.statahead_agl=0
6972         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6973
6974         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6975         # open and close all files to ensure LSOM is updated
6976         cancel_lru_locks $OSC
6977         find $dir -type f | xargs cat > /dev/null
6978
6979         #   expect_found  glimpse_rpcs  command_to_run
6980         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6981         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6982         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6983         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6984
6985         echo "test" > $dir/$tfile
6986         echo "test2" > $dir/$tfile.2 && sync
6987         cancel_lru_locks $OSC
6988         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6989
6990         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6991         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6992         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6993         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6994
6995         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6996         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6997         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6998         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6999         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7000         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7001 }
7002 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7003
7004 test_56rb() {
7005         local dir=$DIR/$tdir
7006         local tmp=$TMP/$tfile.log
7007         local mdt_idx;
7008
7009         test_mkdir -p $dir || error "failed to mkdir $dir"
7010         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7011                 error "failed to setstripe $dir/$tfile"
7012         mdt_idx=$($LFS getdirstripe -i $dir)
7013         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7014
7015         stack_trap "rm -f $tmp" EXIT
7016         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7017         ! grep -q obd_uuid $tmp ||
7018                 error "failed to find --size +100K --ost 0 $dir"
7019         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7020         ! grep -q obd_uuid $tmp ||
7021                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7022 }
7023 run_test 56rb "check lfs find --size --ost/--mdt works"
7024
7025 test_56rc() {
7026         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7027         local dir=$DIR/$tdir
7028         local found
7029
7030         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7031         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7032         (( $MDSCOUNT > 2 )) &&
7033                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7034         mkdir $dir/$tdir-{1..10}
7035         touch $dir/$tfile-{1..10}
7036
7037         found=$($LFS find $dir --mdt-count 2 | wc -l)
7038         expect=11
7039         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7040
7041         found=$($LFS find $dir -T +1 | wc -l)
7042         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7043         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7044
7045         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7046         expect=11
7047         (( $found == $expect )) || error "found $found all_char, expect $expect"
7048
7049         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7050         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7051         (( $found == $expect )) || error "found $found all_char, expect $expect"
7052 }
7053 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7054
7055 test_56s() { # LU-611 #LU-9369
7056         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7057
7058         local dir=$DIR/$tdir
7059         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7060
7061         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7062         for i in $(seq $NUMDIRS); do
7063                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7064         done
7065
7066         local expected=$NUMDIRS
7067         local cmd="$LFS find -c $OSTCOUNT $dir"
7068         local nums=$($cmd | wc -l)
7069
7070         [ $nums -eq $expected ] || {
7071                 $LFS getstripe -R $dir
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073         }
7074
7075         expected=$((NUMDIRS + onestripe))
7076         cmd="$LFS find -stripe-count +0 -type f $dir"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] || {
7079                 $LFS getstripe -R $dir
7080                 error "'$cmd' wrong: found $nums, expected $expected"
7081         }
7082
7083         expected=$onestripe
7084         cmd="$LFS find -stripe-count 1 -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] || {
7087                 $LFS getstripe -R $dir
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089         }
7090
7091         cmd="$LFS find -stripe-count -2 -type f $dir"
7092         nums=$($cmd | wc -l)
7093         [ $nums -eq $expected ] || {
7094                 $LFS getstripe -R $dir
7095                 error "'$cmd' wrong: found $nums, expected $expected"
7096         }
7097
7098         expected=0
7099         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7100         nums=$($cmd | wc -l)
7101         [ $nums -eq $expected ] || {
7102                 $LFS getstripe -R $dir
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104         }
7105 }
7106 run_test 56s "check lfs find -stripe-count works"
7107
7108 test_56t() { # LU-611 #LU-9369
7109         local dir=$DIR/$tdir
7110
7111         setup_56 $dir 0 $NUMDIRS
7112         for i in $(seq $NUMDIRS); do
7113                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7114         done
7115
7116         local expected=$NUMDIRS
7117         local cmd="$LFS find -S 8M $dir"
7118         local nums=$($cmd | wc -l)
7119
7120         [ $nums -eq $expected ] || {
7121                 $LFS getstripe -R $dir
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123         }
7124         rm -rf $dir
7125
7126         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7127
7128         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7129
7130         expected=$(((NUMDIRS + 1) * NUMFILES))
7131         cmd="$LFS find -stripe-size 512k -type f $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135
7136         cmd="$LFS find -stripe-size +320k -type f $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140
7141         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7142         cmd="$LFS find -stripe-size +200k -type f $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146
7147         cmd="$LFS find -stripe-size -640k -type f $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151
7152         expected=4
7153         cmd="$LFS find -stripe-size 256k -type f $dir"
7154         nums=$($cmd | wc -l)
7155         [ $nums -eq $expected ] ||
7156                 error "'$cmd' wrong: found $nums, expected $expected"
7157
7158         cmd="$LFS find -stripe-size -320k -type f $dir"
7159         nums=$($cmd | wc -l)
7160         [ $nums -eq $expected ] ||
7161                 error "'$cmd' wrong: found $nums, expected $expected"
7162
7163         expected=0
7164         cmd="$LFS find -stripe-size 1024k -type f $dir"
7165         nums=$($cmd | wc -l)
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168 }
7169 run_test 56t "check lfs find -stripe-size works"
7170
7171 test_56u() { # LU-611
7172         local dir=$DIR/$tdir
7173
7174         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7175
7176         if [[ $OSTCOUNT -gt 1 ]]; then
7177                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7178                 onestripe=4
7179         else
7180                 onestripe=0
7181         fi
7182
7183         local expected=$(((NUMDIRS + 1) * NUMFILES))
7184         local cmd="$LFS find -stripe-index 0 -type f $dir"
7185         local nums=$($cmd | wc -l)
7186
7187         [ $nums -eq $expected ] ||
7188                 error "'$cmd' wrong: found $nums, expected $expected"
7189
7190         expected=$onestripe
7191         cmd="$LFS find -stripe-index 1 -type f $dir"
7192         nums=$($cmd | wc -l)
7193         [ $nums -eq $expected ] ||
7194                 error "'$cmd' wrong: found $nums, expected $expected"
7195
7196         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7197         nums=$($cmd | wc -l)
7198         [ $nums -eq $expected ] ||
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200
7201         expected=0
7202         # This should produce an error and not return any files
7203         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7204         nums=$($cmd 2>/dev/null | wc -l)
7205         [ $nums -eq $expected ] ||
7206                 error "'$cmd' wrong: found $nums, expected $expected"
7207
7208         if [[ $OSTCOUNT -gt 1 ]]; then
7209                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7210                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7211                 nums=$($cmd | wc -l)
7212                 [ $nums -eq $expected ] ||
7213                         error "'$cmd' wrong: found $nums, expected $expected"
7214         fi
7215 }
7216 run_test 56u "check lfs find -stripe-index works"
7217
7218 test_56v() {
7219         local mdt_idx=0
7220         local dir=$DIR/$tdir
7221
7222         setup_56 $dir $NUMFILES $NUMDIRS
7223
7224         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7225         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7226
7227         for file in $($LFS find -m $UUID $dir); do
7228                 file_midx=$($LFS getstripe -m $file)
7229                 [ $file_midx -eq $mdt_idx ] ||
7230                         error "lfs find -m $UUID != getstripe -m $file_midx"
7231         done
7232 }
7233 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7234
7235 test_56w() {
7236         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238
7239         local dir=$DIR/$tdir
7240
7241         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7242
7243         local stripe_size=$($LFS getstripe -S -d $dir) ||
7244                 error "$LFS getstripe -S -d $dir failed"
7245         stripe_size=${stripe_size%% *}
7246
7247         local file_size=$((stripe_size * OSTCOUNT))
7248         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7249         local required_space=$((file_num * file_size))
7250         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7251                            head -n1)
7252         [[ $free_space -le $((required_space / 1024)) ]] &&
7253                 skip_env "need $required_space, have $free_space kbytes"
7254
7255         local dd_bs=65536
7256         local dd_count=$((file_size / dd_bs))
7257
7258         # write data into the files
7259         local i
7260         local j
7261         local file
7262
7263         for i in $(seq $NUMFILES); do
7264                 file=$dir/file$i
7265                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7266                         error "write data into $file failed"
7267         done
7268         for i in $(seq $NUMDIRS); do
7269                 for j in $(seq $NUMFILES); do
7270                         file=$dir/dir$i/file$j
7271                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7272                                 error "write data into $file failed"
7273                 done
7274         done
7275
7276         # $LFS_MIGRATE will fail if hard link migration is unsupported
7277         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7278                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7279                         error "creating links to $dir/dir1/file1 failed"
7280         fi
7281
7282         local expected=-1
7283
7284         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7285
7286         # lfs_migrate file
7287         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7288
7289         echo "$cmd"
7290         eval $cmd || error "$cmd failed"
7291
7292         check_stripe_count $dir/file1 $expected
7293
7294         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7295         then
7296                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7297                 # OST 1 if it is on OST 0. This file is small enough to
7298                 # be on only one stripe.
7299                 file=$dir/migr_1_ost
7300                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7301                         error "write data into $file failed"
7302                 local obdidx=$($LFS getstripe -i $file)
7303                 local oldmd5=$(md5sum $file)
7304                 local newobdidx=0
7305
7306                 [[ $obdidx -eq 0 ]] && newobdidx=1
7307                 cmd="$LFS migrate -i $newobdidx $file"
7308                 echo $cmd
7309                 eval $cmd || error "$cmd failed"
7310
7311                 local realobdix=$($LFS getstripe -i $file)
7312                 local newmd5=$(md5sum $file)
7313
7314                 [[ $newobdidx -ne $realobdix ]] &&
7315                         error "new OST is different (was=$obdidx, "\
7316                               "wanted=$newobdidx, got=$realobdix)"
7317                 [[ "$oldmd5" != "$newmd5" ]] &&
7318                         error "md5sum differ: $oldmd5, $newmd5"
7319         fi
7320
7321         # lfs_migrate dir
7322         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7323         echo "$cmd"
7324         eval $cmd || error "$cmd failed"
7325
7326         for j in $(seq $NUMFILES); do
7327                 check_stripe_count $dir/dir1/file$j $expected
7328         done
7329
7330         # lfs_migrate works with lfs find
7331         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7332              $LFS_MIGRATE -y -c $expected"
7333         echo "$cmd"
7334         eval $cmd || error "$cmd failed"
7335
7336         for i in $(seq 2 $NUMFILES); do
7337                 check_stripe_count $dir/file$i $expected
7338         done
7339         for i in $(seq 2 $NUMDIRS); do
7340                 for j in $(seq $NUMFILES); do
7341                 check_stripe_count $dir/dir$i/file$j $expected
7342                 done
7343         done
7344 }
7345 run_test 56w "check lfs_migrate -c stripe_count works"
7346
7347 test_56wb() {
7348         local file1=$DIR/$tdir/file1
7349         local create_pool=false
7350         local initial_pool=$($LFS getstripe -p $DIR)
7351         local pool_list=()
7352         local pool=""
7353
7354         echo -n "Creating test dir..."
7355         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7356         echo "done."
7357
7358         echo -n "Creating test file..."
7359         touch $file1 || error "cannot create file"
7360         echo "done."
7361
7362         echo -n "Detecting existing pools..."
7363         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7364
7365         if [ ${#pool_list[@]} -gt 0 ]; then
7366                 echo "${pool_list[@]}"
7367                 for thispool in "${pool_list[@]}"; do
7368                         if [[ -z "$initial_pool" ||
7369                               "$initial_pool" != "$thispool" ]]; then
7370                                 pool="$thispool"
7371                                 echo "Using existing pool '$pool'"
7372                                 break
7373                         fi
7374                 done
7375         else
7376                 echo "none detected."
7377         fi
7378         if [ -z "$pool" ]; then
7379                 pool=${POOL:-testpool}
7380                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7381                 echo -n "Creating pool '$pool'..."
7382                 create_pool=true
7383                 pool_add $pool &> /dev/null ||
7384                         error "pool_add failed"
7385                 echo "done."
7386
7387                 echo -n "Adding target to pool..."
7388                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7389                         error "pool_add_targets failed"
7390                 echo "done."
7391         fi
7392
7393         echo -n "Setting pool using -p option..."
7394         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7395                 error "migrate failed rc = $?"
7396         echo "done."
7397
7398         echo -n "Verifying test file is in pool after migrating..."
7399         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7400                 error "file was not migrated to pool $pool"
7401         echo "done."
7402
7403         echo -n "Removing test file from pool '$pool'..."
7404         # "lfs migrate $file" won't remove the file from the pool
7405         # until some striping information is changed.
7406         $LFS migrate -c 1 $file1 &> /dev/null ||
7407                 error "cannot remove from pool"
7408         [ "$($LFS getstripe -p $file1)" ] &&
7409                 error "pool still set"
7410         echo "done."
7411
7412         echo -n "Setting pool using --pool option..."
7413         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7414                 error "migrate failed rc = $?"
7415         echo "done."
7416
7417         # Clean up
7418         rm -f $file1
7419         if $create_pool; then
7420                 destroy_test_pools 2> /dev/null ||
7421                         error "destroy test pools failed"
7422         fi
7423 }
7424 run_test 56wb "check lfs_migrate pool support"
7425
7426 test_56wc() {
7427         local file1="$DIR/$tdir/file1"
7428         local parent_ssize
7429         local parent_scount
7430         local cur_ssize
7431         local cur_scount
7432         local orig_ssize
7433
7434         echo -n "Creating test dir..."
7435         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7436         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7437                 error "cannot set stripe by '-S 1M -c 1'"
7438         echo "done"
7439
7440         echo -n "Setting initial stripe for test file..."
7441         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7442                 error "cannot set stripe"
7443         cur_ssize=$($LFS getstripe -S "$file1")
7444         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7445         echo "done."
7446
7447         # File currently set to -S 512K -c 1
7448
7449         # Ensure -c and -S options are rejected when -R is set
7450         echo -n "Verifying incompatible options are detected..."
7451         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7452                 error "incompatible -c and -R options not detected"
7453         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7454                 error "incompatible -S and -R options not detected"
7455         echo "done."
7456
7457         # Ensure unrecognized options are passed through to 'lfs migrate'
7458         echo -n "Verifying -S option is passed through to lfs migrate..."
7459         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7460                 error "migration failed"
7461         cur_ssize=$($LFS getstripe -S "$file1")
7462         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7463         echo "done."
7464
7465         # File currently set to -S 1M -c 1
7466
7467         # Ensure long options are supported
7468         echo -n "Verifying long options supported..."
7469         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7470                 error "long option without argument not supported"
7471         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7472                 error "long option with argument not supported"
7473         cur_ssize=$($LFS getstripe -S "$file1")
7474         [ $cur_ssize -eq 524288 ] ||
7475                 error "migrate --stripe-size $cur_ssize != 524288"
7476         echo "done."
7477
7478         # File currently set to -S 512K -c 1
7479
7480         if [ "$OSTCOUNT" -gt 1 ]; then
7481                 echo -n "Verifying explicit stripe count can be set..."
7482                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7483                         error "migrate failed"
7484                 cur_scount=$($LFS getstripe -c "$file1")
7485                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7486                 echo "done."
7487         fi
7488
7489         # File currently set to -S 512K -c 1 or -S 512K -c 2
7490
7491         # Ensure parent striping is used if -R is set, and no stripe
7492         # count or size is specified
7493         echo -n "Setting stripe for parent directory..."
7494         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7495                 error "cannot set stripe '-S 2M -c 1'"
7496         echo "done."
7497
7498         echo -n "Verifying restripe option uses parent stripe settings..."
7499         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7500         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7501         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7502                 error "migrate failed"
7503         cur_ssize=$($LFS getstripe -S "$file1")
7504         [ $cur_ssize -eq $parent_ssize ] ||
7505                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7506         cur_scount=$($LFS getstripe -c "$file1")
7507         [ $cur_scount -eq $parent_scount ] ||
7508                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7509         echo "done."
7510
7511         # File currently set to -S 1M -c 1
7512
7513         # Ensure striping is preserved if -R is not set, and no stripe
7514         # count or size is specified
7515         echo -n "Verifying striping size preserved when not specified..."
7516         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7517         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7518                 error "cannot set stripe on parent directory"
7519         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7520                 error "migrate failed"
7521         cur_ssize=$($LFS getstripe -S "$file1")
7522         [ $cur_ssize -eq $orig_ssize ] ||
7523                 error "migrate by default $cur_ssize != $orig_ssize"
7524         echo "done."
7525
7526         # Ensure file name properly detected when final option has no argument
7527         echo -n "Verifying file name properly detected..."
7528         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7529                 error "file name interpreted as option argument"
7530         echo "done."
7531
7532         # Clean up
7533         rm -f "$file1"
7534 }
7535 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7536
7537 test_56wd() {
7538         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7539
7540         local file1=$DIR/$tdir/file1
7541
7542         echo -n "Creating test dir..."
7543         test_mkdir $DIR/$tdir || error "cannot create dir"
7544         echo "done."
7545
7546         echo -n "Creating test file..."
7547         touch $file1
7548         echo "done."
7549
7550         # Ensure 'lfs migrate' will fail by using a non-existent option,
7551         # and make sure rsync is not called to recover
7552         echo -n "Make sure --no-rsync option works..."
7553         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7554                 grep -q 'refusing to fall back to rsync' ||
7555                 error "rsync was called with --no-rsync set"
7556         echo "done."
7557
7558         # Ensure rsync is called without trying 'lfs migrate' first
7559         echo -n "Make sure --rsync option works..."
7560         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7561                 grep -q 'falling back to rsync' &&
7562                 error "lfs migrate was called with --rsync set"
7563         echo "done."
7564
7565         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7566         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7567                 grep -q 'at the same time' ||
7568                 error "--rsync and --no-rsync accepted concurrently"
7569         echo "done."
7570
7571         # Clean up
7572         rm -f $file1
7573 }
7574 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7575
7576 test_56we() {
7577         local td=$DIR/$tdir
7578         local tf=$td/$tfile
7579
7580         test_mkdir $td || error "cannot create $td"
7581         touch $tf || error "cannot touch $tf"
7582
7583         echo -n "Make sure --non-direct|-D works..."
7584         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7585                 grep -q "lfs migrate --non-direct" ||
7586                 error "--non-direct option cannot work correctly"
7587         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7588                 grep -q "lfs migrate -D" ||
7589                 error "-D option cannot work correctly"
7590         echo "done."
7591 }
7592 run_test 56we "check lfs_migrate --non-direct|-D support"
7593
7594 test_56x() {
7595         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7596         check_swap_layouts_support
7597
7598         local dir=$DIR/$tdir
7599         local ref1=/etc/passwd
7600         local file1=$dir/file1
7601
7602         test_mkdir $dir || error "creating dir $dir"
7603         $LFS setstripe -c 2 $file1
7604         cp $ref1 $file1
7605         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7606         stripe=$($LFS getstripe -c $file1)
7607         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7608         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7609
7610         # clean up
7611         rm -f $file1
7612 }
7613 run_test 56x "lfs migration support"
7614
7615 test_56xa() {
7616         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7617         check_swap_layouts_support
7618
7619         local dir=$DIR/$tdir/$testnum
7620
7621         test_mkdir -p $dir
7622
7623         local ref1=/etc/passwd
7624         local file1=$dir/file1
7625
7626         $LFS setstripe -c 2 $file1
7627         cp $ref1 $file1
7628         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7629
7630         local stripe=$($LFS getstripe -c $file1)
7631
7632         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7633         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7634
7635         # clean up
7636         rm -f $file1
7637 }
7638 run_test 56xa "lfs migration --block support"
7639
7640 check_migrate_links() {
7641         local dir="$1"
7642         local file1="$dir/file1"
7643         local begin="$2"
7644         local count="$3"
7645         local runas="$4"
7646         local total_count=$(($begin + $count - 1))
7647         local symlink_count=10
7648         local uniq_count=10
7649
7650         if [ ! -f "$file1" ]; then
7651                 echo -n "creating initial file..."
7652                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7653                         error "cannot setstripe initial file"
7654                 echo "done"
7655
7656                 echo -n "creating symlinks..."
7657                 for s in $(seq 1 $symlink_count); do
7658                         ln -s "$file1" "$dir/slink$s" ||
7659                                 error "cannot create symlinks"
7660                 done
7661                 echo "done"
7662
7663                 echo -n "creating nonlinked files..."
7664                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7665                         error "cannot create nonlinked files"
7666                 echo "done"
7667         fi
7668
7669         # create hard links
7670         if [ ! -f "$dir/file$total_count" ]; then
7671                 echo -n "creating hard links $begin:$total_count..."
7672                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7673                         /dev/null || error "cannot create hard links"
7674                 echo "done"
7675         fi
7676
7677         echo -n "checking number of hard links listed in xattrs..."
7678         local fid=$($LFS getstripe -F "$file1")
7679         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7680
7681         echo "${#paths[*]}"
7682         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7683                         skip "hard link list has unexpected size, skipping test"
7684         fi
7685         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7686                         error "link names should exceed xattrs size"
7687         fi
7688
7689         echo -n "migrating files..."
7690         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7691         local rc=$?
7692         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7693         echo "done"
7694
7695         # make sure all links have been properly migrated
7696         echo -n "verifying files..."
7697         fid=$($LFS getstripe -F "$file1") ||
7698                 error "cannot get fid for file $file1"
7699         for i in $(seq 2 $total_count); do
7700                 local fid2=$($LFS getstripe -F $dir/file$i)
7701
7702                 [ "$fid2" == "$fid" ] ||
7703                         error "migrated hard link has mismatched FID"
7704         done
7705
7706         # make sure hard links were properly detected, and migration was
7707         # performed only once for the entire link set; nonlinked files should
7708         # also be migrated
7709         local actual=$(grep -c 'done' <<< "$migrate_out")
7710         local expected=$(($uniq_count + 1))
7711
7712         [ "$actual" -eq  "$expected" ] ||
7713                 error "hard links individually migrated ($actual != $expected)"
7714
7715         # make sure the correct number of hard links are present
7716         local hardlinks=$(stat -c '%h' "$file1")
7717
7718         [ $hardlinks -eq $total_count ] ||
7719                 error "num hard links $hardlinks != $total_count"
7720         echo "done"
7721
7722         return 0
7723 }
7724
7725 test_56xb() {
7726         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7727                 skip "Need MDS version at least 2.10.55"
7728
7729         local dir="$DIR/$tdir"
7730
7731         test_mkdir "$dir" || error "cannot create dir $dir"
7732
7733         echo "testing lfs migrate mode when all links fit within xattrs"
7734         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7735
7736         echo "testing rsync mode when all links fit within xattrs"
7737         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7738
7739         echo "testing lfs migrate mode when all links do not fit within xattrs"
7740         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7741
7742         echo "testing rsync mode when all links do not fit within xattrs"
7743         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7744
7745         chown -R $RUNAS_ID $dir
7746         echo "testing non-root lfs migrate mode when not all links are in xattr"
7747         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7748
7749         # clean up
7750         rm -rf $dir
7751 }
7752 run_test 56xb "lfs migration hard link support"
7753
7754 test_56xc() {
7755         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7756
7757         local dir="$DIR/$tdir"
7758
7759         test_mkdir "$dir" || error "cannot create dir $dir"
7760
7761         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7762         echo -n "Setting initial stripe for 20MB test file..."
7763         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7764                 error "cannot setstripe 20MB file"
7765         echo "done"
7766         echo -n "Sizing 20MB test file..."
7767         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7768         echo "done"
7769         echo -n "Verifying small file autostripe count is 1..."
7770         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7771                 error "cannot migrate 20MB file"
7772         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7773                 error "cannot get stripe for $dir/20mb"
7774         [ $stripe_count -eq 1 ] ||
7775                 error "unexpected stripe count $stripe_count for 20MB file"
7776         rm -f "$dir/20mb"
7777         echo "done"
7778
7779         # Test 2: File is small enough to fit within the available space on
7780         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7781         # have at least an additional 1KB for each desired stripe for test 3
7782         echo -n "Setting stripe for 1GB test file..."
7783         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7784         echo "done"
7785         echo -n "Sizing 1GB test file..."
7786         # File size is 1GB + 3KB
7787         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7788         echo "done"
7789
7790         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7791         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7792         if (( avail > 524288 * OSTCOUNT )); then
7793                 echo -n "Migrating 1GB file..."
7794                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7795                         error "cannot migrate 1GB file"
7796                 echo "done"
7797                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7798                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7799                         error "cannot getstripe for 1GB file"
7800                 [ $stripe_count -eq 2 ] ||
7801                         error "unexpected stripe count $stripe_count != 2"
7802                 echo "done"
7803         fi
7804
7805         # Test 3: File is too large to fit within the available space on
7806         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7807         if [ $OSTCOUNT -ge 3 ]; then
7808                 # The required available space is calculated as
7809                 # file size (1GB + 3KB) / OST count (3).
7810                 local kb_per_ost=349526
7811
7812                 echo -n "Migrating 1GB file with limit..."
7813                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7814                         error "cannot migrate 1GB file with limit"
7815                 echo "done"
7816
7817                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7818                 echo -n "Verifying 1GB autostripe count with limited space..."
7819                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7820                         error "unexpected stripe count $stripe_count (min 3)"
7821                 echo "done"
7822         fi
7823
7824         # clean up
7825         rm -rf $dir
7826 }
7827 run_test 56xc "lfs migration autostripe"
7828
7829 test_56xd() {
7830         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7831
7832         local dir=$DIR/$tdir
7833         local f_mgrt=$dir/$tfile.mgrt
7834         local f_yaml=$dir/$tfile.yaml
7835         local f_copy=$dir/$tfile.copy
7836         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7837         local layout_copy="-c 2 -S 2M -i 1"
7838         local yamlfile=$dir/yamlfile
7839         local layout_before;
7840         local layout_after;
7841
7842         test_mkdir "$dir" || error "cannot create dir $dir"
7843         $LFS setstripe $layout_yaml $f_yaml ||
7844                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7845         $LFS getstripe --yaml $f_yaml > $yamlfile
7846         $LFS setstripe $layout_copy $f_copy ||
7847                 error "cannot setstripe $f_copy with layout $layout_copy"
7848         touch $f_mgrt
7849         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7850
7851         # 1. test option --yaml
7852         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7853                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7854         layout_before=$(get_layout_param $f_yaml)
7855         layout_after=$(get_layout_param $f_mgrt)
7856         [ "$layout_after" == "$layout_before" ] ||
7857                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7858
7859         # 2. test option --copy
7860         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7861                 error "cannot migrate $f_mgrt with --copy $f_copy"
7862         layout_before=$(get_layout_param $f_copy)
7863         layout_after=$(get_layout_param $f_mgrt)
7864         [ "$layout_after" == "$layout_before" ] ||
7865                 error "lfs_migrate --copy: $layout_after != $layout_before"
7866 }
7867 run_test 56xd "check lfs_migrate --yaml and --copy support"
7868
7869 test_56xe() {
7870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7871
7872         local dir=$DIR/$tdir
7873         local f_comp=$dir/$tfile
7874         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7875         local layout_before=""
7876         local layout_after=""
7877
7878         test_mkdir "$dir" || error "cannot create dir $dir"
7879         $LFS setstripe $layout $f_comp ||
7880                 error "cannot setstripe $f_comp with layout $layout"
7881         layout_before=$(get_layout_param $f_comp)
7882         dd if=/dev/zero of=$f_comp bs=1M count=4
7883
7884         # 1. migrate a comp layout file by lfs_migrate
7885         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7886         layout_after=$(get_layout_param $f_comp)
7887         [ "$layout_before" == "$layout_after" ] ||
7888                 error "lfs_migrate: $layout_before != $layout_after"
7889
7890         # 2. migrate a comp layout file by lfs migrate
7891         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7892         layout_after=$(get_layout_param $f_comp)
7893         [ "$layout_before" == "$layout_after" ] ||
7894                 error "lfs migrate: $layout_before != $layout_after"
7895 }
7896 run_test 56xe "migrate a composite layout file"
7897
7898 test_56xf() {
7899         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7900
7901         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7902                 skip "Need server version at least 2.13.53"
7903
7904         local dir=$DIR/$tdir
7905         local f_comp=$dir/$tfile
7906         local layout="-E 1M -c1 -E -1 -c2"
7907         local fid_before=""
7908         local fid_after=""
7909
7910         test_mkdir "$dir" || error "cannot create dir $dir"
7911         $LFS setstripe $layout $f_comp ||
7912                 error "cannot setstripe $f_comp with layout $layout"
7913         fid_before=$($LFS getstripe --fid $f_comp)
7914         dd if=/dev/zero of=$f_comp bs=1M count=4
7915
7916         # 1. migrate a comp layout file to a comp layout
7917         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7918         fid_after=$($LFS getstripe --fid $f_comp)
7919         [ "$fid_before" == "$fid_after" ] ||
7920                 error "comp-to-comp migrate: $fid_before != $fid_after"
7921
7922         # 2. migrate a comp layout file to a plain layout
7923         $LFS migrate -c2 $f_comp ||
7924                 error "cannot migrate $f_comp by lfs migrate"
7925         fid_after=$($LFS getstripe --fid $f_comp)
7926         [ "$fid_before" == "$fid_after" ] ||
7927                 error "comp-to-plain migrate: $fid_before != $fid_after"
7928
7929         # 3. migrate a plain layout file to a comp layout
7930         $LFS migrate $layout $f_comp ||
7931                 error "cannot migrate $f_comp by lfs migrate"
7932         fid_after=$($LFS getstripe --fid $f_comp)
7933         [ "$fid_before" == "$fid_after" ] ||
7934                 error "plain-to-comp migrate: $fid_before != $fid_after"
7935 }
7936 run_test 56xf "FID is not lost during migration of a composite layout file"
7937
7938 check_file_ost_range() {
7939         local file="$1"
7940         shift
7941         local range="$*"
7942         local -a file_range
7943         local idx
7944
7945         file_range=($($LFS getstripe -y "$file" |
7946                 awk '/l_ost_idx:/ { print $NF }'))
7947
7948         if [[ "${#file_range[@]}" = 0 ]]; then
7949                 echo "No osts found for $file"
7950                 return 1
7951         fi
7952
7953         for idx in "${file_range[@]}"; do
7954                 [[ " $range " =~ " $idx " ]] ||
7955                         return 1
7956         done
7957
7958         return 0
7959 }
7960
7961 sub_test_56xg() {
7962         local stripe_opt="$1"
7963         local pool="$2"
7964         shift 2
7965         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7966
7967         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7968                 error "Fail to migrate $tfile on $pool"
7969         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7970                 error "$tfile is not in pool $pool"
7971         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7972                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7973 }
7974
7975 test_56xg() {
7976         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7977         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7978         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7979                 skip "Need MDS version newer than 2.14.52"
7980
7981         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7982         local -a pool_ranges=("0 0" "1 1" "0 1")
7983
7984         # init pools
7985         for i in "${!pool_names[@]}"; do
7986                 pool_add ${pool_names[$i]} ||
7987                         error "pool_add failed (pool: ${pool_names[$i]})"
7988                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7989                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7990         done
7991
7992         # init the file to migrate
7993         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7994                 error "Unable to create $tfile on OST1"
7995         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7996                 error "Unable to write on $tfile"
7997
7998         echo "1. migrate $tfile on pool ${pool_names[0]}"
7999         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8000
8001         echo "2. migrate $tfile on pool ${pool_names[2]}"
8002         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8003
8004         echo "3. migrate $tfile on pool ${pool_names[1]}"
8005         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8006
8007         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8008         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8009         echo
8010
8011         # Clean pools
8012         destroy_test_pools ||
8013                 error "pool_destroy failed"
8014 }
8015 run_test 56xg "lfs migrate pool support"
8016
8017 test_56y() {
8018         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8019                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8020
8021         local res=""
8022         local dir=$DIR/$tdir
8023         local f1=$dir/file1
8024         local f2=$dir/file2
8025
8026         test_mkdir -p $dir || error "creating dir $dir"
8027         touch $f1 || error "creating std file $f1"
8028         $MULTIOP $f2 H2c || error "creating released file $f2"
8029
8030         # a directory can be raid0, so ask only for files
8031         res=$($LFS find $dir -L raid0 -type f | wc -l)
8032         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8033
8034         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8035         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8036
8037         # only files can be released, so no need to force file search
8038         res=$($LFS find $dir -L released)
8039         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8040
8041         res=$($LFS find $dir -type f \! -L released)
8042         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8043 }
8044 run_test 56y "lfs find -L raid0|released"
8045
8046 test_56z() { # LU-4824
8047         # This checks to make sure 'lfs find' continues after errors
8048         # There are two classes of errors that should be caught:
8049         # - If multiple paths are provided, all should be searched even if one
8050         #   errors out
8051         # - If errors are encountered during the search, it should not terminate
8052         #   early
8053         local dir=$DIR/$tdir
8054         local i
8055
8056         test_mkdir $dir
8057         for i in d{0..9}; do
8058                 test_mkdir $dir/$i
8059                 touch $dir/$i/$tfile
8060         done
8061         $LFS find $DIR/non_existent_dir $dir &&
8062                 error "$LFS find did not return an error"
8063         # Make a directory unsearchable. This should NOT be the last entry in
8064         # directory order.  Arbitrarily pick the 6th entry
8065         chmod 700 $($LFS find $dir -type d | sed '6!d')
8066
8067         $RUNAS $LFS find $DIR/non_existent $dir
8068         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8069
8070         # The user should be able to see 10 directories and 9 files
8071         (( count == 19 )) ||
8072                 error "$LFS find found $count != 19 entries after error"
8073 }
8074 run_test 56z "lfs find should continue after an error"
8075
8076 test_56aa() { # LU-5937
8077         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8078
8079         local dir=$DIR/$tdir
8080
8081         mkdir $dir
8082         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8083
8084         createmany -o $dir/striped_dir/${tfile}- 1024
8085         local dirs=$($LFS find --size +8k $dir/)
8086
8087         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8088 }
8089 run_test 56aa "lfs find --size under striped dir"
8090
8091 test_56ab() { # LU-10705
8092         test_mkdir $DIR/$tdir
8093         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8094         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8095         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8096         # Flush writes to ensure valid blocks.  Need to be more thorough for
8097         # ZFS, since blocks are not allocated/returned to client immediately.
8098         sync_all_data
8099         wait_zfs_commit ost1 2
8100         cancel_lru_locks osc
8101         ls -ls $DIR/$tdir
8102
8103         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8104
8105         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8106
8107         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8108         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8109
8110         rm -f $DIR/$tdir/$tfile.[123]
8111 }
8112 run_test 56ab "lfs find --blocks"
8113
8114 # LU-11188
8115 test_56aca() {
8116         local dir="$DIR/$tdir"
8117         local perms=(001 002 003 004 005 006 007
8118                      010 020 030 040 050 060 070
8119                      100 200 300 400 500 600 700
8120                      111 222 333 444 555 666 777)
8121         local perm_minus=(8 8 4 8 4 4 2
8122                           8 8 4 8 4 4 2
8123                           8 8 4 8 4 4 2
8124                           4 4 2 4 2 2 1)
8125         local perm_slash=(8  8 12  8 12 12 14
8126                           8  8 12  8 12 12 14
8127                           8  8 12  8 12 12 14
8128                          16 16 24 16 24 24 28)
8129
8130         test_mkdir "$dir"
8131         for perm in ${perms[*]}; do
8132                 touch "$dir/$tfile.$perm"
8133                 chmod $perm "$dir/$tfile.$perm"
8134         done
8135
8136         for ((i = 0; i < ${#perms[*]}; i++)); do
8137                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8138                 (( $num == 1 )) ||
8139                         error "lfs find -perm ${perms[i]}:"\
8140                               "$num != 1"
8141
8142                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8143                 (( $num == ${perm_minus[i]} )) ||
8144                         error "lfs find -perm -${perms[i]}:"\
8145                               "$num != ${perm_minus[i]}"
8146
8147                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8148                 (( $num == ${perm_slash[i]} )) ||
8149                         error "lfs find -perm /${perms[i]}:"\
8150                               "$num != ${perm_slash[i]}"
8151         done
8152 }
8153 run_test 56aca "check lfs find -perm with octal representation"
8154
8155 test_56acb() {
8156         local dir=$DIR/$tdir
8157         # p is the permission of write and execute for user, group and other
8158         # without the umask. It is used to test +wx.
8159         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8160         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8161         local symbolic=(+t  a+t u+t g+t o+t
8162                         g+s u+s o+s +s o+sr
8163                         o=r,ug+o,u+w
8164                         u+ g+ o+ a+ ugo+
8165                         u- g- o- a- ugo-
8166                         u= g= o= a= ugo=
8167                         o=r,ug+o,u+w u=r,a+u,u+w
8168                         g=r,ugo=g,u+w u+x,+X +X
8169                         u+x,u+X u+X u+x,g+X o+r,+X
8170                         u+x,go+X +wx +rwx)
8171
8172         test_mkdir $dir
8173         for perm in ${perms[*]}; do
8174                 touch "$dir/$tfile.$perm"
8175                 chmod $perm "$dir/$tfile.$perm"
8176         done
8177
8178         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8179                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8180
8181                 (( $num == 1 )) ||
8182                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8183         done
8184 }
8185 run_test 56acb "check lfs find -perm with symbolic representation"
8186
8187 test_56acc() {
8188         local dir=$DIR/$tdir
8189         local tests="17777 787 789 abcd
8190                 ug=uu ug=a ug=gu uo=ou urw
8191                 u+xg+x a=r,u+x,"
8192
8193         test_mkdir $dir
8194         for err in $tests; do
8195                 if $LFS find $dir -perm $err 2>/dev/null; then
8196                         error "lfs find -perm $err: parsing should have failed"
8197                 fi
8198         done
8199 }
8200 run_test 56acc "check parsing error for lfs find -perm"
8201
8202 test_56ba() {
8203         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8204                 skip "Need MDS version at least 2.10.50"
8205
8206         # Create composite files with one component
8207         local dir=$DIR/$tdir
8208
8209         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8210         # Create composite files with three components
8211         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8212         # Create non-composite files
8213         createmany -o $dir/${tfile}- 10
8214
8215         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8216
8217         [[ $nfiles == 10 ]] ||
8218                 error "lfs find -E 1M found $nfiles != 10 files"
8219
8220         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8221         [[ $nfiles == 25 ]] ||
8222                 error "lfs find ! -E 1M found $nfiles != 25 files"
8223
8224         # All files have a component that starts at 0
8225         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8226         [[ $nfiles == 35 ]] ||
8227                 error "lfs find --component-start 0 - $nfiles != 35 files"
8228
8229         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8230         [[ $nfiles == 15 ]] ||
8231                 error "lfs find --component-start 2M - $nfiles != 15 files"
8232
8233         # All files created here have a componenet that does not starts at 2M
8234         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8235         [[ $nfiles == 35 ]] ||
8236                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8237
8238         # Find files with a specified number of components
8239         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8240         [[ $nfiles == 15 ]] ||
8241                 error "lfs find --component-count 3 - $nfiles != 15 files"
8242
8243         # Remember non-composite files have a component count of zero
8244         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8245         [[ $nfiles == 10 ]] ||
8246                 error "lfs find --component-count 0 - $nfiles != 10 files"
8247
8248         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8249         [[ $nfiles == 20 ]] ||
8250                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8251
8252         # All files have a flag called "init"
8253         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8254         [[ $nfiles == 35 ]] ||
8255                 error "lfs find --component-flags init - $nfiles != 35 files"
8256
8257         # Multi-component files will have a component not initialized
8258         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8259         [[ $nfiles == 15 ]] ||
8260                 error "lfs find !--component-flags init - $nfiles != 15 files"
8261
8262         rm -rf $dir
8263
8264 }
8265 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8266
8267 test_56ca() {
8268         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8269                 skip "Need MDS version at least 2.10.57"
8270
8271         local td=$DIR/$tdir
8272         local tf=$td/$tfile
8273         local dir
8274         local nfiles
8275         local cmd
8276         local i
8277         local j
8278
8279         # create mirrored directories and mirrored files
8280         mkdir $td || error "mkdir $td failed"
8281         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8282         createmany -o $tf- 10 || error "create $tf- failed"
8283
8284         for i in $(seq 2); do
8285                 dir=$td/dir$i
8286                 mkdir $dir || error "mkdir $dir failed"
8287                 $LFS mirror create -N$((3 + i)) $dir ||
8288                         error "create mirrored dir $dir failed"
8289                 createmany -o $dir/$tfile- 10 ||
8290                         error "create $dir/$tfile- failed"
8291         done
8292
8293         # change the states of some mirrored files
8294         echo foo > $tf-6
8295         for i in $(seq 2); do
8296                 dir=$td/dir$i
8297                 for j in $(seq 4 9); do
8298                         echo foo > $dir/$tfile-$j
8299                 done
8300         done
8301
8302         # find mirrored files with specific mirror count
8303         cmd="$LFS find --mirror-count 3 --type f $td"
8304         nfiles=$($cmd | wc -l)
8305         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8306
8307         cmd="$LFS find ! --mirror-count 3 --type f $td"
8308         nfiles=$($cmd | wc -l)
8309         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8310
8311         cmd="$LFS find --mirror-count +2 --type f $td"
8312         nfiles=$($cmd | wc -l)
8313         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8314
8315         cmd="$LFS find --mirror-count -6 --type f $td"
8316         nfiles=$($cmd | wc -l)
8317         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8318
8319         # find mirrored files with specific file state
8320         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8321         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8322
8323         cmd="$LFS find --mirror-state=ro --type f $td"
8324         nfiles=$($cmd | wc -l)
8325         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8326
8327         cmd="$LFS find ! --mirror-state=ro --type f $td"
8328         nfiles=$($cmd | wc -l)
8329         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8330
8331         cmd="$LFS find --mirror-state=wp --type f $td"
8332         nfiles=$($cmd | wc -l)
8333         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8334
8335         cmd="$LFS find ! --mirror-state=sp --type f $td"
8336         nfiles=$($cmd | wc -l)
8337         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8338 }
8339 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8340
8341 test_56da() { # LU-14179
8342         local path=$DIR/$tdir
8343
8344         test_mkdir $path
8345         cd $path
8346
8347         local longdir=$(str_repeat 'a' 255)
8348
8349         for i in {1..15}; do
8350                 path=$path/$longdir
8351                 test_mkdir $longdir
8352                 cd $longdir
8353         done
8354
8355         local len=${#path}
8356         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8357
8358         test_mkdir $lastdir
8359         cd $lastdir
8360         # PATH_MAX-1
8361         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8362
8363         # NAME_MAX
8364         touch $(str_repeat 'f' 255)
8365
8366         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8367                 error "lfs find reported an error"
8368
8369         rm -rf $DIR/$tdir
8370 }
8371 run_test 56da "test lfs find with long paths"
8372
8373 test_56ea() { #LU-10378
8374         local path=$DIR/$tdir
8375         local pool=$TESTNAME
8376
8377         # Create ost pool
8378         pool_add $pool || error "pool_add $pool failed"
8379         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8380                 error "adding targets to $pool failed"
8381
8382         # Set default pool on directory before creating file
8383         mkdir $path || error "mkdir $path failed"
8384         $LFS setstripe -p $pool $path ||
8385                 error "set OST pool on $pool failed"
8386         touch $path/$tfile || error "touch $path/$tfile failed"
8387
8388         # Compare basic file attributes from -printf and stat
8389         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8390         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8391
8392         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8393                 error "Attrs from lfs find and stat don't match"
8394
8395         # Compare Lustre attributes from lfs find and lfs getstripe
8396         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8397         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8398         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8399         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8400         local fpool=$($LFS getstripe --pool $path/$tfile)
8401         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8402
8403         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8404                 error "Attrs from lfs find and lfs getstripe don't match"
8405
8406         # Verify behavior for unknown escape/format sequences
8407         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8408
8409         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8410                 error "Escape/format codes don't match"
8411 }
8412 run_test 56ea "test lfs find -printf option"
8413
8414 test_56eb() {
8415         local dir=$DIR/$tdir
8416         local subdir_1=$dir/subdir_1
8417
8418         test_mkdir -p $subdir_1
8419         ln -s subdir_1 $dir/link_1
8420
8421         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8422                 error "symlink is not followed"
8423
8424         $LFS getstripe --no-follow $dir |
8425                 grep "^$dir/link_1 has no stripe info$" ||
8426                 error "symlink should not have stripe info"
8427
8428         touch $dir/testfile
8429         ln -s testfile $dir/file_link_2
8430
8431         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8432                 error "symlink is not followed"
8433
8434         $LFS getstripe --no-follow $dir |
8435                 grep "^$dir/file_link_2 has no stripe info$" ||
8436                 error "symlink should not have stripe info"
8437 }
8438 run_test 56eb "check lfs getstripe on symlink"
8439
8440 test_57a() {
8441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8442         # note test will not do anything if MDS is not local
8443         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8444                 skip_env "ldiskfs only test"
8445         fi
8446         remote_mds_nodsh && skip "remote MDS with nodsh"
8447
8448         local MNTDEV="osd*.*MDT*.mntdev"
8449         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8450         [ -z "$DEV" ] && error "can't access $MNTDEV"
8451         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8452                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8453                         error "can't access $DEV"
8454                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8455                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8456                 rm $TMP/t57a.dump
8457         done
8458 }
8459 run_test 57a "verify MDS filesystem created with large inodes =="
8460
8461 test_57b() {
8462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8463         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8464                 skip_env "ldiskfs only test"
8465         fi
8466         remote_mds_nodsh && skip "remote MDS with nodsh"
8467
8468         local dir=$DIR/$tdir
8469         local filecount=100
8470         local file1=$dir/f1
8471         local fileN=$dir/f$filecount
8472
8473         rm -rf $dir || error "removing $dir"
8474         test_mkdir -c1 $dir
8475         local mdtidx=$($LFS getstripe -m $dir)
8476         local mdtname=MDT$(printf %04x $mdtidx)
8477         local facet=mds$((mdtidx + 1))
8478
8479         echo "mcreating $filecount files"
8480         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8481
8482         # verify that files do not have EAs yet
8483         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8484                 error "$file1 has an EA"
8485         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8486                 error "$fileN has an EA"
8487
8488         sync
8489         sleep 1
8490         df $dir  #make sure we get new statfs data
8491         local mdsfree=$(do_facet $facet \
8492                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8493         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8494         local file
8495
8496         echo "opening files to create objects/EAs"
8497         for file in $(seq -f $dir/f%g 1 $filecount); do
8498                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8499                         error "opening $file"
8500         done
8501
8502         # verify that files have EAs now
8503         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8504         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8505
8506         sleep 1  #make sure we get new statfs data
8507         df $dir
8508         local mdsfree2=$(do_facet $facet \
8509                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8510         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8511
8512         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8513                 if [ "$mdsfree" != "$mdsfree2" ]; then
8514                         error "MDC before $mdcfree != after $mdcfree2"
8515                 else
8516                         echo "MDC before $mdcfree != after $mdcfree2"
8517                         echo "unable to confirm if MDS has large inodes"
8518                 fi
8519         fi
8520         rm -rf $dir
8521 }
8522 run_test 57b "default LOV EAs are stored inside large inodes ==="
8523
8524 test_58() {
8525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8526         [ -z "$(which wiretest 2>/dev/null)" ] &&
8527                         skip_env "could not find wiretest"
8528
8529         wiretest
8530 }
8531 run_test 58 "verify cross-platform wire constants =============="
8532
8533 test_59() {
8534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8535
8536         echo "touch 130 files"
8537         createmany -o $DIR/f59- 130
8538         echo "rm 130 files"
8539         unlinkmany $DIR/f59- 130
8540         sync
8541         # wait for commitment of removal
8542         wait_delete_completed
8543 }
8544 run_test 59 "verify cancellation of llog records async ========="
8545
8546 TEST60_HEAD="test_60 run $RANDOM"
8547 test_60a() {
8548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8549         remote_mgs_nodsh && skip "remote MGS with nodsh"
8550         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8551                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8552                         skip_env "missing subtest run-llog.sh"
8553
8554         log "$TEST60_HEAD - from kernel mode"
8555         do_facet mgs "$LCTL dk > /dev/null"
8556         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8557         do_facet mgs $LCTL dk > $TMP/$tfile
8558
8559         # LU-6388: test llog_reader
8560         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8561         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8562         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8563                         skip_env "missing llog_reader"
8564         local fstype=$(facet_fstype mgs)
8565         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8566                 skip_env "Only for ldiskfs or zfs type mgs"
8567
8568         local mntpt=$(facet_mntpt mgs)
8569         local mgsdev=$(mgsdevname 1)
8570         local fid_list
8571         local fid
8572         local rec_list
8573         local rec
8574         local rec_type
8575         local obj_file
8576         local path
8577         local seq
8578         local oid
8579         local pass=true
8580
8581         #get fid and record list
8582         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8583                 tail -n 4))
8584         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8585                 tail -n 4))
8586         #remount mgs as ldiskfs or zfs type
8587         stop mgs || error "stop mgs failed"
8588         mount_fstype mgs || error "remount mgs failed"
8589         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8590                 fid=${fid_list[i]}
8591                 rec=${rec_list[i]}
8592                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8593                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8594                 oid=$((16#$oid))
8595
8596                 case $fstype in
8597                         ldiskfs )
8598                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8599                         zfs )
8600                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8601                 esac
8602                 echo "obj_file is $obj_file"
8603                 do_facet mgs $llog_reader $obj_file
8604
8605                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8606                         awk '{ print $3 }' | sed -e "s/^type=//g")
8607                 if [ $rec_type != $rec ]; then
8608                         echo "FAILED test_60a wrong record type $rec_type," \
8609                               "should be $rec"
8610                         pass=false
8611                         break
8612                 fi
8613
8614                 #check obj path if record type is LLOG_LOGID_MAGIC
8615                 if [ "$rec" == "1064553b" ]; then
8616                         path=$(do_facet mgs $llog_reader $obj_file |
8617                                 grep "path=" | awk '{ print $NF }' |
8618                                 sed -e "s/^path=//g")
8619                         if [ $obj_file != $mntpt/$path ]; then
8620                                 echo "FAILED test_60a wrong obj path" \
8621                                       "$montpt/$path, should be $obj_file"
8622                                 pass=false
8623                                 break
8624                         fi
8625                 fi
8626         done
8627         rm -f $TMP/$tfile
8628         #restart mgs before "error", otherwise it will block the next test
8629         stop mgs || error "stop mgs failed"
8630         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8631         $pass || error "test failed, see FAILED test_60a messages for specifics"
8632 }
8633 run_test 60a "llog_test run from kernel module and test llog_reader"
8634
8635 test_60b() { # bug 6411
8636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8637
8638         dmesg > $DIR/$tfile
8639         LLOG_COUNT=$(do_facet mgs dmesg |
8640                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8641                           /llog_[a-z]*.c:[0-9]/ {
8642                                 if (marker)
8643                                         from_marker++
8644                                 from_begin++
8645                           }
8646                           END {
8647                                 if (marker)
8648                                         print from_marker
8649                                 else
8650                                         print from_begin
8651                           }")
8652
8653         [[ $LLOG_COUNT -gt 120 ]] &&
8654                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8655 }
8656 run_test 60b "limit repeated messages from CERROR/CWARN"
8657
8658 test_60c() {
8659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8660
8661         echo "create 5000 files"
8662         createmany -o $DIR/f60c- 5000
8663 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8664         lctl set_param fail_loc=0x80000137
8665         unlinkmany $DIR/f60c- 5000
8666         lctl set_param fail_loc=0
8667 }
8668 run_test 60c "unlink file when mds full"
8669
8670 test_60d() {
8671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8672
8673         SAVEPRINTK=$(lctl get_param -n printk)
8674         # verify "lctl mark" is even working"
8675         MESSAGE="test message ID $RANDOM $$"
8676         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8677         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8678
8679         lctl set_param printk=0 || error "set lnet.printk failed"
8680         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8681         MESSAGE="new test message ID $RANDOM $$"
8682         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8683         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8684         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8685
8686         lctl set_param -n printk="$SAVEPRINTK"
8687 }
8688 run_test 60d "test printk console message masking"
8689
8690 test_60e() {
8691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8692         remote_mds_nodsh && skip "remote MDS with nodsh"
8693
8694         touch $DIR/$tfile
8695 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8696         do_facet mds1 lctl set_param fail_loc=0x15b
8697         rm $DIR/$tfile
8698 }
8699 run_test 60e "no space while new llog is being created"
8700
8701 test_60f() {
8702         local old_path=$($LCTL get_param -n debug_path)
8703
8704         stack_trap "$LCTL set_param debug_path=$old_path"
8705         stack_trap "rm -f $TMP/$tfile*"
8706         rm -f $TMP/$tfile* 2> /dev/null
8707         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8708         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8709         test_mkdir $DIR/$tdir
8710         # retry in case the open is cached and not released
8711         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8712                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8713                 sleep 0.1
8714         done
8715         ls $TMP/$tfile*
8716         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8717 }
8718 run_test 60f "change debug_path works"
8719
8720 test_60g() {
8721         local pid
8722         local i
8723
8724         test_mkdir -c $MDSCOUNT $DIR/$tdir
8725
8726         (
8727                 local index=0
8728                 while true; do
8729                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8730                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8731                                 2>/dev/null
8732                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8733                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8734                         index=$((index + 1))
8735                 done
8736         ) &
8737
8738         pid=$!
8739
8740         for i in {0..100}; do
8741                 # define OBD_FAIL_OSD_TXN_START    0x19a
8742                 local index=$((i % MDSCOUNT + 1))
8743
8744                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8745                         > /dev/null
8746                 sleep 0.01
8747         done
8748
8749         kill -9 $pid
8750
8751         for i in $(seq $MDSCOUNT); do
8752                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8753         done
8754
8755         mkdir $DIR/$tdir/new || error "mkdir failed"
8756         rmdir $DIR/$tdir/new || error "rmdir failed"
8757
8758         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8759                 -t namespace
8760         for i in $(seq $MDSCOUNT); do
8761                 wait_update_facet mds$i "$LCTL get_param -n \
8762                         mdd.$(facet_svc mds$i).lfsck_namespace |
8763                         awk '/^status/ { print \\\$2 }'" "completed"
8764         done
8765
8766         ls -R $DIR/$tdir
8767         rm -rf $DIR/$tdir || error "rmdir failed"
8768 }
8769 run_test 60g "transaction abort won't cause MDT hung"
8770
8771 test_60h() {
8772         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8773                 skip "Need MDS version at least 2.12.52"
8774         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8775
8776         local f
8777
8778         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8779         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8780         for fail_loc in 0x80000188 0x80000189; do
8781                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8782                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8783                         error "mkdir $dir-$fail_loc failed"
8784                 for i in {0..10}; do
8785                         # create may fail on missing stripe
8786                         echo $i > $DIR/$tdir-$fail_loc/$i
8787                 done
8788                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8789                         error "getdirstripe $tdir-$fail_loc failed"
8790                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8791                         error "migrate $tdir-$fail_loc failed"
8792                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8793                         error "getdirstripe $tdir-$fail_loc failed"
8794                 pushd $DIR/$tdir-$fail_loc
8795                 for f in *; do
8796                         echo $f | cmp $f - || error "$f data mismatch"
8797                 done
8798                 popd
8799                 rm -rf $DIR/$tdir-$fail_loc
8800         done
8801 }
8802 run_test 60h "striped directory with missing stripes can be accessed"
8803
8804 function t60i_load() {
8805         mkdir $DIR/$tdir
8806         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8807         $LCTL set_param fail_loc=0x131c fail_val=1
8808         for ((i=0; i<5000; i++)); do
8809                 touch $DIR/$tdir/f$i
8810         done
8811 }
8812
8813 test_60i() {
8814         changelog_register || error "changelog_register failed"
8815         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8816         changelog_users $SINGLEMDS | grep -q $cl_user ||
8817                 error "User $cl_user not found in changelog_users"
8818         changelog_chmask "ALL"
8819         t60i_load &
8820         local PID=$!
8821         for((i=0; i<100; i++)); do
8822                 changelog_dump >/dev/null ||
8823                         error "can't read changelog"
8824         done
8825         kill $PID
8826         wait $PID
8827         changelog_deregister || error "changelog_deregister failed"
8828         $LCTL set_param fail_loc=0
8829 }
8830 run_test 60i "llog: new record vs reader race"
8831
8832 test_60j() {
8833         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8834                 skip "need MDS version at least 2.15.50"
8835         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8836         remote_mds_nodsh && skip "remote MDS with nodsh"
8837         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8838
8839         changelog_users $SINGLEMDS | grep "^cl" &&
8840                 skip "active changelog user"
8841
8842         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8843
8844         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8845                 skip_env "missing llog_reader"
8846
8847         mkdir_on_mdt0 $DIR/$tdir
8848
8849         local f=$DIR/$tdir/$tfile
8850         local mdt_dev
8851         local tmpfile
8852         local plain
8853
8854         changelog_register || error "cannot register changelog user"
8855
8856         # set changelog_mask to ALL
8857         changelog_chmask "ALL"
8858         changelog_clear
8859
8860         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8861         unlinkmany ${f}- 100 || error "unlinkmany failed"
8862
8863         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8864         mdt_dev=$(facet_device $SINGLEMDS)
8865
8866         do_facet $SINGLEMDS sync
8867         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8868                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8869                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8870
8871         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8872
8873         # if $tmpfile is not on EXT3 filesystem for some reason
8874         [[ ${plain:0:1} == 'O' ]] ||
8875                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8876
8877         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8878                 $mdt_dev; stat -c %s $tmpfile")
8879         echo "Truncate llog from $size to $((size - size % 8192))"
8880         size=$((size - size % 8192))
8881         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8882         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8883                 grep -c 'in bitmap only')
8884         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8885
8886         size=$((size - 9000))
8887         echo "Corrupt llog in the middle at $size"
8888         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8889                 count=333 conv=notrunc
8890         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8891                 grep -c 'next chunk')
8892         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
8893 }
8894 run_test 60j "llog_reader reports corruptions"
8895
8896 test_61a() {
8897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8898
8899         f="$DIR/f61"
8900         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8901         cancel_lru_locks osc
8902         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8903         sync
8904 }
8905 run_test 61a "mmap() writes don't make sync hang ================"
8906
8907 test_61b() {
8908         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8909 }
8910 run_test 61b "mmap() of unstriped file is successful"
8911
8912 # bug 2330 - insufficient obd_match error checking causes LBUG
8913 test_62() {
8914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8915
8916         f="$DIR/f62"
8917         echo foo > $f
8918         cancel_lru_locks osc
8919         lctl set_param fail_loc=0x405
8920         cat $f && error "cat succeeded, expect -EIO"
8921         lctl set_param fail_loc=0
8922 }
8923 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8924 # match every page all of the time.
8925 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8926
8927 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8928 # Though this test is irrelevant anymore, it helped to reveal some
8929 # other grant bugs (LU-4482), let's keep it.
8930 test_63a() {   # was test_63
8931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8932
8933         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8934
8935         for i in `seq 10` ; do
8936                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8937                 sleep 5
8938                 kill $!
8939                 sleep 1
8940         done
8941
8942         rm -f $DIR/f63 || true
8943 }
8944 run_test 63a "Verify oig_wait interruption does not crash ======="
8945
8946 # bug 2248 - async write errors didn't return to application on sync
8947 # bug 3677 - async write errors left page locked
8948 test_63b() {
8949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8950
8951         debugsave
8952         lctl set_param debug=-1
8953
8954         # ensure we have a grant to do async writes
8955         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8956         rm $DIR/$tfile
8957
8958         sync    # sync lest earlier test intercept the fail_loc
8959
8960         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8961         lctl set_param fail_loc=0x80000406
8962         $MULTIOP $DIR/$tfile Owy && \
8963                 error "sync didn't return ENOMEM"
8964         sync; sleep 2; sync     # do a real sync this time to flush page
8965         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8966                 error "locked page left in cache after async error" || true
8967         debugrestore
8968 }
8969 run_test 63b "async write errors should be returned to fsync ==="
8970
8971 test_64a () {
8972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8973
8974         lfs df $DIR
8975         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8976 }
8977 run_test 64a "verify filter grant calculations (in kernel) ====="
8978
8979 test_64b () {
8980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8981
8982         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8983 }
8984 run_test 64b "check out-of-space detection on client"
8985
8986 test_64c() {
8987         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8988 }
8989 run_test 64c "verify grant shrink"
8990
8991 import_param() {
8992         local tgt=$1
8993         local param=$2
8994
8995         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8996 }
8997
8998 # this does exactly what osc_request.c:osc_announce_cached() does in
8999 # order to calculate max amount of grants to ask from server
9000 want_grant() {
9001         local tgt=$1
9002
9003         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9004         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9005
9006         ((rpc_in_flight++));
9007         nrpages=$((nrpages * rpc_in_flight))
9008
9009         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9010
9011         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9012
9013         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9014         local undirty=$((nrpages * PAGE_SIZE))
9015
9016         local max_extent_pages
9017         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9018         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9019         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9020         local grant_extent_tax
9021         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9022
9023         undirty=$((undirty + nrextents * grant_extent_tax))
9024
9025         echo $undirty
9026 }
9027
9028 # this is size of unit for grant allocation. It should be equal to
9029 # what tgt_grant.c:tgt_grant_chunk() calculates
9030 grant_chunk() {
9031         local tgt=$1
9032         local max_brw_size
9033         local grant_extent_tax
9034
9035         max_brw_size=$(import_param $tgt max_brw_size)
9036
9037         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9038
9039         echo $(((max_brw_size + grant_extent_tax) * 2))
9040 }
9041
9042 test_64d() {
9043         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9044                 skip "OST < 2.10.55 doesn't limit grants enough"
9045
9046         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9047
9048         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9049                 skip "no grant_param connect flag"
9050
9051         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9052
9053         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9054         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9055
9056
9057         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9058         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9059
9060         $LFS setstripe $DIR/$tfile -i 0 -c 1
9061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9062         ddpid=$!
9063
9064         while kill -0 $ddpid; do
9065                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9066
9067                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9068                         kill $ddpid
9069                         error "cur_grant $cur_grant > $max_cur_granted"
9070                 fi
9071
9072                 sleep 1
9073         done
9074 }
9075 run_test 64d "check grant limit exceed"
9076
9077 check_grants() {
9078         local tgt=$1
9079         local expected=$2
9080         local msg=$3
9081         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9082
9083         ((cur_grants == expected)) ||
9084                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9085 }
9086
9087 round_up_p2() {
9088         echo $((($1 + $2 - 1) & ~($2 - 1)))
9089 }
9090
9091 test_64e() {
9092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9093         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9094                 skip "Need OSS version at least 2.11.56"
9095
9096         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9097         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9098         $LCTL set_param debug=+cache
9099
9100         # Remount client to reset grant
9101         remount_client $MOUNT || error "failed to remount client"
9102         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9103
9104         local init_grants=$(import_param $osc_tgt initial_grant)
9105
9106         check_grants $osc_tgt $init_grants "init grants"
9107
9108         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9109         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9110         local gbs=$(import_param $osc_tgt grant_block_size)
9111
9112         # write random number of bytes from max_brw_size / 4 to max_brw_size
9113         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9114         # align for direct io
9115         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9116         # round to grant consumption unit
9117         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9118
9119         local grants=$((wb_round_up + extent_tax))
9120
9121         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9122
9123         # define OBD_FAIL_TGT_NO_GRANT 0x725
9124         # make the server not grant more back
9125         do_facet ost1 $LCTL set_param fail_loc=0x725
9126         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9127
9128         do_facet ost1 $LCTL set_param fail_loc=0
9129
9130         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9131
9132         rm -f $DIR/$tfile || error "rm failed"
9133
9134         # Remount client to reset grant
9135         remount_client $MOUNT || error "failed to remount client"
9136         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9137
9138         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9139
9140         # define OBD_FAIL_TGT_NO_GRANT 0x725
9141         # make the server not grant more back
9142         do_facet ost1 $LCTL set_param fail_loc=0x725
9143         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9144         do_facet ost1 $LCTL set_param fail_loc=0
9145
9146         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9147 }
9148 run_test 64e "check grant consumption (no grant allocation)"
9149
9150 test_64f() {
9151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9152
9153         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9154         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9155         $LCTL set_param debug=+cache
9156
9157         # Remount client to reset grant
9158         remount_client $MOUNT || error "failed to remount client"
9159         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9160
9161         local init_grants=$(import_param $osc_tgt initial_grant)
9162         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9163         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9164         local gbs=$(import_param $osc_tgt grant_block_size)
9165         local chunk=$(grant_chunk $osc_tgt)
9166
9167         # write random number of bytes from max_brw_size / 4 to max_brw_size
9168         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9169         # align for direct io
9170         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9171         # round to grant consumption unit
9172         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9173
9174         local grants=$((wb_round_up + extent_tax))
9175
9176         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9177         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9178                 error "error writing to $DIR/$tfile"
9179
9180         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9181                 "direct io with grant allocation"
9182
9183         rm -f $DIR/$tfile || error "rm failed"
9184
9185         # Remount client to reset grant
9186         remount_client $MOUNT || error "failed to remount client"
9187         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9188
9189         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9190
9191         local cmd="oO_WRONLY:w${write_bytes}_yc"
9192
9193         $MULTIOP $DIR/$tfile $cmd &
9194         MULTIPID=$!
9195         sleep 1
9196
9197         check_grants $osc_tgt $((init_grants - grants)) \
9198                 "buffered io, not write rpc"
9199
9200         kill -USR1 $MULTIPID
9201         wait
9202
9203         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9204                 "buffered io, one RPC"
9205 }
9206 run_test 64f "check grant consumption (with grant allocation)"
9207
9208 test_64g() {
9209         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9210                 skip "Need MDS version at least 2.14.56"
9211
9212         local mdts=$(comma_list $(mdts_nodes))
9213
9214         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9215                         tr '\n' ' ')
9216         stack_trap "$LCTL set_param $old"
9217
9218         # generate dirty pages and increase dirty granted on MDT
9219         stack_trap "rm -f $DIR/$tfile-*"
9220         for (( i = 0; i < 10; i++)); do
9221                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9222                         error "can't set stripe"
9223                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9224                         error "can't dd"
9225                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9226                         $LFS getstripe $DIR/$tfile-$i
9227                         error "not DoM file"
9228                 }
9229         done
9230
9231         # flush dirty pages
9232         sync
9233
9234         # wait until grant shrink reset grant dirty on MDTs
9235         for ((i = 0; i < 120; i++)); do
9236                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9237                         awk '{sum=sum+$1} END {print sum}')
9238                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9239                 echo "$grant_dirty grants, $vm_dirty pages"
9240                 (( grant_dirty + vm_dirty == 0 )) && break
9241                 (( i == 3 )) && sync &&
9242                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9243                 sleep 1
9244         done
9245
9246         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9247                 awk '{sum=sum+$1} END {print sum}')
9248         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9249 }
9250 run_test 64g "grant shrink on MDT"
9251
9252 test_64h() {
9253         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9254                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9255
9256         local instance=$($LFS getname -i $DIR)
9257         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9258         local num_exps=$(do_facet ost1 \
9259             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9260         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9261         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9262         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9263
9264         # 10MiB is for file to be written, max_brw_size * 16 *
9265         # num_exps is space reserve so that tgt_grant_shrink() decided
9266         # to not shrink
9267         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9268         (( avail * 1024 < expect )) &&
9269                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9270
9271         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9272         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9273         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9274         $LCTL set_param osc.*OST0000*.grant_shrink=1
9275         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9276
9277         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9278         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9279
9280         # drop cache so that coming read would do rpc
9281         cancel_lru_locks osc
9282
9283         # shrink interval is set to 10, pause for 7 seconds so that
9284         # grant thread did not wake up yet but coming read entered
9285         # shrink mode for rpc (osc_should_shrink_grant())
9286         sleep 7
9287
9288         declare -a cur_grant_bytes
9289         declare -a tot_granted
9290         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9291         tot_granted[0]=$(do_facet ost1 \
9292             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9293
9294         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9295
9296         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9297         tot_granted[1]=$(do_facet ost1 \
9298             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9299
9300         # grant change should be equal on both sides
9301         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9302                 tot_granted[0] - tot_granted[1])) ||
9303                 error "grant change mismatch, "                                \
9304                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9305                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9306 }
9307 run_test 64h "grant shrink on read"
9308
9309 test_64i() {
9310         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9311                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9312
9313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9314         remote_ost_nodsh && skip "remote OSTs with nodsh"
9315
9316         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9317
9318         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9319
9320         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9321         local instance=$($LFS getname -i $DIR)
9322
9323         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9324         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9325
9326         # shrink grants and simulate rpc loss
9327         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9328         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9329         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9330
9331         fail ost1
9332
9333         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9334
9335         local testid=$(echo $TESTNAME | tr '_' ' ')
9336
9337         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9338                 grep "GRANT, real grant" &&
9339                 error "client has more grants then it owns" || true
9340 }
9341 run_test 64i "shrink on reconnect"
9342
9343 # bug 1414 - set/get directories' stripe info
9344 test_65a() {
9345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9346
9347         test_mkdir $DIR/$tdir
9348         touch $DIR/$tdir/f1
9349         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9350 }
9351 run_test 65a "directory with no stripe info"
9352
9353 test_65b() {
9354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9355
9356         test_mkdir $DIR/$tdir
9357         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9358
9359         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9360                                                 error "setstripe"
9361         touch $DIR/$tdir/f2
9362         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9363 }
9364 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9365
9366 test_65c() {
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9369
9370         test_mkdir $DIR/$tdir
9371         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9372
9373         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9374                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9375         touch $DIR/$tdir/f3
9376         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9377 }
9378 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9379
9380 test_65d() {
9381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9382
9383         test_mkdir $DIR/$tdir
9384         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9385         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9386
9387         if [[ $STRIPECOUNT -le 0 ]]; then
9388                 sc=1
9389         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9390                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9391                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9392         else
9393                 sc=$(($STRIPECOUNT - 1))
9394         fi
9395         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9396         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9397         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9398                 error "lverify failed"
9399 }
9400 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9401
9402 test_65e() {
9403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9404
9405         test_mkdir $DIR/$tdir
9406
9407         $LFS setstripe $DIR/$tdir || error "setstripe"
9408         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9409                                         error "no stripe info failed"
9410         touch $DIR/$tdir/f6
9411         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9412 }
9413 run_test 65e "directory setstripe defaults"
9414
9415 test_65f() {
9416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9417
9418         test_mkdir $DIR/${tdir}f
9419         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9420                 error "setstripe succeeded" || true
9421 }
9422 run_test 65f "dir setstripe permission (should return error) ==="
9423
9424 test_65g() {
9425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9426
9427         test_mkdir $DIR/$tdir
9428         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9429
9430         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9431                 error "setstripe -S failed"
9432         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9433         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9434                 error "delete default stripe failed"
9435 }
9436 run_test 65g "directory setstripe -d"
9437
9438 test_65h() {
9439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9440
9441         test_mkdir $DIR/$tdir
9442         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9443
9444         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9445                 error "setstripe -S failed"
9446         test_mkdir $DIR/$tdir/dd1
9447         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9448                 error "stripe info inherit failed"
9449 }
9450 run_test 65h "directory stripe info inherit ===================="
9451
9452 test_65i() {
9453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9454
9455         save_layout_restore_at_exit $MOUNT
9456
9457         # bug6367: set non-default striping on root directory
9458         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9459
9460         # bug12836: getstripe on -1 default directory striping
9461         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9462
9463         # bug12836: getstripe -v on -1 default directory striping
9464         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9465
9466         # bug12836: new find on -1 default directory striping
9467         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9468 }
9469 run_test 65i "various tests to set root directory striping"
9470
9471 test_65j() { # bug6367
9472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9473
9474         sync; sleep 1
9475
9476         # if we aren't already remounting for each test, do so for this test
9477         if [ "$I_MOUNTED" = "yes" ]; then
9478                 cleanup || error "failed to unmount"
9479                 setup
9480         fi
9481
9482         save_layout_restore_at_exit $MOUNT
9483
9484         $LFS setstripe -d $MOUNT || error "setstripe failed"
9485 }
9486 run_test 65j "set default striping on root directory (bug 6367)="
9487
9488 cleanup_65k() {
9489         rm -rf $DIR/$tdir
9490         wait_delete_completed
9491         do_facet $SINGLEMDS "lctl set_param -n \
9492                 osp.$ost*MDT0000.max_create_count=$max_count"
9493         do_facet $SINGLEMDS "lctl set_param -n \
9494                 osp.$ost*MDT0000.create_count=$count"
9495         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9496         echo $INACTIVE_OSC "is Activate"
9497
9498         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9499 }
9500
9501 test_65k() { # bug11679
9502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9503         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9504         remote_mds_nodsh && skip "remote MDS with nodsh"
9505
9506         local disable_precreate=true
9507         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9508                 disable_precreate=false
9509
9510         echo "Check OST status: "
9511         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9512                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9513
9514         for OSC in $MDS_OSCS; do
9515                 echo $OSC "is active"
9516                 do_facet $SINGLEMDS lctl --device %$OSC activate
9517         done
9518
9519         for INACTIVE_OSC in $MDS_OSCS; do
9520                 local ost=$(osc_to_ost $INACTIVE_OSC)
9521                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9522                                lov.*md*.target_obd |
9523                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9524
9525                 mkdir -p $DIR/$tdir
9526                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9527                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9528
9529                 echo "Deactivate: " $INACTIVE_OSC
9530                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9531
9532                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9533                               osp.$ost*MDT0000.create_count")
9534                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9535                                   osp.$ost*MDT0000.max_create_count")
9536                 $disable_precreate &&
9537                         do_facet $SINGLEMDS "lctl set_param -n \
9538                                 osp.$ost*MDT0000.max_create_count=0"
9539
9540                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9541                         [ -f $DIR/$tdir/$idx ] && continue
9542                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9543                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9544                                 { cleanup_65k;
9545                                   error "setstripe $idx should succeed"; }
9546                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9547                 done
9548                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9549                 rmdir $DIR/$tdir
9550
9551                 do_facet $SINGLEMDS "lctl set_param -n \
9552                         osp.$ost*MDT0000.max_create_count=$max_count"
9553                 do_facet $SINGLEMDS "lctl set_param -n \
9554                         osp.$ost*MDT0000.create_count=$count"
9555                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9556                 echo $INACTIVE_OSC "is Activate"
9557
9558                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9559         done
9560 }
9561 run_test 65k "validate manual striping works properly with deactivated OSCs"
9562
9563 test_65l() { # bug 12836
9564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9565
9566         test_mkdir -p $DIR/$tdir/test_dir
9567         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9568         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9569 }
9570 run_test 65l "lfs find on -1 stripe dir ========================"
9571
9572 test_65m() {
9573         local layout=$(save_layout $MOUNT)
9574         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9575                 restore_layout $MOUNT $layout
9576                 error "setstripe should fail by non-root users"
9577         }
9578         true
9579 }
9580 run_test 65m "normal user can't set filesystem default stripe"
9581
9582 test_65n() {
9583         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9584         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9585                 skip "Need MDS version at least 2.12.50"
9586         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9587
9588         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9589         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9590         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9591
9592         save_layout_restore_at_exit $MOUNT
9593
9594         # new subdirectory under root directory should not inherit
9595         # the default layout from root
9596         local dir1=$MOUNT/$tdir-1
9597         mkdir $dir1 || error "mkdir $dir1 failed"
9598         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9599                 error "$dir1 shouldn't have LOV EA"
9600
9601         # delete the default layout on root directory
9602         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9603
9604         local dir2=$MOUNT/$tdir-2
9605         mkdir $dir2 || error "mkdir $dir2 failed"
9606         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9607                 error "$dir2 shouldn't have LOV EA"
9608
9609         # set a new striping pattern on root directory
9610         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9611         local new_def_stripe_size=$((def_stripe_size * 2))
9612         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9613                 error "set stripe size on $MOUNT failed"
9614
9615         # new file created in $dir2 should inherit the new stripe size from
9616         # the filesystem default
9617         local file2=$dir2/$tfile-2
9618         touch $file2 || error "touch $file2 failed"
9619
9620         local file2_stripe_size=$($LFS getstripe -S $file2)
9621         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9622         {
9623                 echo "file2_stripe_size: '$file2_stripe_size'"
9624                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9625                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9626         }
9627
9628         local dir3=$MOUNT/$tdir-3
9629         mkdir $dir3 || error "mkdir $dir3 failed"
9630         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9631         # the root layout, which is the actual default layout that will be used
9632         # when new files are created in $dir3.
9633         local dir3_layout=$(get_layout_param $dir3)
9634         local root_dir_layout=$(get_layout_param $MOUNT)
9635         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9636         {
9637                 echo "dir3_layout: '$dir3_layout'"
9638                 echo "root_dir_layout: '$root_dir_layout'"
9639                 error "$dir3 should show the default layout from $MOUNT"
9640         }
9641
9642         # set OST pool on root directory
9643         local pool=$TESTNAME
9644         pool_add $pool || error "add $pool failed"
9645         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9646                 error "add targets to $pool failed"
9647
9648         $LFS setstripe -p $pool $MOUNT ||
9649                 error "set OST pool on $MOUNT failed"
9650
9651         # new file created in $dir3 should inherit the pool from
9652         # the filesystem default
9653         local file3=$dir3/$tfile-3
9654         touch $file3 || error "touch $file3 failed"
9655
9656         local file3_pool=$($LFS getstripe -p $file3)
9657         [[ "$file3_pool" = "$pool" ]] ||
9658                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9659
9660         local dir4=$MOUNT/$tdir-4
9661         mkdir $dir4 || error "mkdir $dir4 failed"
9662         local dir4_layout=$(get_layout_param $dir4)
9663         root_dir_layout=$(get_layout_param $MOUNT)
9664         echo "$LFS getstripe -d $dir4"
9665         $LFS getstripe -d $dir4
9666         echo "$LFS getstripe -d $MOUNT"
9667         $LFS getstripe -d $MOUNT
9668         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9669         {
9670                 echo "dir4_layout: '$dir4_layout'"
9671                 echo "root_dir_layout: '$root_dir_layout'"
9672                 error "$dir4 should show the default layout from $MOUNT"
9673         }
9674
9675         # new file created in $dir4 should inherit the pool from
9676         # the filesystem default
9677         local file4=$dir4/$tfile-4
9678         touch $file4 || error "touch $file4 failed"
9679
9680         local file4_pool=$($LFS getstripe -p $file4)
9681         [[ "$file4_pool" = "$pool" ]] ||
9682                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9683
9684         # new subdirectory under non-root directory should inherit
9685         # the default layout from its parent directory
9686         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9687                 error "set directory layout on $dir4 failed"
9688
9689         local dir5=$dir4/$tdir-5
9690         mkdir $dir5 || error "mkdir $dir5 failed"
9691
9692         dir4_layout=$(get_layout_param $dir4)
9693         local dir5_layout=$(get_layout_param $dir5)
9694         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9695         {
9696                 echo "dir4_layout: '$dir4_layout'"
9697                 echo "dir5_layout: '$dir5_layout'"
9698                 error "$dir5 should inherit the default layout from $dir4"
9699         }
9700
9701         # though subdir under ROOT doesn't inherit default layout, but
9702         # its sub dir/file should be created with default layout.
9703         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9704         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9705                 skip "Need MDS version at least 2.12.59"
9706
9707         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9708         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9709         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9710
9711         if [ $default_lmv_hash == "none" ]; then
9712                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9713         else
9714                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9715                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9716         fi
9717
9718         $LFS setdirstripe -D -c 2 $MOUNT ||
9719                 error "setdirstripe -D -c 2 failed"
9720         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9721         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9722         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9723
9724         # $dir4 layout includes pool
9725         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9726         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9727                 error "pool lost on setstripe"
9728         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9729         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9730                 error "pool lost on compound layout setstripe"
9731 }
9732 run_test 65n "don't inherit default layout from root for new subdirectories"
9733
9734 test_65o() {
9735         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9736                 skip "need MDS version at least 2.14.57"
9737
9738         # set OST pool on root directory
9739         local pool=$TESTNAME
9740
9741         pool_add $pool || error "add $pool failed"
9742         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9743                 error "add targets to $pool failed"
9744
9745         local dir1=$MOUNT/$tdir
9746
9747         mkdir $dir1 || error "mkdir $dir1 failed"
9748
9749         # set a new striping pattern on root directory
9750         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9751
9752         $LFS setstripe -p $pool $dir1 ||
9753                 error "set directory layout on $dir1 failed"
9754
9755         # $dir1 layout includes pool
9756         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9757         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9758                 error "pool lost on setstripe"
9759         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9760         $LFS getstripe $dir1
9761         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9762                 error "pool lost on compound layout setstripe"
9763
9764         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9765                 error "setdirstripe failed on sub-dir with inherited pool"
9766         $LFS getstripe $dir1/dir2
9767         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9768                 error "pool lost on compound layout setdirstripe"
9769
9770         $LFS setstripe -E -1 -c 1 $dir1
9771         $LFS getstripe -d $dir1
9772         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9773                 error "pool lost on setstripe"
9774 }
9775 run_test 65o "pool inheritance for mdt component"
9776
9777 test_65p () { # LU-16152
9778         local src_dir=$DIR/$tdir/src_dir
9779         local dst_dir=$DIR/$tdir/dst_dir
9780         local yaml_file=$DIR/$tdir/layout.yaml
9781         local border
9782
9783         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9784                 skip "Need at least version 2.15.51"
9785
9786         test_mkdir -p $src_dir
9787         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9788                 error "failed to setstripe"
9789         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9790                 error "failed to getstripe"
9791
9792         test_mkdir -p $dst_dir
9793         $LFS setstripe --yaml $yaml_file $dst_dir ||
9794                 error "failed to setstripe with yaml file"
9795         border=$($LFS getstripe -d $dst_dir |
9796                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9797                 error "failed to getstripe"
9798
9799         # 2048M is 0x80000000, or 2147483648
9800         (( $border == 2147483648 )) ||
9801                 error "failed to handle huge number in yaml layout"
9802 }
9803 run_test 65p "setstripe with yaml file and huge number"
9804
9805 # bug 2543 - update blocks count on client
9806 test_66() {
9807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9808
9809         local COUNT=${COUNT:-8}
9810         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9811         sync; sync_all_data; sync; sync_all_data
9812         cancel_lru_locks osc
9813         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9814         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9815 }
9816 run_test 66 "update inode blocks count on client ==============="
9817
9818 meminfo() {
9819         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9820 }
9821
9822 swap_used() {
9823         swapon -s | awk '($1 == "'$1'") { print $4 }'
9824 }
9825
9826 # bug5265, obdfilter oa2dentry return -ENOENT
9827 # #define OBD_FAIL_SRV_ENOENT 0x217
9828 test_69() {
9829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9830         remote_ost_nodsh && skip "remote OST with nodsh"
9831
9832         f="$DIR/$tfile"
9833         $LFS setstripe -c 1 -i 0 $f
9834
9835         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9836
9837         do_facet ost1 lctl set_param fail_loc=0x217
9838         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9839         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9840
9841         do_facet ost1 lctl set_param fail_loc=0
9842         $DIRECTIO write $f 0 2 || error "write error"
9843
9844         cancel_lru_locks osc
9845         $DIRECTIO read $f 0 1 || error "read error"
9846
9847         do_facet ost1 lctl set_param fail_loc=0x217
9848         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9849
9850         do_facet ost1 lctl set_param fail_loc=0
9851         rm -f $f
9852 }
9853 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9854
9855 test_71() {
9856         test_mkdir $DIR/$tdir
9857         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9858         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9859 }
9860 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9861
9862 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9864         [ "$RUNAS_ID" = "$UID" ] &&
9865                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9866         # Check that testing environment is properly set up. Skip if not
9867         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9868                 skip_env "User $RUNAS_ID does not exist - skipping"
9869
9870         touch $DIR/$tfile
9871         chmod 777 $DIR/$tfile
9872         chmod ug+s $DIR/$tfile
9873         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9874                 error "$RUNAS dd $DIR/$tfile failed"
9875         # See if we are still setuid/sgid
9876         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9877                 error "S/gid is not dropped on write"
9878         # Now test that MDS is updated too
9879         cancel_lru_locks mdc
9880         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9881                 error "S/gid is not dropped on MDS"
9882         rm -f $DIR/$tfile
9883 }
9884 run_test 72a "Test that remove suid works properly (bug5695) ===="
9885
9886 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9887         local perm
9888
9889         [ "$RUNAS_ID" = "$UID" ] &&
9890                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9891         [ "$RUNAS_ID" -eq 0 ] &&
9892                 skip_env "RUNAS_ID = 0 -- skipping"
9893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9894         # Check that testing environment is properly set up. Skip if not
9895         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9896                 skip_env "User $RUNAS_ID does not exist - skipping"
9897
9898         touch $DIR/${tfile}-f{g,u}
9899         test_mkdir $DIR/${tfile}-dg
9900         test_mkdir $DIR/${tfile}-du
9901         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9902         chmod g+s $DIR/${tfile}-{f,d}g
9903         chmod u+s $DIR/${tfile}-{f,d}u
9904         for perm in 777 2777 4777; do
9905                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9906                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9907                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9908                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9909         done
9910         true
9911 }
9912 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9913
9914 # bug 3462 - multiple simultaneous MDC requests
9915 test_73() {
9916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9917
9918         test_mkdir $DIR/d73-1
9919         test_mkdir $DIR/d73-2
9920         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9921         pid1=$!
9922
9923         lctl set_param fail_loc=0x80000129
9924         $MULTIOP $DIR/d73-1/f73-2 Oc &
9925         sleep 1
9926         lctl set_param fail_loc=0
9927
9928         $MULTIOP $DIR/d73-2/f73-3 Oc &
9929         pid3=$!
9930
9931         kill -USR1 $pid1
9932         wait $pid1 || return 1
9933
9934         sleep 25
9935
9936         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9937         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9938         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9939
9940         rm -rf $DIR/d73-*
9941 }
9942 run_test 73 "multiple MDC requests (should not deadlock)"
9943
9944 test_74a() { # bug 6149, 6184
9945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9946
9947         touch $DIR/f74a
9948         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9949         #
9950         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9951         # will spin in a tight reconnection loop
9952         $LCTL set_param fail_loc=0x8000030e
9953         # get any lock that won't be difficult - lookup works.
9954         ls $DIR/f74a
9955         $LCTL set_param fail_loc=0
9956         rm -f $DIR/f74a
9957         true
9958 }
9959 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9960
9961 test_74b() { # bug 13310
9962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9963
9964         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9965         #
9966         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9967         # will spin in a tight reconnection loop
9968         $LCTL set_param fail_loc=0x8000030e
9969         # get a "difficult" lock
9970         touch $DIR/f74b
9971         $LCTL set_param fail_loc=0
9972         rm -f $DIR/f74b
9973         true
9974 }
9975 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9976
9977 test_74c() {
9978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9979
9980         #define OBD_FAIL_LDLM_NEW_LOCK
9981         $LCTL set_param fail_loc=0x319
9982         touch $DIR/$tfile && error "touch successful"
9983         $LCTL set_param fail_loc=0
9984         true
9985 }
9986 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9987
9988 slab_lic=/sys/kernel/slab/lustre_inode_cache
9989 num_objects() {
9990         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9991         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9992                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9993 }
9994
9995 test_76a() { # Now for b=20433, added originally in b=1443
9996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9997
9998         cancel_lru_locks osc
9999         # there may be some slab objects cached per core
10000         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10001         local before=$(num_objects)
10002         local count=$((512 * cpus))
10003         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10004         local margin=$((count / 10))
10005         if [[ -f $slab_lic/aliases ]]; then
10006                 local aliases=$(cat $slab_lic/aliases)
10007                 (( aliases > 0 )) && margin=$((margin * aliases))
10008         fi
10009
10010         echo "before slab objects: $before"
10011         for i in $(seq $count); do
10012                 touch $DIR/$tfile
10013                 rm -f $DIR/$tfile
10014         done
10015         cancel_lru_locks osc
10016         local after=$(num_objects)
10017         echo "created: $count, after slab objects: $after"
10018         # shared slab counts are not very accurate, allow significant margin
10019         # the main goal is that the cache growth is not permanently > $count
10020         while (( after > before + margin )); do
10021                 sleep 1
10022                 after=$(num_objects)
10023                 wait=$((wait + 1))
10024                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10025                 if (( wait > 60 )); then
10026                         error "inode slab grew from $before+$margin to $after"
10027                 fi
10028         done
10029 }
10030 run_test 76a "confirm clients recycle inodes properly ===="
10031
10032 test_76b() {
10033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10034         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10035
10036         local count=512
10037         local before=$(num_objects)
10038
10039         for i in $(seq $count); do
10040                 mkdir $DIR/$tdir
10041                 rmdir $DIR/$tdir
10042         done
10043
10044         local after=$(num_objects)
10045         local wait=0
10046
10047         while (( after > before )); do
10048                 sleep 1
10049                 after=$(num_objects)
10050                 wait=$((wait + 1))
10051                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10052                 if (( wait > 60 )); then
10053                         error "inode slab grew from $before to $after"
10054                 fi
10055         done
10056
10057         echo "slab objects before: $before, after: $after"
10058 }
10059 run_test 76b "confirm clients recycle directory inodes properly ===="
10060
10061 export ORIG_CSUM=""
10062 set_checksums()
10063 {
10064         # Note: in sptlrpc modes which enable its own bulk checksum, the
10065         # original crc32_le bulk checksum will be automatically disabled,
10066         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10067         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10068         # In this case set_checksums() will not be no-op, because sptlrpc
10069         # bulk checksum will be enabled all through the test.
10070
10071         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10072         lctl set_param -n osc.*.checksums $1
10073         return 0
10074 }
10075
10076 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10077                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10078 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10079                              tr -d [] | head -n1)}
10080 set_checksum_type()
10081 {
10082         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10083         rc=$?
10084         log "set checksum type to $1, rc = $rc"
10085         return $rc
10086 }
10087
10088 get_osc_checksum_type()
10089 {
10090         # arugment 1: OST name, like OST0000
10091         ost=$1
10092         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10093                         sed 's/.*\[\(.*\)\].*/\1/g')
10094         rc=$?
10095         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10096         echo $checksum_type
10097 }
10098
10099 F77_TMP=$TMP/f77-temp
10100 F77SZ=8
10101 setup_f77() {
10102         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10103                 error "error writing to $F77_TMP"
10104 }
10105
10106 test_77a() { # bug 10889
10107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10108         $GSS && skip_env "could not run with gss"
10109
10110         [ ! -f $F77_TMP ] && setup_f77
10111         set_checksums 1
10112         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10113         set_checksums 0
10114         rm -f $DIR/$tfile
10115 }
10116 run_test 77a "normal checksum read/write operation"
10117
10118 test_77b() { # bug 10889
10119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10120         $GSS && skip_env "could not run with gss"
10121
10122         [ ! -f $F77_TMP ] && setup_f77
10123         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10124         $LCTL set_param fail_loc=0x80000409
10125         set_checksums 1
10126
10127         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10128                 error "dd error: $?"
10129         $LCTL set_param fail_loc=0
10130
10131         for algo in $CKSUM_TYPES; do
10132                 cancel_lru_locks osc
10133                 set_checksum_type $algo
10134                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10135                 $LCTL set_param fail_loc=0x80000408
10136                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10137                 $LCTL set_param fail_loc=0
10138         done
10139         set_checksums 0
10140         set_checksum_type $ORIG_CSUM_TYPE
10141         rm -f $DIR/$tfile
10142 }
10143 run_test 77b "checksum error on client write, read"
10144
10145 cleanup_77c() {
10146         trap 0
10147         set_checksums 0
10148         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10149         $check_ost &&
10150                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10151         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10152         $check_ost && [ -n "$ost_file_prefix" ] &&
10153                 do_facet ost1 rm -f ${ost_file_prefix}\*
10154 }
10155
10156 test_77c() {
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10158         $GSS && skip_env "could not run with gss"
10159         remote_ost_nodsh && skip "remote OST with nodsh"
10160
10161         local bad1
10162         local osc_file_prefix
10163         local osc_file
10164         local check_ost=false
10165         local ost_file_prefix
10166         local ost_file
10167         local orig_cksum
10168         local dump_cksum
10169         local fid
10170
10171         # ensure corruption will occur on first OSS/OST
10172         $LFS setstripe -i 0 $DIR/$tfile
10173
10174         [ ! -f $F77_TMP ] && setup_f77
10175         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10176                 error "dd write error: $?"
10177         fid=$($LFS path2fid $DIR/$tfile)
10178
10179         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10180         then
10181                 check_ost=true
10182                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10183                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10184         else
10185                 echo "OSS do not support bulk pages dump upon error"
10186         fi
10187
10188         osc_file_prefix=$($LCTL get_param -n debug_path)
10189         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10190
10191         trap cleanup_77c EXIT
10192
10193         set_checksums 1
10194         # enable bulk pages dump upon error on Client
10195         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10196         # enable bulk pages dump upon error on OSS
10197         $check_ost &&
10198                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10199
10200         # flush Client cache to allow next read to reach OSS
10201         cancel_lru_locks osc
10202
10203         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10204         $LCTL set_param fail_loc=0x80000408
10205         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10206         $LCTL set_param fail_loc=0
10207
10208         rm -f $DIR/$tfile
10209
10210         # check cksum dump on Client
10211         osc_file=$(ls ${osc_file_prefix}*)
10212         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10213         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10214         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10215         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10216         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10217                      cksum)
10218         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10219         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10220                 error "dump content does not match on Client"
10221
10222         $check_ost || skip "No need to check cksum dump on OSS"
10223
10224         # check cksum dump on OSS
10225         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10226         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10227         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10228         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10229         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10230                 error "dump content does not match on OSS"
10231
10232         cleanup_77c
10233 }
10234 run_test 77c "checksum error on client read with debug"
10235
10236 test_77d() { # bug 10889
10237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10238         $GSS && skip_env "could not run with gss"
10239
10240         stack_trap "rm -f $DIR/$tfile"
10241         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10242         $LCTL set_param fail_loc=0x80000409
10243         set_checksums 1
10244         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10245                 error "direct write: rc=$?"
10246         $LCTL set_param fail_loc=0
10247         set_checksums 0
10248
10249         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10250         $LCTL set_param fail_loc=0x80000408
10251         set_checksums 1
10252         cancel_lru_locks osc
10253         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10254                 error "direct read: rc=$?"
10255         $LCTL set_param fail_loc=0
10256         set_checksums 0
10257 }
10258 run_test 77d "checksum error on OST direct write, read"
10259
10260 test_77f() { # bug 10889
10261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10262         $GSS && skip_env "could not run with gss"
10263
10264         set_checksums 1
10265         stack_trap "rm -f $DIR/$tfile"
10266         for algo in $CKSUM_TYPES; do
10267                 cancel_lru_locks osc
10268                 set_checksum_type $algo
10269                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10270                 $LCTL set_param fail_loc=0x409
10271                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10272                         error "direct write succeeded"
10273                 $LCTL set_param fail_loc=0
10274         done
10275         set_checksum_type $ORIG_CSUM_TYPE
10276         set_checksums 0
10277 }
10278 run_test 77f "repeat checksum error on write (expect error)"
10279
10280 test_77g() { # bug 10889
10281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10282         $GSS && skip_env "could not run with gss"
10283         remote_ost_nodsh && skip "remote OST with nodsh"
10284
10285         [ ! -f $F77_TMP ] && setup_f77
10286
10287         local file=$DIR/$tfile
10288         stack_trap "rm -f $file" EXIT
10289
10290         $LFS setstripe -c 1 -i 0 $file
10291         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10292         do_facet ost1 lctl set_param fail_loc=0x8000021a
10293         set_checksums 1
10294         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10295                 error "write error: rc=$?"
10296         do_facet ost1 lctl set_param fail_loc=0
10297         set_checksums 0
10298
10299         cancel_lru_locks osc
10300         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10301         do_facet ost1 lctl set_param fail_loc=0x8000021b
10302         set_checksums 1
10303         cmp $F77_TMP $file || error "file compare failed"
10304         do_facet ost1 lctl set_param fail_loc=0
10305         set_checksums 0
10306 }
10307 run_test 77g "checksum error on OST write, read"
10308
10309 test_77k() { # LU-10906
10310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10311         $GSS && skip_env "could not run with gss"
10312
10313         local cksum_param="osc.$FSNAME*.checksums"
10314         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10315         local checksum
10316         local i
10317
10318         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10319         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10320         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10321
10322         for i in 0 1; do
10323                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10324                         error "failed to set checksum=$i on MGS"
10325                 wait_update $HOSTNAME "$get_checksum" $i
10326                 #remount
10327                 echo "remount client, checksum should be $i"
10328                 remount_client $MOUNT || error "failed to remount client"
10329                 checksum=$(eval $get_checksum)
10330                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10331         done
10332         # remove persistent param to avoid races with checksum mountopt below
10333         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10334                 error "failed to delete checksum on MGS"
10335
10336         for opt in "checksum" "nochecksum"; do
10337                 #remount with mount option
10338                 echo "remount client with option $opt, checksum should be $i"
10339                 umount_client $MOUNT || error "failed to umount client"
10340                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10341                         error "failed to mount client with option '$opt'"
10342                 checksum=$(eval $get_checksum)
10343                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10344                 i=$((i - 1))
10345         done
10346
10347         remount_client $MOUNT || error "failed to remount client"
10348 }
10349 run_test 77k "enable/disable checksum correctly"
10350
10351 test_77l() {
10352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10353         $GSS && skip_env "could not run with gss"
10354
10355         set_checksums 1
10356         stack_trap "set_checksums $ORIG_CSUM" EXIT
10357         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10358
10359         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10360
10361         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10362         for algo in $CKSUM_TYPES; do
10363                 set_checksum_type $algo || error "fail to set checksum type $algo"
10364                 osc_algo=$(get_osc_checksum_type OST0000)
10365                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10366
10367                 # no locks, no reqs to let the connection idle
10368                 cancel_lru_locks osc
10369                 lru_resize_disable osc
10370                 wait_osc_import_state client ost1 IDLE
10371
10372                 # ensure ost1 is connected
10373                 stat $DIR/$tfile >/dev/null || error "can't stat"
10374                 wait_osc_import_state client ost1 FULL
10375
10376                 osc_algo=$(get_osc_checksum_type OST0000)
10377                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10378         done
10379         return 0
10380 }
10381 run_test 77l "preferred checksum type is remembered after reconnected"
10382
10383 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10384 rm -f $F77_TMP
10385 unset F77_TMP
10386
10387 test_77m() {
10388         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10389                 skip "Need at least version 2.14.52"
10390         local param=checksum_speed
10391
10392         $LCTL get_param $param || error "reading $param failed"
10393
10394         csum_speeds=$($LCTL get_param -n $param)
10395
10396         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10397                 error "known checksum types are missing"
10398 }
10399 run_test 77m "Verify checksum_speed is correctly read"
10400
10401 check_filefrag_77n() {
10402         local nr_ext=0
10403         local starts=()
10404         local ends=()
10405
10406         while read extidx a b start end rest; do
10407                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10408                         nr_ext=$(( $nr_ext + 1 ))
10409                         starts+=( ${start%..} )
10410                         ends+=( ${end%:} )
10411                 fi
10412         done < <( filefrag -sv $1 )
10413
10414         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10415         return 1
10416 }
10417
10418 test_77n() {
10419         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10420
10421         touch $DIR/$tfile
10422         $TRUNCATE $DIR/$tfile 0
10423         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10424         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10425         check_filefrag_77n $DIR/$tfile ||
10426                 skip "$tfile blocks not contiguous around hole"
10427
10428         set_checksums 1
10429         stack_trap "set_checksums $ORIG_CSUM" EXIT
10430         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10431         stack_trap "rm -f $DIR/$tfile"
10432
10433         for algo in $CKSUM_TYPES; do
10434                 if [[ "$algo" =~ ^t10 ]]; then
10435                         set_checksum_type $algo ||
10436                                 error "fail to set checksum type $algo"
10437                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10438                                 error "fail to read $tfile with $algo"
10439                 fi
10440         done
10441         rm -f $DIR/$tfile
10442         return 0
10443 }
10444 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10445
10446 test_77o() {
10447         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10448                 skip "Need MDS version at least 2.14.55"
10449         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10450                 skip "Need OST version at least 2.14.55"
10451         local ofd=obdfilter
10452         local mdt=mdt
10453
10454         # print OST checksum_type
10455         echo "$ofd.$FSNAME-*.checksum_type:"
10456         do_nodes $(comma_list $(osts_nodes)) \
10457                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10458
10459         # print MDT checksum_type
10460         echo "$mdt.$FSNAME-*.checksum_type:"
10461         do_nodes $(comma_list $(mdts_nodes)) \
10462                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10463
10464         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10465                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10466
10467         (( $o_count == $OSTCOUNT )) ||
10468                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10469
10470         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10471                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10472
10473         (( $m_count == $MDSCOUNT )) ||
10474                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10475 }
10476 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10477
10478 cleanup_test_78() {
10479         trap 0
10480         rm -f $DIR/$tfile
10481 }
10482
10483 test_78() { # bug 10901
10484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10485         remote_ost || skip_env "local OST"
10486
10487         NSEQ=5
10488         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10489         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10490         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10491         echo "MemTotal: $MEMTOTAL"
10492
10493         # reserve 256MB of memory for the kernel and other running processes,
10494         # and then take 1/2 of the remaining memory for the read/write buffers.
10495         if [ $MEMTOTAL -gt 512 ] ;then
10496                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10497         else
10498                 # for those poor memory-starved high-end clusters...
10499                 MEMTOTAL=$((MEMTOTAL / 2))
10500         fi
10501         echo "Mem to use for directio: $MEMTOTAL"
10502
10503         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10504         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10505         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10506         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10507                 head -n1)
10508         echo "Smallest OST: $SMALLESTOST"
10509         [[ $SMALLESTOST -lt 10240 ]] &&
10510                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10511
10512         trap cleanup_test_78 EXIT
10513
10514         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10515                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10516
10517         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10518         echo "File size: $F78SIZE"
10519         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10520         for i in $(seq 1 $NSEQ); do
10521                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10522                 echo directIO rdwr round $i of $NSEQ
10523                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10524         done
10525
10526         cleanup_test_78
10527 }
10528 run_test 78 "handle large O_DIRECT writes correctly ============"
10529
10530 test_79() { # bug 12743
10531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10532
10533         wait_delete_completed
10534
10535         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10536         BKFREE=$(calc_osc_kbytes kbytesfree)
10537         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10538
10539         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10540         DFTOTAL=`echo $STRING | cut -d, -f1`
10541         DFUSED=`echo $STRING  | cut -d, -f2`
10542         DFAVAIL=`echo $STRING | cut -d, -f3`
10543         DFFREE=$(($DFTOTAL - $DFUSED))
10544
10545         ALLOWANCE=$((64 * $OSTCOUNT))
10546
10547         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10548            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10549                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10550         fi
10551         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10552            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10553                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10554         fi
10555         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10556            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10557                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10558         fi
10559 }
10560 run_test 79 "df report consistency check ======================="
10561
10562 test_80() { # bug 10718
10563         remote_ost_nodsh && skip "remote OST with nodsh"
10564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10565
10566         # relax strong synchronous semantics for slow backends like ZFS
10567         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10568                 local soc="obdfilter.*.sync_lock_cancel"
10569                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10570
10571                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10572                 if [ -z "$save" ]; then
10573                         soc="obdfilter.*.sync_on_lock_cancel"
10574                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10575                 fi
10576
10577                 if [ "$save" != "never" ]; then
10578                         local hosts=$(comma_list $(osts_nodes))
10579
10580                         do_nodes $hosts $LCTL set_param $soc=never
10581                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10582                 fi
10583         fi
10584
10585         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10586         sync; sleep 1; sync
10587         local before=$(date +%s)
10588         cancel_lru_locks osc
10589         local after=$(date +%s)
10590         local diff=$((after - before))
10591         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10592
10593         rm -f $DIR/$tfile
10594 }
10595 run_test 80 "Page eviction is equally fast at high offsets too"
10596
10597 test_81a() { # LU-456
10598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10599         remote_ost_nodsh && skip "remote OST with nodsh"
10600
10601         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10602         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10603         do_facet ost1 lctl set_param fail_loc=0x80000228
10604
10605         # write should trigger a retry and success
10606         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10607         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10608         RC=$?
10609         if [ $RC -ne 0 ] ; then
10610                 error "write should success, but failed for $RC"
10611         fi
10612 }
10613 run_test 81a "OST should retry write when get -ENOSPC ==============="
10614
10615 test_81b() { # LU-456
10616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10617         remote_ost_nodsh && skip "remote OST with nodsh"
10618
10619         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10620         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10621         do_facet ost1 lctl set_param fail_loc=0x228
10622
10623         # write should retry several times and return -ENOSPC finally
10624         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10625         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10626         RC=$?
10627         ENOSPC=28
10628         if [ $RC -ne $ENOSPC ] ; then
10629                 error "dd should fail for -ENOSPC, but succeed."
10630         fi
10631 }
10632 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10633
10634 test_99() {
10635         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10636
10637         test_mkdir $DIR/$tdir.cvsroot
10638         chown $RUNAS_ID $DIR/$tdir.cvsroot
10639
10640         cd $TMP
10641         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10642
10643         cd /etc/init.d
10644         # some versions of cvs import exit(1) when asked to import links or
10645         # files they can't read.  ignore those files.
10646         local toignore=$(find . -type l -printf '-I %f\n' -o \
10647                          ! -perm /4 -printf '-I %f\n')
10648         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10649                 $tdir.reposname vtag rtag
10650
10651         cd $DIR
10652         test_mkdir $DIR/$tdir.reposname
10653         chown $RUNAS_ID $DIR/$tdir.reposname
10654         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10655
10656         cd $DIR/$tdir.reposname
10657         $RUNAS touch foo99
10658         $RUNAS cvs add -m 'addmsg' foo99
10659         $RUNAS cvs update
10660         $RUNAS cvs commit -m 'nomsg' foo99
10661         rm -fr $DIR/$tdir.cvsroot
10662 }
10663 run_test 99 "cvs strange file/directory operations"
10664
10665 test_100() {
10666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10667         [[ "$NETTYPE" =~ tcp ]] ||
10668                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10669         remote_ost_nodsh && skip "remote OST with nodsh"
10670         remote_mds_nodsh && skip "remote MDS with nodsh"
10671         remote_servers ||
10672                 skip "useless for local single node setup"
10673
10674         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10675                 [ "$PROT" != "tcp" ] && continue
10676                 RPORT=$(echo $REMOTE | cut -d: -f2)
10677                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10678
10679                 rc=0
10680                 LPORT=`echo $LOCAL | cut -d: -f2`
10681                 if [ $LPORT -ge 1024 ]; then
10682                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10683                         netstat -tna
10684                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10685                 fi
10686         done
10687         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10688 }
10689 run_test 100 "check local port using privileged port ==========="
10690
10691 function get_named_value()
10692 {
10693     local tag=$1
10694
10695     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10696 }
10697
10698 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10699                    awk '/^max_cached_mb/ { print $2 }')
10700
10701 cleanup_101a() {
10702         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10703         trap 0
10704 }
10705
10706 test_101a() {
10707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10708
10709         local s
10710         local discard
10711         local nreads=10000
10712         local cache_limit=32
10713
10714         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10715         trap cleanup_101a EXIT
10716         $LCTL set_param -n llite.*.read_ahead_stats=0
10717         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10718
10719         #
10720         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10721         #
10722         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10723         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10724
10725         discard=0
10726         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10727                    get_named_value 'read.but.discarded'); do
10728                         discard=$(($discard + $s))
10729         done
10730         cleanup_101a
10731
10732         $LCTL get_param osc.*-osc*.rpc_stats
10733         $LCTL get_param llite.*.read_ahead_stats
10734
10735         # Discard is generally zero, but sometimes a few random reads line up
10736         # and trigger larger readahead, which is wasted & leads to discards.
10737         if [[ $(($discard)) -gt $nreads ]]; then
10738                 error "too many ($discard) discarded pages"
10739         fi
10740         rm -f $DIR/$tfile || true
10741 }
10742 run_test 101a "check read-ahead for random reads"
10743
10744 setup_test101bc() {
10745         test_mkdir $DIR/$tdir
10746         local ssize=$1
10747         local FILE_LENGTH=$2
10748         STRIPE_OFFSET=0
10749
10750         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10751
10752         local list=$(comma_list $(osts_nodes))
10753         set_osd_param $list '' read_cache_enable 0
10754         set_osd_param $list '' writethrough_cache_enable 0
10755
10756         trap cleanup_test101bc EXIT
10757         # prepare the read-ahead file
10758         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10759
10760         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10761                                 count=$FILE_SIZE_MB 2> /dev/null
10762
10763 }
10764
10765 cleanup_test101bc() {
10766         trap 0
10767         rm -rf $DIR/$tdir
10768         rm -f $DIR/$tfile
10769
10770         local list=$(comma_list $(osts_nodes))
10771         set_osd_param $list '' read_cache_enable 1
10772         set_osd_param $list '' writethrough_cache_enable 1
10773 }
10774
10775 calc_total() {
10776         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10777 }
10778
10779 ra_check_101() {
10780         local read_size=$1
10781         local stripe_size=$2
10782         local stride_length=$((stripe_size / read_size))
10783         local stride_width=$((stride_length * OSTCOUNT))
10784         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10785                                 (stride_width - stride_length) ))
10786         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10787                   get_named_value 'read.but.discarded' | calc_total)
10788
10789         if [[ $discard -gt $discard_limit ]]; then
10790                 $LCTL get_param llite.*.read_ahead_stats
10791                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10792         else
10793                 echo "Read-ahead success for size ${read_size}"
10794         fi
10795 }
10796
10797 test_101b() {
10798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10800
10801         local STRIPE_SIZE=1048576
10802         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10803
10804         if [ $SLOW == "yes" ]; then
10805                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10806         else
10807                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10808         fi
10809
10810         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10811
10812         # prepare the read-ahead file
10813         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10814         cancel_lru_locks osc
10815         for BIDX in 2 4 8 16 32 64 128 256
10816         do
10817                 local BSIZE=$((BIDX*4096))
10818                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10819                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10820                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10821                 $LCTL set_param -n llite.*.read_ahead_stats=0
10822                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10823                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10824                 cancel_lru_locks osc
10825                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10826         done
10827         cleanup_test101bc
10828         true
10829 }
10830 run_test 101b "check stride-io mode read-ahead ================="
10831
10832 test_101c() {
10833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10834
10835         local STRIPE_SIZE=1048576
10836         local FILE_LENGTH=$((STRIPE_SIZE*100))
10837         local nreads=10000
10838         local rsize=65536
10839         local osc_rpc_stats
10840
10841         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10842
10843         cancel_lru_locks osc
10844         $LCTL set_param osc.*.rpc_stats=0
10845         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10846         $LCTL get_param osc.*.rpc_stats
10847         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10848                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10849                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10850                 local size
10851
10852                 if [ $lines -le 20 ]; then
10853                         echo "continue debug"
10854                         continue
10855                 fi
10856                 for size in 1 2 4 8; do
10857                         local rpc=$(echo "$stats" |
10858                                     awk '($1 == "'$size':") {print $2; exit; }')
10859                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10860                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10861                 done
10862                 echo "$osc_rpc_stats check passed!"
10863         done
10864         cleanup_test101bc
10865         true
10866 }
10867 run_test 101c "check stripe_size aligned read-ahead"
10868
10869 test_101d() {
10870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10871
10872         local file=$DIR/$tfile
10873         local sz_MB=${FILESIZE_101d:-80}
10874         local ra_MB=${READAHEAD_MB:-40}
10875
10876         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10877         [ $free_MB -lt $sz_MB ] &&
10878                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10879
10880         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10881         $LFS setstripe -c -1 $file || error "setstripe failed"
10882
10883         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10884         echo Cancel LRU locks on lustre client to flush the client cache
10885         cancel_lru_locks osc
10886
10887         echo Disable read-ahead
10888         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10889         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10890         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10891         $LCTL get_param -n llite.*.max_read_ahead_mb
10892
10893         echo "Reading the test file $file with read-ahead disabled"
10894         local sz_KB=$((sz_MB * 1024 / 4))
10895         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10896         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10897         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10898                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10899
10900         echo "Cancel LRU locks on lustre client to flush the client cache"
10901         cancel_lru_locks osc
10902         echo Enable read-ahead with ${ra_MB}MB
10903         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10904
10905         echo "Reading the test file $file with read-ahead enabled"
10906         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10907                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10908
10909         echo "read-ahead disabled time read $raOFF"
10910         echo "read-ahead enabled time read $raON"
10911
10912         rm -f $file
10913         wait_delete_completed
10914
10915         # use awk for this check instead of bash because it handles decimals
10916         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10917                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10918 }
10919 run_test 101d "file read with and without read-ahead enabled"
10920
10921 test_101e() {
10922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10923
10924         local file=$DIR/$tfile
10925         local size_KB=500  #KB
10926         local count=100
10927         local bsize=1024
10928
10929         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10930         local need_KB=$((count * size_KB))
10931         [[ $free_KB -le $need_KB ]] &&
10932                 skip_env "Need free space $need_KB, have $free_KB"
10933
10934         echo "Creating $count ${size_KB}K test files"
10935         for ((i = 0; i < $count; i++)); do
10936                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10937         done
10938
10939         echo "Cancel LRU locks on lustre client to flush the client cache"
10940         cancel_lru_locks $OSC
10941
10942         echo "Reset readahead stats"
10943         $LCTL set_param -n llite.*.read_ahead_stats=0
10944
10945         for ((i = 0; i < $count; i++)); do
10946                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10947         done
10948
10949         $LCTL get_param llite.*.max_cached_mb
10950         $LCTL get_param llite.*.read_ahead_stats
10951         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10952                      get_named_value 'misses' | calc_total)
10953
10954         for ((i = 0; i < $count; i++)); do
10955                 rm -rf $file.$i 2>/dev/null
10956         done
10957
10958         #10000 means 20% reads are missing in readahead
10959         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10960 }
10961 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10962
10963 test_101f() {
10964         which iozone || skip_env "no iozone installed"
10965
10966         local old_debug=$($LCTL get_param debug)
10967         old_debug=${old_debug#*=}
10968         $LCTL set_param debug="reada mmap"
10969
10970         # create a test file
10971         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10972
10973         echo Cancel LRU locks on lustre client to flush the client cache
10974         cancel_lru_locks osc
10975
10976         echo Reset readahead stats
10977         $LCTL set_param -n llite.*.read_ahead_stats=0
10978
10979         echo mmap read the file with small block size
10980         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10981                 > /dev/null 2>&1
10982
10983         echo checking missing pages
10984         $LCTL get_param llite.*.read_ahead_stats
10985         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10986                         get_named_value 'misses' | calc_total)
10987
10988         $LCTL set_param debug="$old_debug"
10989         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10990         rm -f $DIR/$tfile
10991 }
10992 run_test 101f "check mmap read performance"
10993
10994 test_101g_brw_size_test() {
10995         local mb=$1
10996         local pages=$((mb * 1048576 / PAGE_SIZE))
10997         local file=$DIR/$tfile
10998
10999         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11000                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11001         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11002                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11003                         return 2
11004         done
11005
11006         stack_trap "rm -f $file" EXIT
11007         $LCTL set_param -n osc.*.rpc_stats=0
11008
11009         # 10 RPCs should be enough for the test
11010         local count=10
11011         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11012                 { error "dd write ${mb} MB blocks failed"; return 3; }
11013         cancel_lru_locks osc
11014         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11015                 { error "dd write ${mb} MB blocks failed"; return 4; }
11016
11017         # calculate number of full-sized read and write RPCs
11018         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11019                 sed -n '/pages per rpc/,/^$/p' |
11020                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11021                 END { print reads,writes }'))
11022         # allow one extra full-sized read RPC for async readahead
11023         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11024                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11025         [[ ${rpcs[1]} == $count ]] ||
11026                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11027 }
11028
11029 test_101g() {
11030         remote_ost_nodsh && skip "remote OST with nodsh"
11031
11032         local rpcs
11033         local osts=$(get_facets OST)
11034         local list=$(comma_list $(osts_nodes))
11035         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11036         local brw_size="obdfilter.*.brw_size"
11037
11038         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11039
11040         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11041
11042         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11043                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11044                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11045            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11046                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11047                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11048
11049                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11050                         suffix="M"
11051
11052                 if [[ $orig_mb -lt 16 ]]; then
11053                         save_lustre_params $osts "$brw_size" > $p
11054                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11055                                 error "set 16MB RPC size failed"
11056
11057                         echo "remount client to enable new RPC size"
11058                         remount_client $MOUNT || error "remount_client failed"
11059                 fi
11060
11061                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11062                 # should be able to set brw_size=12, but no rpc_stats for that
11063                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11064         fi
11065
11066         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11067
11068         if [[ $orig_mb -lt 16 ]]; then
11069                 restore_lustre_params < $p
11070                 remount_client $MOUNT || error "remount_client restore failed"
11071         fi
11072
11073         rm -f $p $DIR/$tfile
11074 }
11075 run_test 101g "Big bulk(4/16 MiB) readahead"
11076
11077 test_101h() {
11078         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11079
11080         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11081                 error "dd 70M file failed"
11082         echo Cancel LRU locks on lustre client to flush the client cache
11083         cancel_lru_locks osc
11084
11085         echo "Reset readahead stats"
11086         $LCTL set_param -n llite.*.read_ahead_stats 0
11087
11088         echo "Read 10M of data but cross 64M bundary"
11089         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11090         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11091                      get_named_value 'misses' | calc_total)
11092         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11093         rm -f $p $DIR/$tfile
11094 }
11095 run_test 101h "Readahead should cover current read window"
11096
11097 test_101i() {
11098         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11099                 error "dd 10M file failed"
11100
11101         local max_per_file_mb=$($LCTL get_param -n \
11102                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11103         cancel_lru_locks osc
11104         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11105         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11106                 error "set max_read_ahead_per_file_mb to 1 failed"
11107
11108         echo "Reset readahead stats"
11109         $LCTL set_param llite.*.read_ahead_stats=0
11110
11111         dd if=$DIR/$tfile of=/dev/null bs=2M
11112
11113         $LCTL get_param llite.*.read_ahead_stats
11114         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11115                      awk '/misses/ { print $2 }')
11116         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11117         rm -f $DIR/$tfile
11118 }
11119 run_test 101i "allow current readahead to exceed reservation"
11120
11121 test_101j() {
11122         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11123                 error "setstripe $DIR/$tfile failed"
11124         local file_size=$((1048576 * 16))
11125         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11126         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11127
11128         echo Disable read-ahead
11129         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11130
11131         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11132         for blk in $PAGE_SIZE 1048576 $file_size; do
11133                 cancel_lru_locks osc
11134                 echo "Reset readahead stats"
11135                 $LCTL set_param -n llite.*.read_ahead_stats=0
11136                 local count=$(($file_size / $blk))
11137                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11138                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11139                              get_named_value 'failed.to.fast.read' | calc_total)
11140                 $LCTL get_param -n llite.*.read_ahead_stats
11141                 [ $miss -eq $count ] || error "expected $count got $miss"
11142         done
11143
11144         rm -f $p $DIR/$tfile
11145 }
11146 run_test 101j "A complete read block should be submitted when no RA"
11147
11148 setup_test102() {
11149         test_mkdir $DIR/$tdir
11150         chown $RUNAS_ID $DIR/$tdir
11151         STRIPE_SIZE=65536
11152         STRIPE_OFFSET=1
11153         STRIPE_COUNT=$OSTCOUNT
11154         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11155
11156         trap cleanup_test102 EXIT
11157         cd $DIR
11158         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11159         cd $DIR/$tdir
11160         for num in 1 2 3 4; do
11161                 for count in $(seq 1 $STRIPE_COUNT); do
11162                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11163                                 local size=`expr $STRIPE_SIZE \* $num`
11164                                 local file=file"$num-$idx-$count"
11165                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11166                         done
11167                 done
11168         done
11169
11170         cd $DIR
11171         $1 tar cf $TMP/f102.tar $tdir --xattrs
11172 }
11173
11174 cleanup_test102() {
11175         trap 0
11176         rm -f $TMP/f102.tar
11177         rm -rf $DIR/d0.sanity/d102
11178 }
11179
11180 test_102a() {
11181         [ "$UID" != 0 ] && skip "must run as root"
11182         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11183                 skip_env "must have user_xattr"
11184
11185         [ -z "$(which setfattr 2>/dev/null)" ] &&
11186                 skip_env "could not find setfattr"
11187
11188         local testfile=$DIR/$tfile
11189
11190         touch $testfile
11191         echo "set/get xattr..."
11192         setfattr -n trusted.name1 -v value1 $testfile ||
11193                 error "setfattr -n trusted.name1=value1 $testfile failed"
11194         getfattr -n trusted.name1 $testfile 2> /dev/null |
11195           grep "trusted.name1=.value1" ||
11196                 error "$testfile missing trusted.name1=value1"
11197
11198         setfattr -n user.author1 -v author1 $testfile ||
11199                 error "setfattr -n user.author1=author1 $testfile failed"
11200         getfattr -n user.author1 $testfile 2> /dev/null |
11201           grep "user.author1=.author1" ||
11202                 error "$testfile missing trusted.author1=author1"
11203
11204         echo "listxattr..."
11205         setfattr -n trusted.name2 -v value2 $testfile ||
11206                 error "$testfile unable to set trusted.name2"
11207         setfattr -n trusted.name3 -v value3 $testfile ||
11208                 error "$testfile unable to set trusted.name3"
11209         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11210             grep "trusted.name" | wc -l) -eq 3 ] ||
11211                 error "$testfile missing 3 trusted.name xattrs"
11212
11213         setfattr -n user.author2 -v author2 $testfile ||
11214                 error "$testfile unable to set user.author2"
11215         setfattr -n user.author3 -v author3 $testfile ||
11216                 error "$testfile unable to set user.author3"
11217         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11218             grep "user.author" | wc -l) -eq 3 ] ||
11219                 error "$testfile missing 3 user.author xattrs"
11220
11221         echo "remove xattr..."
11222         setfattr -x trusted.name1 $testfile ||
11223                 error "$testfile error deleting trusted.name1"
11224         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11225                 error "$testfile did not delete trusted.name1 xattr"
11226
11227         setfattr -x user.author1 $testfile ||
11228                 error "$testfile error deleting user.author1"
11229         echo "set lustre special xattr ..."
11230         $LFS setstripe -c1 $testfile
11231         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11232                 awk -F "=" '/trusted.lov/ { print $2 }' )
11233         setfattr -n "trusted.lov" -v $lovea $testfile ||
11234                 error "$testfile doesn't ignore setting trusted.lov again"
11235         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11236                 error "$testfile allow setting invalid trusted.lov"
11237         rm -f $testfile
11238 }
11239 run_test 102a "user xattr test =================================="
11240
11241 check_102b_layout() {
11242         local layout="$*"
11243         local testfile=$DIR/$tfile
11244
11245         echo "test layout '$layout'"
11246         $LFS setstripe $layout $testfile || error "setstripe failed"
11247         $LFS getstripe -y $testfile
11248
11249         echo "get/set/list trusted.lov xattr ..." # b=10930
11250         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11251         [[ "$value" =~ "trusted.lov" ]] ||
11252                 error "can't get trusted.lov from $testfile"
11253         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11254                 error "getstripe failed"
11255
11256         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11257
11258         value=$(cut -d= -f2 <<<$value)
11259         # LU-13168: truncated xattr should fail if short lov_user_md header
11260         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11261                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11262         for len in $lens; do
11263                 echo "setfattr $len $testfile.2"
11264                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11265                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11266         done
11267         local stripe_size=$($LFS getstripe -S $testfile.2)
11268         local stripe_count=$($LFS getstripe -c $testfile.2)
11269         [[ $stripe_size -eq 65536 ]] ||
11270                 error "stripe size $stripe_size != 65536"
11271         [[ $stripe_count -eq $stripe_count_orig ]] ||
11272                 error "stripe count $stripe_count != $stripe_count_orig"
11273         rm $testfile $testfile.2
11274 }
11275
11276 test_102b() {
11277         [ -z "$(which setfattr 2>/dev/null)" ] &&
11278                 skip_env "could not find setfattr"
11279         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11280
11281         # check plain layout
11282         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11283
11284         # and also check composite layout
11285         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11286
11287 }
11288 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11289
11290 test_102c() {
11291         [ -z "$(which setfattr 2>/dev/null)" ] &&
11292                 skip_env "could not find setfattr"
11293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11294
11295         # b10930: get/set/list lustre.lov xattr
11296         echo "get/set/list lustre.lov xattr ..."
11297         test_mkdir $DIR/$tdir
11298         chown $RUNAS_ID $DIR/$tdir
11299         local testfile=$DIR/$tdir/$tfile
11300         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11301                 error "setstripe failed"
11302         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11303                 error "getstripe failed"
11304         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11305         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11306
11307         local testfile2=${testfile}2
11308         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11309                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11310
11311         $RUNAS $MCREATE $testfile2
11312         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11313         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11314         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11315         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11316         [ $stripe_count -eq $STRIPECOUNT ] ||
11317                 error "stripe count $stripe_count != $STRIPECOUNT"
11318 }
11319 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11320
11321 compare_stripe_info1() {
11322         local stripe_index_all_zero=true
11323
11324         for num in 1 2 3 4; do
11325                 for count in $(seq 1 $STRIPE_COUNT); do
11326                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11327                                 local size=$((STRIPE_SIZE * num))
11328                                 local file=file"$num-$offset-$count"
11329                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11330                                 [[ $stripe_size -ne $size ]] &&
11331                                     error "$file: size $stripe_size != $size"
11332                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11333                                 # allow fewer stripes to be created, ORI-601
11334                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11335                                     error "$file: count $stripe_count != $count"
11336                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11337                                 [[ $stripe_index -ne 0 ]] &&
11338                                         stripe_index_all_zero=false
11339                         done
11340                 done
11341         done
11342         $stripe_index_all_zero &&
11343                 error "all files are being extracted starting from OST index 0"
11344         return 0
11345 }
11346
11347 have_xattrs_include() {
11348         tar --help | grep -q xattrs-include &&
11349                 echo --xattrs-include="lustre.*"
11350 }
11351
11352 test_102d() {
11353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11354         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11355
11356         XINC=$(have_xattrs_include)
11357         setup_test102
11358         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11359         cd $DIR/$tdir/$tdir
11360         compare_stripe_info1
11361 }
11362 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11363
11364 test_102f() {
11365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11367
11368         XINC=$(have_xattrs_include)
11369         setup_test102
11370         test_mkdir $DIR/$tdir.restore
11371         cd $DIR
11372         tar cf - --xattrs $tdir | tar xf - \
11373                 -C $DIR/$tdir.restore --xattrs $XINC
11374         cd $DIR/$tdir.restore/$tdir
11375         compare_stripe_info1
11376 }
11377 run_test 102f "tar copy files, not keep osts"
11378
11379 grow_xattr() {
11380         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11381                 skip "must have user_xattr"
11382         [ -z "$(which setfattr 2>/dev/null)" ] &&
11383                 skip_env "could not find setfattr"
11384         [ -z "$(which getfattr 2>/dev/null)" ] &&
11385                 skip_env "could not find getfattr"
11386
11387         local xsize=${1:-1024}  # in bytes
11388         local file=$DIR/$tfile
11389         local value="$(generate_string $xsize)"
11390         local xbig=trusted.big
11391         local toobig=$2
11392
11393         touch $file
11394         log "save $xbig on $file"
11395         if [ -z "$toobig" ]
11396         then
11397                 setfattr -n $xbig -v $value $file ||
11398                         error "saving $xbig on $file failed"
11399         else
11400                 setfattr -n $xbig -v $value $file &&
11401                         error "saving $xbig on $file succeeded"
11402                 return 0
11403         fi
11404
11405         local orig=$(get_xattr_value $xbig $file)
11406         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11407
11408         local xsml=trusted.sml
11409         log "save $xsml on $file"
11410         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11411
11412         local new=$(get_xattr_value $xbig $file)
11413         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11414
11415         log "grow $xsml on $file"
11416         setfattr -n $xsml -v "$value" $file ||
11417                 error "growing $xsml on $file failed"
11418
11419         new=$(get_xattr_value $xbig $file)
11420         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11421         log "$xbig still valid after growing $xsml"
11422
11423         rm -f $file
11424 }
11425
11426 test_102h() { # bug 15777
11427         grow_xattr 1024
11428 }
11429 run_test 102h "grow xattr from inside inode to external block"
11430
11431 test_102ha() {
11432         large_xattr_enabled || skip_env "ea_inode feature disabled"
11433
11434         echo "setting xattr of max xattr size: $(max_xattr_size)"
11435         grow_xattr $(max_xattr_size)
11436
11437         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11438         echo "This should fail:"
11439         grow_xattr $(($(max_xattr_size) + 10)) 1
11440 }
11441 run_test 102ha "grow xattr from inside inode to external inode"
11442
11443 test_102i() { # bug 17038
11444         [ -z "$(which getfattr 2>/dev/null)" ] &&
11445                 skip "could not find getfattr"
11446
11447         touch $DIR/$tfile
11448         ln -s $DIR/$tfile $DIR/${tfile}link
11449         getfattr -n trusted.lov $DIR/$tfile ||
11450                 error "lgetxattr on $DIR/$tfile failed"
11451         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11452                 grep -i "no such attr" ||
11453                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11454         rm -f $DIR/$tfile $DIR/${tfile}link
11455 }
11456 run_test 102i "lgetxattr test on symbolic link ============"
11457
11458 test_102j() {
11459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11460         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11461
11462         XINC=$(have_xattrs_include)
11463         setup_test102 "$RUNAS"
11464         chown $RUNAS_ID $DIR/$tdir
11465         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11466         cd $DIR/$tdir/$tdir
11467         compare_stripe_info1 "$RUNAS"
11468 }
11469 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11470
11471 test_102k() {
11472         [ -z "$(which setfattr 2>/dev/null)" ] &&
11473                 skip "could not find setfattr"
11474
11475         touch $DIR/$tfile
11476         # b22187 just check that does not crash for regular file.
11477         setfattr -n trusted.lov $DIR/$tfile
11478         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11479         local test_kdir=$DIR/$tdir
11480         test_mkdir $test_kdir
11481         local default_size=$($LFS getstripe -S $test_kdir)
11482         local default_count=$($LFS getstripe -c $test_kdir)
11483         local default_offset=$($LFS getstripe -i $test_kdir)
11484         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11485                 error 'dir setstripe failed'
11486         setfattr -n trusted.lov $test_kdir
11487         local stripe_size=$($LFS getstripe -S $test_kdir)
11488         local stripe_count=$($LFS getstripe -c $test_kdir)
11489         local stripe_offset=$($LFS getstripe -i $test_kdir)
11490         [ $stripe_size -eq $default_size ] ||
11491                 error "stripe size $stripe_size != $default_size"
11492         [ $stripe_count -eq $default_count ] ||
11493                 error "stripe count $stripe_count != $default_count"
11494         [ $stripe_offset -eq $default_offset ] ||
11495                 error "stripe offset $stripe_offset != $default_offset"
11496         rm -rf $DIR/$tfile $test_kdir
11497 }
11498 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11499
11500 test_102l() {
11501         [ -z "$(which getfattr 2>/dev/null)" ] &&
11502                 skip "could not find getfattr"
11503
11504         # LU-532 trusted. xattr is invisible to non-root
11505         local testfile=$DIR/$tfile
11506
11507         touch $testfile
11508
11509         echo "listxattr as user..."
11510         chown $RUNAS_ID $testfile
11511         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11512             grep -q "trusted" &&
11513                 error "$testfile trusted xattrs are user visible"
11514
11515         return 0;
11516 }
11517 run_test 102l "listxattr size test =================================="
11518
11519 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11520         local path=$DIR/$tfile
11521         touch $path
11522
11523         listxattr_size_check $path || error "listattr_size_check $path failed"
11524 }
11525 run_test 102m "Ensure listxattr fails on small bufffer ========"
11526
11527 cleanup_test102
11528
11529 getxattr() { # getxattr path name
11530         # Return the base64 encoding of the value of xattr name on path.
11531         local path=$1
11532         local name=$2
11533
11534         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11535         # file: $path
11536         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11537         #
11538         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11539
11540         getfattr --absolute-names --encoding=base64 --name=$name $path |
11541                 awk -F= -v name=$name '$1 == name {
11542                         print substr($0, index($0, "=") + 1);
11543         }'
11544 }
11545
11546 test_102n() { # LU-4101 mdt: protect internal xattrs
11547         [ -z "$(which setfattr 2>/dev/null)" ] &&
11548                 skip "could not find setfattr"
11549         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11550         then
11551                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11552         fi
11553
11554         local file0=$DIR/$tfile.0
11555         local file1=$DIR/$tfile.1
11556         local xattr0=$TMP/$tfile.0
11557         local xattr1=$TMP/$tfile.1
11558         local namelist="lov lma lmv link fid version som hsm"
11559         local name
11560         local value
11561
11562         rm -rf $file0 $file1 $xattr0 $xattr1
11563         touch $file0 $file1
11564
11565         # Get 'before' xattrs of $file1.
11566         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11567
11568         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11569                 namelist+=" lfsck_namespace"
11570         for name in $namelist; do
11571                 # Try to copy xattr from $file0 to $file1.
11572                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11573
11574                 setfattr --name=trusted.$name --value="$value" $file1 ||
11575                         error "setxattr 'trusted.$name' failed"
11576
11577                 # Try to set a garbage xattr.
11578                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11579
11580                 if [[ x$name == "xlov" ]]; then
11581                         setfattr --name=trusted.lov --value="$value" $file1 &&
11582                         error "setxattr invalid 'trusted.lov' success"
11583                 else
11584                         setfattr --name=trusted.$name --value="$value" $file1 ||
11585                                 error "setxattr invalid 'trusted.$name' failed"
11586                 fi
11587
11588                 # Try to remove the xattr from $file1. We don't care if this
11589                 # appears to succeed or fail, we just don't want there to be
11590                 # any changes or crashes.
11591                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11592         done
11593
11594         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11595         then
11596                 name="lfsck_ns"
11597                 # Try to copy xattr from $file0 to $file1.
11598                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11599
11600                 setfattr --name=trusted.$name --value="$value" $file1 ||
11601                         error "setxattr 'trusted.$name' failed"
11602
11603                 # Try to set a garbage xattr.
11604                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11605
11606                 setfattr --name=trusted.$name --value="$value" $file1 ||
11607                         error "setxattr 'trusted.$name' failed"
11608
11609                 # Try to remove the xattr from $file1. We don't care if this
11610                 # appears to succeed or fail, we just don't want there to be
11611                 # any changes or crashes.
11612                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11613         fi
11614
11615         # Get 'after' xattrs of file1.
11616         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11617
11618         if ! diff $xattr0 $xattr1; then
11619                 error "before and after xattrs of '$file1' differ"
11620         fi
11621
11622         rm -rf $file0 $file1 $xattr0 $xattr1
11623
11624         return 0
11625 }
11626 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11627
11628 test_102p() { # LU-4703 setxattr did not check ownership
11629         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11630                 skip "MDS needs to be at least 2.5.56"
11631
11632         local testfile=$DIR/$tfile
11633
11634         touch $testfile
11635
11636         echo "setfacl as user..."
11637         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11638         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11639
11640         echo "setfattr as user..."
11641         setfacl -m "u:$RUNAS_ID:---" $testfile
11642         $RUNAS setfattr -x system.posix_acl_access $testfile
11643         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11644 }
11645 run_test 102p "check setxattr(2) correctly fails without permission"
11646
11647 test_102q() {
11648         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11649                 skip "MDS needs to be at least 2.6.92"
11650
11651         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11652 }
11653 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11654
11655 test_102r() {
11656         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11657                 skip "MDS needs to be at least 2.6.93"
11658
11659         touch $DIR/$tfile || error "touch"
11660         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11661         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11662         rm $DIR/$tfile || error "rm"
11663
11664         #normal directory
11665         mkdir -p $DIR/$tdir || error "mkdir"
11666         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11667         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11668         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11669                 error "$testfile error deleting user.author1"
11670         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11671                 grep "user.$(basename $tdir)" &&
11672                 error "$tdir did not delete user.$(basename $tdir)"
11673         rmdir $DIR/$tdir || error "rmdir"
11674
11675         #striped directory
11676         test_mkdir $DIR/$tdir
11677         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11678         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11679         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11680                 error "$testfile error deleting user.author1"
11681         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11682                 grep "user.$(basename $tdir)" &&
11683                 error "$tdir did not delete user.$(basename $tdir)"
11684         rmdir $DIR/$tdir || error "rm striped dir"
11685 }
11686 run_test 102r "set EAs with empty values"
11687
11688 test_102s() {
11689         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11690                 skip "MDS needs to be at least 2.11.52"
11691
11692         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11693
11694         save_lustre_params client "llite.*.xattr_cache" > $save
11695
11696         for cache in 0 1; do
11697                 lctl set_param llite.*.xattr_cache=$cache
11698
11699                 rm -f $DIR/$tfile
11700                 touch $DIR/$tfile || error "touch"
11701                 for prefix in lustre security system trusted user; do
11702                         # Note getxattr() may fail with 'Operation not
11703                         # supported' or 'No such attribute' depending
11704                         # on prefix and cache.
11705                         getfattr -n $prefix.n102s $DIR/$tfile &&
11706                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11707                 done
11708         done
11709
11710         restore_lustre_params < $save
11711 }
11712 run_test 102s "getting nonexistent xattrs should fail"
11713
11714 test_102t() {
11715         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11716                 skip "MDS needs to be at least 2.11.52"
11717
11718         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11719
11720         save_lustre_params client "llite.*.xattr_cache" > $save
11721
11722         for cache in 0 1; do
11723                 lctl set_param llite.*.xattr_cache=$cache
11724
11725                 for buf_size in 0 256; do
11726                         rm -f $DIR/$tfile
11727                         touch $DIR/$tfile || error "touch"
11728                         setfattr -n user.multiop $DIR/$tfile
11729                         $MULTIOP $DIR/$tfile oa$buf_size ||
11730                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11731                 done
11732         done
11733
11734         restore_lustre_params < $save
11735 }
11736 run_test 102t "zero length xattr values handled correctly"
11737
11738 run_acl_subtest()
11739 {
11740         local test=$LUSTRE/tests/acl/$1.test
11741         local tmp=$(mktemp -t $1-XXXXXX).test
11742         local bin=$2
11743         local dmn=$3
11744         local grp=$4
11745         local nbd=$5
11746         export LANG=C
11747
11748
11749         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11750         local sedgroups="-e s/:users/:$grp/g"
11751         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11752
11753         sed $sedusers $sedgroups < $test > $tmp
11754         stack_trap "rm -f $tmp"
11755         [[ -s $tmp ]] || error "sed failed to create test script"
11756
11757         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11758         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11759 }
11760
11761 test_103a() {
11762         [ "$UID" != 0 ] && skip "must run as root"
11763         $GSS && skip_env "could not run under gss"
11764         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11765                 skip_env "must have acl enabled"
11766         which setfacl || skip_env "could not find setfacl"
11767         remote_mds_nodsh && skip "remote MDS with nodsh"
11768
11769         ACLBIN=${ACLBIN:-"bin"}
11770         ACLDMN=${ACLDMN:-"daemon"}
11771         ACLGRP=${ACLGRP:-"users"}
11772         ACLNBD=${ACLNBD:-"nobody"}
11773
11774         if ! id $ACLBIN ||
11775            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11776                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11777                 ACLBIN=$USER0
11778                 if ! id $ACLBIN ; then
11779                         cat /etc/passwd
11780                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11781                 fi
11782         fi
11783         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11784            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11785                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11786                 ACLDMN=$USER1
11787                 if ! id $ACLDMN ; then
11788                         cat /etc/passwd
11789                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11790                 fi
11791         fi
11792         if ! getent group $ACLGRP; then
11793                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11794                 ACLGRP="$TSTUSR"
11795                 if ! getent group $ACLGRP; then
11796                         echo "cannot find group '$ACLGRP', adding it"
11797                         cat /etc/group
11798                         add_group 60000 $ACLGRP
11799                 fi
11800         fi
11801
11802         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11803         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11804         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11805
11806         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11807                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11808                 ACLGRP="$TSTUSR"
11809                 if ! getent group $ACLGRP; then
11810                         echo "cannot find group '$ACLGRP', adding it"
11811                         cat /etc/group
11812                         add_group 60000 $ACLGRP
11813                 fi
11814                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11815                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11816                         cat /etc/group
11817                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11818                 fi
11819         fi
11820
11821         gpasswd -a $ACLDMN $ACLBIN ||
11822                 error "setting client group failed"             # LU-5641
11823         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11824                 error "setting MDS group failed"                # LU-5641
11825
11826         declare -a identity_old
11827
11828         for num in $(seq $MDSCOUNT); do
11829                 switch_identity $num true || identity_old[$num]=$?
11830         done
11831
11832         SAVE_UMASK=$(umask)
11833         umask 0022
11834         mkdir -p $DIR/$tdir
11835         cd $DIR/$tdir
11836
11837         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11838         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11839         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11840         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11841         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11842         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11843         if ! id -u $ACLNBD ||
11844            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11845                 ACLNBD="nfsnobody"
11846                 if ! id -u $ACLNBD; then
11847                         ACLNBD=""
11848                 fi
11849         fi
11850         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11851                 add_group $(id -u $ACLNBD) $ACLNBD
11852                 if ! getent group $ACLNBD; then
11853                         ACLNBD=""
11854                 fi
11855         fi
11856         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11857            [[ -n "$ACLNBD" ]] && which setfattr; then
11858                 run_acl_subtest permissions_xattr \
11859                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11860         elif [[ -z "$ACLNBD" ]]; then
11861                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11862         else
11863                 echo "skip 'permission_xattr' test - missing setfattr command"
11864         fi
11865         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11866
11867         # inheritance test got from HP
11868         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11869         chmod +x make-tree || error "chmod +x failed"
11870         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11871         rm -f make-tree
11872
11873         echo "LU-974 ignore umask when acl is enabled..."
11874         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11875         if [ $MDSCOUNT -ge 2 ]; then
11876                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11877         fi
11878
11879         echo "LU-2561 newly created file is same size as directory..."
11880         if [ "$mds1_FSTYPE" != "zfs" ]; then
11881                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11882         else
11883                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11884         fi
11885
11886         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11887
11888         cd $SAVE_PWD
11889         umask $SAVE_UMASK
11890
11891         for num in $(seq $MDSCOUNT); do
11892                 if [ "${identity_old[$num]}" = 1 ]; then
11893                         switch_identity $num false || identity_old[$num]=$?
11894                 fi
11895         done
11896 }
11897 run_test 103a "acl test"
11898
11899 test_103b() {
11900         declare -a pids
11901         local U
11902
11903         for U in {0..511}; do
11904                 {
11905                 local O=$(printf "%04o" $U)
11906
11907                 umask $(printf "%04o" $((511 ^ $O)))
11908                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11909                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11910
11911                 (( $S == ($O & 0666) )) ||
11912                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11913
11914                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11915                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11916                 (( $S == ($O & 0666) )) ||
11917                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11918
11919                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11920                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11921                 (( $S == ($O & 0666) )) ||
11922                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11923                 rm -f $DIR/$tfile.[smp]$0
11924                 } &
11925                 local pid=$!
11926
11927                 # limit the concurrently running threads to 64. LU-11878
11928                 local idx=$((U % 64))
11929                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11930                 pids[idx]=$pid
11931         done
11932         wait
11933 }
11934 run_test 103b "umask lfs setstripe"
11935
11936 test_103c() {
11937         mkdir -p $DIR/$tdir
11938         cp -rp $DIR/$tdir $DIR/$tdir.bak
11939
11940         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11941                 error "$DIR/$tdir shouldn't contain default ACL"
11942         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11943                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11944         true
11945 }
11946 run_test 103c "'cp -rp' won't set empty acl"
11947
11948 test_103e() {
11949         local numacl
11950         local fileacl
11951         local saved_debug=$($LCTL get_param -n debug)
11952
11953         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11954                 skip "MDS needs to be at least 2.14.52"
11955
11956         large_xattr_enabled || skip_env "ea_inode feature disabled"
11957
11958         mkdir -p $DIR/$tdir
11959         # add big LOV EA to cause reply buffer overflow earlier
11960         $LFS setstripe -C 1000 $DIR/$tdir
11961         lctl set_param mdc.*-mdc*.stats=clear
11962
11963         $LCTL set_param debug=0
11964         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11965         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11966
11967         # add a large number of default ACLs (expect 8000+ for 2.13+)
11968         for U in {2..7000}; do
11969                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11970                         error "Able to add just $U default ACLs"
11971         done
11972         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11973         echo "$numacl default ACLs created"
11974
11975         stat $DIR/$tdir || error "Cannot stat directory"
11976         # check file creation
11977         touch $DIR/$tdir/$tfile ||
11978                 error "failed to create $tfile with $numacl default ACLs"
11979         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11980         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11981         echo "$fileacl ACLs were inherited"
11982         (( $fileacl == $numacl )) ||
11983                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11984         # check that new ACLs creation adds new ACLs to inherited ACLs
11985         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11986                 error "Cannot set new ACL"
11987         numacl=$((numacl + 1))
11988         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11989         (( $fileacl == $numacl )) ||
11990                 error "failed to add new ACL: $fileacl != $numacl as expected"
11991         # adds more ACLs to a file to reach their maximum at 8000+
11992         numacl=0
11993         for U in {20000..25000}; do
11994                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11995                 numacl=$((numacl + 1))
11996         done
11997         echo "Added $numacl more ACLs to the file"
11998         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11999         echo "Total $fileacl ACLs in file"
12000         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12001         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12002         rmdir $DIR/$tdir || error "Cannot remove directory"
12003 }
12004 run_test 103e "inheritance of big amount of default ACLs"
12005
12006 test_103f() {
12007         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12008                 skip "MDS needs to be at least 2.14.51"
12009
12010         large_xattr_enabled || skip_env "ea_inode feature disabled"
12011
12012         # enable changelog to consume more internal MDD buffers
12013         changelog_register
12014
12015         mkdir -p $DIR/$tdir
12016         # add big LOV EA
12017         $LFS setstripe -C 1000 $DIR/$tdir
12018         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12019         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12020         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12021         rmdir $DIR/$tdir || error "Cannot remove directory"
12022 }
12023 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12024
12025 test_104a() {
12026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12027
12028         touch $DIR/$tfile
12029         lfs df || error "lfs df failed"
12030         lfs df -ih || error "lfs df -ih failed"
12031         lfs df -h $DIR || error "lfs df -h $DIR failed"
12032         lfs df -i $DIR || error "lfs df -i $DIR failed"
12033         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12034         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12035
12036         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12037         lctl --device %$OSC deactivate
12038         lfs df || error "lfs df with deactivated OSC failed"
12039         lctl --device %$OSC activate
12040         # wait the osc back to normal
12041         wait_osc_import_ready client ost
12042
12043         lfs df || error "lfs df with reactivated OSC failed"
12044         rm -f $DIR/$tfile
12045 }
12046 run_test 104a "lfs df [-ih] [path] test ========================="
12047
12048 test_104b() {
12049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12050         [ $RUNAS_ID -eq $UID ] &&
12051                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12052
12053         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12054                         grep "Permission denied" | wc -l)))
12055         if [ $denied_cnt -ne 0 ]; then
12056                 error "lfs check servers test failed"
12057         fi
12058 }
12059 run_test 104b "$RUNAS lfs check servers test ===================="
12060
12061 #
12062 # Verify $1 is within range of $2.
12063 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12064 # $1 is <= 2% of $2. Else Fail.
12065 #
12066 value_in_range() {
12067         # Strip all units (M, G, T)
12068         actual=$(echo $1 | tr -d A-Z)
12069         expect=$(echo $2 | tr -d A-Z)
12070
12071         expect_lo=$(($expect * 98 / 100)) # 2% below
12072         expect_hi=$(($expect * 102 / 100)) # 2% above
12073
12074         # permit 2% drift above and below
12075         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12076 }
12077
12078 test_104c() {
12079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12080         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12081
12082         local ost_param="osd-zfs.$FSNAME-OST0000."
12083         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12084         local ofacets=$(get_facets OST)
12085         local mfacets=$(get_facets MDS)
12086         local saved_ost_blocks=
12087         local saved_mdt_blocks=
12088
12089         echo "Before recordsize change"
12090         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12091         df=($(df -h | grep "$MOUNT"$))
12092
12093         # For checking.
12094         echo "lfs output : ${lfs_df[*]}"
12095         echo "df  output : ${df[*]}"
12096
12097         for facet in ${ofacets//,/ }; do
12098                 if [ -z $saved_ost_blocks ]; then
12099                         saved_ost_blocks=$(do_facet $facet \
12100                                 lctl get_param -n $ost_param.blocksize)
12101                         echo "OST Blocksize: $saved_ost_blocks"
12102                 fi
12103                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12104                 do_facet $facet zfs set recordsize=32768 $ost
12105         done
12106
12107         # BS too small. Sufficient for functional testing.
12108         for facet in ${mfacets//,/ }; do
12109                 if [ -z $saved_mdt_blocks ]; then
12110                         saved_mdt_blocks=$(do_facet $facet \
12111                                 lctl get_param -n $mdt_param.blocksize)
12112                         echo "MDT Blocksize: $saved_mdt_blocks"
12113                 fi
12114                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12115                 do_facet $facet zfs set recordsize=32768 $mdt
12116         done
12117
12118         # Give new values chance to reflect change
12119         sleep 2
12120
12121         echo "After recordsize change"
12122         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12123         df_after=($(df -h | grep "$MOUNT"$))
12124
12125         # For checking.
12126         echo "lfs output : ${lfs_df_after[*]}"
12127         echo "df  output : ${df_after[*]}"
12128
12129         # Verify lfs df
12130         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12131                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12132         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12133                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12134         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12135                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12136
12137         # Verify df
12138         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12139                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12140         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12141                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12142         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12143                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12144
12145         # Restore MDT recordize back to original
12146         for facet in ${mfacets//,/ }; do
12147                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12148                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12149         done
12150
12151         # Restore OST recordize back to original
12152         for facet in ${ofacets//,/ }; do
12153                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12154                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12155         done
12156
12157         return 0
12158 }
12159 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12160
12161 test_104d() {
12162         (( $RUNAS_ID != $UID )) ||
12163                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12164
12165         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12166                 skip "lustre version doesn't support lctl dl with non-root"
12167
12168         # debugfs only allows root users to access files, so the
12169         # previous move of the "devices" file to debugfs broke
12170         # "lctl dl" for non-root users. The LU-9680 Netlink
12171         # interface again allows non-root users to list devices.
12172         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12173                 error "lctl dl doesn't work for non root"
12174
12175         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12176         [ "$ost_count" -eq $OSTCOUNT ]  ||
12177                 error "lctl dl reports wrong number of OST devices"
12178
12179         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12180         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12181                 error "lctl dl reports wrong number of MDT devices"
12182 }
12183 run_test 104d "$RUNAS lctl dl test"
12184
12185 test_105a() {
12186         # doesn't work on 2.4 kernels
12187         touch $DIR/$tfile
12188         if $(flock_is_enabled); then
12189                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12190         else
12191                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12192         fi
12193         rm -f $DIR/$tfile
12194 }
12195 run_test 105a "flock when mounted without -o flock test ========"
12196
12197 test_105b() {
12198         touch $DIR/$tfile
12199         if $(flock_is_enabled); then
12200                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12201         else
12202                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12203         fi
12204         rm -f $DIR/$tfile
12205 }
12206 run_test 105b "fcntl when mounted without -o flock test ========"
12207
12208 test_105c() {
12209         touch $DIR/$tfile
12210         if $(flock_is_enabled); then
12211                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12212         else
12213                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12214         fi
12215         rm -f $DIR/$tfile
12216 }
12217 run_test 105c "lockf when mounted without -o flock test"
12218
12219 test_105d() { # bug 15924
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221
12222         test_mkdir $DIR/$tdir
12223         flock_is_enabled || skip_env "mount w/o flock enabled"
12224         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12225         $LCTL set_param fail_loc=0x80000315
12226         flocks_test 2 $DIR/$tdir
12227 }
12228 run_test 105d "flock race (should not freeze) ========"
12229
12230 test_105e() { # bug 22660 && 22040
12231         flock_is_enabled || skip_env "mount w/o flock enabled"
12232
12233         touch $DIR/$tfile
12234         flocks_test 3 $DIR/$tfile
12235 }
12236 run_test 105e "Two conflicting flocks from same process"
12237
12238 test_106() { #bug 10921
12239         test_mkdir $DIR/$tdir
12240         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12241         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12242 }
12243 run_test 106 "attempt exec of dir followed by chown of that dir"
12244
12245 test_107() {
12246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12247
12248         CDIR=`pwd`
12249         local file=core
12250
12251         cd $DIR
12252         rm -f $file
12253
12254         local save_pattern=$(sysctl -n kernel.core_pattern)
12255         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12256         sysctl -w kernel.core_pattern=$file
12257         sysctl -w kernel.core_uses_pid=0
12258
12259         ulimit -c unlimited
12260         sleep 60 &
12261         SLEEPPID=$!
12262
12263         sleep 1
12264
12265         kill -s 11 $SLEEPPID
12266         wait $SLEEPPID
12267         if [ -e $file ]; then
12268                 size=`stat -c%s $file`
12269                 [ $size -eq 0 ] && error "Fail to create core file $file"
12270         else
12271                 error "Fail to create core file $file"
12272         fi
12273         rm -f $file
12274         sysctl -w kernel.core_pattern=$save_pattern
12275         sysctl -w kernel.core_uses_pid=$save_uses_pid
12276         cd $CDIR
12277 }
12278 run_test 107 "Coredump on SIG"
12279
12280 test_110() {
12281         test_mkdir $DIR/$tdir
12282         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12283         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12284                 error "mkdir with 256 char should fail, but did not"
12285         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12286                 error "create with 255 char failed"
12287         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12288                 error "create with 256 char should fail, but did not"
12289
12290         ls -l $DIR/$tdir
12291         rm -rf $DIR/$tdir
12292 }
12293 run_test 110 "filename length checking"
12294
12295 test_116a() { # was previously test_116()
12296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12297         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12298         remote_mds_nodsh && skip "remote MDS with nodsh"
12299
12300         echo -n "Free space priority "
12301         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12302                 head -n1
12303         declare -a AVAIL
12304         free_min_max
12305
12306         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12307         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12308         stack_trap simple_cleanup_common
12309
12310         # Check if we need to generate uneven OSTs
12311         test_mkdir -p $DIR/$tdir/OST${MINI}
12312         local FILL=$((MINV / 4))
12313         local DIFF=$((MAXV - MINV))
12314         local DIFF2=$((DIFF * 100 / MINV))
12315
12316         local threshold=$(do_facet $SINGLEMDS \
12317                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12318         threshold=${threshold%%%}
12319         echo -n "Check for uneven OSTs: "
12320         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12321
12322         if [[ $DIFF2 -gt $threshold ]]; then
12323                 echo "ok"
12324                 echo "Don't need to fill OST$MINI"
12325         else
12326                 # generate uneven OSTs. Write 2% over the QOS threshold value
12327                 echo "no"
12328                 DIFF=$((threshold - DIFF2 + 2))
12329                 DIFF2=$((MINV * DIFF / 100))
12330                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12331                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12332                         error "setstripe failed"
12333                 DIFF=$((DIFF2 / 2048))
12334                 i=0
12335                 while [ $i -lt $DIFF ]; do
12336                         i=$((i + 1))
12337                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12338                                 bs=2M count=1 2>/dev/null
12339                         echo -n .
12340                 done
12341                 echo .
12342                 sync
12343                 sleep_maxage
12344                 free_min_max
12345         fi
12346
12347         DIFF=$((MAXV - MINV))
12348         DIFF2=$((DIFF * 100 / MINV))
12349         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12350         if [ $DIFF2 -gt $threshold ]; then
12351                 echo "ok"
12352         else
12353                 skip "QOS imbalance criteria not met"
12354         fi
12355
12356         MINI1=$MINI
12357         MINV1=$MINV
12358         MAXI1=$MAXI
12359         MAXV1=$MAXV
12360
12361         # now fill using QOS
12362         $LFS setstripe -c 1 $DIR/$tdir
12363         FILL=$((FILL / 200))
12364         if [ $FILL -gt 600 ]; then
12365                 FILL=600
12366         fi
12367         echo "writing $FILL files to QOS-assigned OSTs"
12368         i=0
12369         while [ $i -lt $FILL ]; do
12370                 i=$((i + 1))
12371                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12372                         count=1 2>/dev/null
12373                 echo -n .
12374         done
12375         echo "wrote $i 200k files"
12376         sync
12377         sleep_maxage
12378
12379         echo "Note: free space may not be updated, so measurements might be off"
12380         free_min_max
12381         DIFF2=$((MAXV - MINV))
12382         echo "free space delta: orig $DIFF final $DIFF2"
12383         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12384         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12385         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12386         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12387         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12388         if [[ $DIFF -gt 0 ]]; then
12389                 FILL=$((DIFF2 * 100 / DIFF - 100))
12390                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12391         fi
12392
12393         # Figure out which files were written where
12394         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12395                awk '/'$MINI1': / {print $2; exit}')
12396         echo $UUID
12397         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12398         echo "$MINC files created on smaller OST $MINI1"
12399         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12400                awk '/'$MAXI1': / {print $2; exit}')
12401         echo $UUID
12402         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12403         echo "$MAXC files created on larger OST $MAXI1"
12404         if [[ $MINC -gt 0 ]]; then
12405                 FILL=$((MAXC * 100 / MINC - 100))
12406                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12407         fi
12408         [[ $MAXC -gt $MINC ]] ||
12409                 error_ignore LU-9 "stripe QOS didn't balance free space"
12410 }
12411 run_test 116a "stripe QOS: free space balance ==================="
12412
12413 test_116b() { # LU-2093
12414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12415         remote_mds_nodsh && skip "remote MDS with nodsh"
12416
12417 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12418         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12419                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12420         [ -z "$old_rr" ] && skip "no QOS"
12421         do_facet $SINGLEMDS lctl set_param \
12422                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12423         mkdir -p $DIR/$tdir
12424         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12425         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12426         do_facet $SINGLEMDS lctl set_param fail_loc=0
12427         rm -rf $DIR/$tdir
12428         do_facet $SINGLEMDS lctl set_param \
12429                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12430 }
12431 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12432
12433 test_117() # bug 10891
12434 {
12435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12436
12437         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12438         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12439         lctl set_param fail_loc=0x21e
12440         > $DIR/$tfile || error "truncate failed"
12441         lctl set_param fail_loc=0
12442         echo "Truncate succeeded."
12443         rm -f $DIR/$tfile
12444 }
12445 run_test 117 "verify osd extend =========="
12446
12447 NO_SLOW_RESENDCOUNT=4
12448 export OLD_RESENDCOUNT=""
12449 set_resend_count () {
12450         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12451         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12452         lctl set_param -n $PROC_RESENDCOUNT $1
12453         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12454 }
12455
12456 # for reduce test_118* time (b=14842)
12457 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12458
12459 # Reset async IO behavior after error case
12460 reset_async() {
12461         FILE=$DIR/reset_async
12462
12463         # Ensure all OSCs are cleared
12464         $LFS setstripe -c -1 $FILE
12465         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12466         sync
12467         rm $FILE
12468 }
12469
12470 test_118a() #bug 11710
12471 {
12472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12473
12474         reset_async
12475
12476         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12477         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12478         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12479
12480         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12481                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12482                 return 1;
12483         fi
12484         rm -f $DIR/$tfile
12485 }
12486 run_test 118a "verify O_SYNC works =========="
12487
12488 test_118b()
12489 {
12490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12491         remote_ost_nodsh && skip "remote OST with nodsh"
12492
12493         reset_async
12494
12495         #define OBD_FAIL_SRV_ENOENT 0x217
12496         set_nodes_failloc "$(osts_nodes)" 0x217
12497         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12498         RC=$?
12499         set_nodes_failloc "$(osts_nodes)" 0
12500         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12501         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12502                     grep -c writeback)
12503
12504         if [[ $RC -eq 0 ]]; then
12505                 error "Must return error due to dropped pages, rc=$RC"
12506                 return 1;
12507         fi
12508
12509         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12510                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12511                 return 1;
12512         fi
12513
12514         echo "Dirty pages not leaked on ENOENT"
12515
12516         # Due to the above error the OSC will issue all RPCs syncronously
12517         # until a subsequent RPC completes successfully without error.
12518         $MULTIOP $DIR/$tfile Ow4096yc
12519         rm -f $DIR/$tfile
12520
12521         return 0
12522 }
12523 run_test 118b "Reclaim dirty pages on fatal error =========="
12524
12525 test_118c()
12526 {
12527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12528
12529         # for 118c, restore the original resend count, LU-1940
12530         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12531                                 set_resend_count $OLD_RESENDCOUNT
12532         remote_ost_nodsh && skip "remote OST with nodsh"
12533
12534         reset_async
12535
12536         #define OBD_FAIL_OST_EROFS               0x216
12537         set_nodes_failloc "$(osts_nodes)" 0x216
12538
12539         # multiop should block due to fsync until pages are written
12540         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12541         MULTIPID=$!
12542         sleep 1
12543
12544         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12545                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12546         fi
12547
12548         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12549                     grep -c writeback)
12550         if [[ $WRITEBACK -eq 0 ]]; then
12551                 error "No page in writeback, writeback=$WRITEBACK"
12552         fi
12553
12554         set_nodes_failloc "$(osts_nodes)" 0
12555         wait $MULTIPID
12556         RC=$?
12557         if [[ $RC -ne 0 ]]; then
12558                 error "Multiop fsync failed, rc=$RC"
12559         fi
12560
12561         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12562         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12563                     grep -c writeback)
12564         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12565                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12566         fi
12567
12568         rm -f $DIR/$tfile
12569         echo "Dirty pages flushed via fsync on EROFS"
12570         return 0
12571 }
12572 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12573
12574 # continue to use small resend count to reduce test_118* time (b=14842)
12575 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12576
12577 test_118d()
12578 {
12579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12580         remote_ost_nodsh && skip "remote OST with nodsh"
12581
12582         reset_async
12583
12584         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12585         set_nodes_failloc "$(osts_nodes)" 0x214
12586         # multiop should block due to fsync until pages are written
12587         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12588         MULTIPID=$!
12589         sleep 1
12590
12591         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12592                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12593         fi
12594
12595         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12596                     grep -c writeback)
12597         if [[ $WRITEBACK -eq 0 ]]; then
12598                 error "No page in writeback, writeback=$WRITEBACK"
12599         fi
12600
12601         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12602         set_nodes_failloc "$(osts_nodes)" 0
12603
12604         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12605         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12606                     grep -c writeback)
12607         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12608                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12609         fi
12610
12611         rm -f $DIR/$tfile
12612         echo "Dirty pages gaurenteed flushed via fsync"
12613         return 0
12614 }
12615 run_test 118d "Fsync validation inject a delay of the bulk =========="
12616
12617 test_118f() {
12618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12619
12620         reset_async
12621
12622         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12623         lctl set_param fail_loc=0x8000040a
12624
12625         # Should simulate EINVAL error which is fatal
12626         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12627         RC=$?
12628         if [[ $RC -eq 0 ]]; then
12629                 error "Must return error due to dropped pages, rc=$RC"
12630         fi
12631
12632         lctl set_param fail_loc=0x0
12633
12634         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12635         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12636         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12637                     grep -c writeback)
12638         if [[ $LOCKED -ne 0 ]]; then
12639                 error "Locked pages remain in cache, locked=$LOCKED"
12640         fi
12641
12642         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12643                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12644         fi
12645
12646         rm -f $DIR/$tfile
12647         echo "No pages locked after fsync"
12648
12649         reset_async
12650         return 0
12651 }
12652 run_test 118f "Simulate unrecoverable OSC side error =========="
12653
12654 test_118g() {
12655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12656
12657         reset_async
12658
12659         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12660         lctl set_param fail_loc=0x406
12661
12662         # simulate local -ENOMEM
12663         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12664         RC=$?
12665
12666         lctl set_param fail_loc=0
12667         if [[ $RC -eq 0 ]]; then
12668                 error "Must return error due to dropped pages, rc=$RC"
12669         fi
12670
12671         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12672         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12673         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12674                         grep -c writeback)
12675         if [[ $LOCKED -ne 0 ]]; then
12676                 error "Locked pages remain in cache, locked=$LOCKED"
12677         fi
12678
12679         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12680                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12681         fi
12682
12683         rm -f $DIR/$tfile
12684         echo "No pages locked after fsync"
12685
12686         reset_async
12687         return 0
12688 }
12689 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12690
12691 test_118h() {
12692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12693         remote_ost_nodsh && skip "remote OST with nodsh"
12694
12695         reset_async
12696
12697         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12698         set_nodes_failloc "$(osts_nodes)" 0x20e
12699         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12700         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12701         RC=$?
12702
12703         set_nodes_failloc "$(osts_nodes)" 0
12704         if [[ $RC -eq 0 ]]; then
12705                 error "Must return error due to dropped pages, rc=$RC"
12706         fi
12707
12708         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12709         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12710         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12711                     grep -c writeback)
12712         if [[ $LOCKED -ne 0 ]]; then
12713                 error "Locked pages remain in cache, locked=$LOCKED"
12714         fi
12715
12716         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12717                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12718         fi
12719
12720         rm -f $DIR/$tfile
12721         echo "No pages locked after fsync"
12722
12723         return 0
12724 }
12725 run_test 118h "Verify timeout in handling recoverables errors  =========="
12726
12727 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12728
12729 test_118i() {
12730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12731         remote_ost_nodsh && skip "remote OST with nodsh"
12732
12733         reset_async
12734
12735         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12736         set_nodes_failloc "$(osts_nodes)" 0x20e
12737
12738         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12739         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12740         PID=$!
12741         sleep 5
12742         set_nodes_failloc "$(osts_nodes)" 0
12743
12744         wait $PID
12745         RC=$?
12746         if [[ $RC -ne 0 ]]; then
12747                 error "got error, but should be not, rc=$RC"
12748         fi
12749
12750         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12751         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12752         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12753         if [[ $LOCKED -ne 0 ]]; then
12754                 error "Locked pages remain in cache, locked=$LOCKED"
12755         fi
12756
12757         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12758                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12759         fi
12760
12761         rm -f $DIR/$tfile
12762         echo "No pages locked after fsync"
12763
12764         return 0
12765 }
12766 run_test 118i "Fix error before timeout in recoverable error  =========="
12767
12768 [ "$SLOW" = "no" ] && set_resend_count 4
12769
12770 test_118j() {
12771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12772         remote_ost_nodsh && skip "remote OST with nodsh"
12773
12774         reset_async
12775
12776         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12777         set_nodes_failloc "$(osts_nodes)" 0x220
12778
12779         # return -EIO from OST
12780         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12781         RC=$?
12782         set_nodes_failloc "$(osts_nodes)" 0x0
12783         if [[ $RC -eq 0 ]]; then
12784                 error "Must return error due to dropped pages, rc=$RC"
12785         fi
12786
12787         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12788         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12789         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12790         if [[ $LOCKED -ne 0 ]]; then
12791                 error "Locked pages remain in cache, locked=$LOCKED"
12792         fi
12793
12794         # in recoverable error on OST we want resend and stay until it finished
12795         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12796                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12797         fi
12798
12799         rm -f $DIR/$tfile
12800         echo "No pages locked after fsync"
12801
12802         return 0
12803 }
12804 run_test 118j "Simulate unrecoverable OST side error =========="
12805
12806 test_118k()
12807 {
12808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12809         remote_ost_nodsh && skip "remote OSTs with nodsh"
12810
12811         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12812         set_nodes_failloc "$(osts_nodes)" 0x20e
12813         test_mkdir $DIR/$tdir
12814
12815         for ((i=0;i<10;i++)); do
12816                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12817                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12818                 SLEEPPID=$!
12819                 sleep 0.500s
12820                 kill $SLEEPPID
12821                 wait $SLEEPPID
12822         done
12823
12824         set_nodes_failloc "$(osts_nodes)" 0
12825         rm -rf $DIR/$tdir
12826 }
12827 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12828
12829 test_118l() # LU-646
12830 {
12831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12832
12833         test_mkdir $DIR/$tdir
12834         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12835         rm -rf $DIR/$tdir
12836 }
12837 run_test 118l "fsync dir"
12838
12839 test_118m() # LU-3066
12840 {
12841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12842
12843         test_mkdir $DIR/$tdir
12844         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12845         rm -rf $DIR/$tdir
12846 }
12847 run_test 118m "fdatasync dir ========="
12848
12849 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12850
12851 test_118n()
12852 {
12853         local begin
12854         local end
12855
12856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12857         remote_ost_nodsh && skip "remote OSTs with nodsh"
12858
12859         # Sleep to avoid a cached response.
12860         #define OBD_STATFS_CACHE_SECONDS 1
12861         sleep 2
12862
12863         # Inject a 10 second delay in the OST_STATFS handler.
12864         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12865         set_nodes_failloc "$(osts_nodes)" 0x242
12866
12867         begin=$SECONDS
12868         stat --file-system $MOUNT > /dev/null
12869         end=$SECONDS
12870
12871         set_nodes_failloc "$(osts_nodes)" 0
12872
12873         if ((end - begin > 20)); then
12874             error "statfs took $((end - begin)) seconds, expected 10"
12875         fi
12876 }
12877 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12878
12879 test_119a() # bug 11737
12880 {
12881         BSIZE=$((512 * 1024))
12882         directio write $DIR/$tfile 0 1 $BSIZE
12883         # We ask to read two blocks, which is more than a file size.
12884         # directio will indicate an error when requested and actual
12885         # sizes aren't equeal (a normal situation in this case) and
12886         # print actual read amount.
12887         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12888         if [ "$NOB" != "$BSIZE" ]; then
12889                 error "read $NOB bytes instead of $BSIZE"
12890         fi
12891         rm -f $DIR/$tfile
12892 }
12893 run_test 119a "Short directIO read must return actual read amount"
12894
12895 test_119b() # bug 11737
12896 {
12897         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12898
12899         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12900         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12901         sync
12902         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12903                 error "direct read failed"
12904         rm -f $DIR/$tfile
12905 }
12906 run_test 119b "Sparse directIO read must return actual read amount"
12907
12908 test_119c() # bug 13099
12909 {
12910         BSIZE=1048576
12911         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12912         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12913         rm -f $DIR/$tfile
12914 }
12915 run_test 119c "Testing for direct read hitting hole"
12916
12917 test_119d() # bug 15950
12918 {
12919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12920
12921         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12922         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12923         BSIZE=1048576
12924         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12925         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12926         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12927         lctl set_param fail_loc=0x40d
12928         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12929         pid_dio=$!
12930         sleep 1
12931         cat $DIR/$tfile > /dev/null &
12932         lctl set_param fail_loc=0
12933         pid_reads=$!
12934         wait $pid_dio
12935         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12936         sleep 2
12937         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12938         error "the read rpcs have not completed in 2s"
12939         rm -f $DIR/$tfile
12940         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12941 }
12942 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12943
12944 test_120a() {
12945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12946         remote_mds_nodsh && skip "remote MDS with nodsh"
12947         test_mkdir -i0 -c1 $DIR/$tdir
12948         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12949                 skip_env "no early lock cancel on server"
12950
12951         lru_resize_disable mdc
12952         lru_resize_disable osc
12953         cancel_lru_locks mdc
12954         # asynchronous object destroy at MDT could cause bl ast to client
12955         cancel_lru_locks osc
12956
12957         stat $DIR/$tdir > /dev/null
12958         can1=$(do_facet mds1 \
12959                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12960                awk '/ldlm_cancel/ {print $2}')
12961         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12962                awk '/ldlm_bl_callback/ {print $2}')
12963         test_mkdir -i0 -c1 $DIR/$tdir/d1
12964         can2=$(do_facet mds1 \
12965                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12966                awk '/ldlm_cancel/ {print $2}')
12967         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12968                awk '/ldlm_bl_callback/ {print $2}')
12969         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12970         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12971         lru_resize_enable mdc
12972         lru_resize_enable osc
12973 }
12974 run_test 120a "Early Lock Cancel: mkdir test"
12975
12976 test_120b() {
12977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12978         remote_mds_nodsh && skip "remote MDS with nodsh"
12979         test_mkdir $DIR/$tdir
12980         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12981                 skip_env "no early lock cancel on server"
12982
12983         lru_resize_disable mdc
12984         lru_resize_disable osc
12985         cancel_lru_locks mdc
12986         stat $DIR/$tdir > /dev/null
12987         can1=$(do_facet $SINGLEMDS \
12988                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12989                awk '/ldlm_cancel/ {print $2}')
12990         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12991                awk '/ldlm_bl_callback/ {print $2}')
12992         touch $DIR/$tdir/f1
12993         can2=$(do_facet $SINGLEMDS \
12994                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12995                awk '/ldlm_cancel/ {print $2}')
12996         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12997                awk '/ldlm_bl_callback/ {print $2}')
12998         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12999         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13000         lru_resize_enable mdc
13001         lru_resize_enable osc
13002 }
13003 run_test 120b "Early Lock Cancel: create test"
13004
13005 test_120c() {
13006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13007         remote_mds_nodsh && skip "remote MDS with nodsh"
13008         test_mkdir -i0 -c1 $DIR/$tdir
13009         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13010                 skip "no early lock cancel on server"
13011
13012         lru_resize_disable mdc
13013         lru_resize_disable osc
13014         test_mkdir -i0 -c1 $DIR/$tdir/d1
13015         test_mkdir -i0 -c1 $DIR/$tdir/d2
13016         touch $DIR/$tdir/d1/f1
13017         cancel_lru_locks mdc
13018         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13019         can1=$(do_facet mds1 \
13020                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13021                awk '/ldlm_cancel/ {print $2}')
13022         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13023                awk '/ldlm_bl_callback/ {print $2}')
13024         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13025         can2=$(do_facet mds1 \
13026                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13027                awk '/ldlm_cancel/ {print $2}')
13028         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13029                awk '/ldlm_bl_callback/ {print $2}')
13030         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13031         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13032         lru_resize_enable mdc
13033         lru_resize_enable osc
13034 }
13035 run_test 120c "Early Lock Cancel: link test"
13036
13037 test_120d() {
13038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13039         remote_mds_nodsh && skip "remote MDS with nodsh"
13040         test_mkdir -i0 -c1 $DIR/$tdir
13041         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13042                 skip_env "no early lock cancel on server"
13043
13044         lru_resize_disable mdc
13045         lru_resize_disable osc
13046         touch $DIR/$tdir
13047         cancel_lru_locks mdc
13048         stat $DIR/$tdir > /dev/null
13049         can1=$(do_facet mds1 \
13050                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13051                awk '/ldlm_cancel/ {print $2}')
13052         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13053                awk '/ldlm_bl_callback/ {print $2}')
13054         chmod a+x $DIR/$tdir
13055         can2=$(do_facet mds1 \
13056                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13057                awk '/ldlm_cancel/ {print $2}')
13058         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13059                awk '/ldlm_bl_callback/ {print $2}')
13060         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13061         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13062         lru_resize_enable mdc
13063         lru_resize_enable osc
13064 }
13065 run_test 120d "Early Lock Cancel: setattr test"
13066
13067 test_120e() {
13068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13069         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13070                 skip_env "no early lock cancel on server"
13071         remote_mds_nodsh && skip "remote MDS with nodsh"
13072
13073         local dlmtrace_set=false
13074
13075         test_mkdir -i0 -c1 $DIR/$tdir
13076         lru_resize_disable mdc
13077         lru_resize_disable osc
13078         ! $LCTL get_param debug | grep -q dlmtrace &&
13079                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13080         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13081         cancel_lru_locks mdc
13082         cancel_lru_locks osc
13083         dd if=$DIR/$tdir/f1 of=/dev/null
13084         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13085         # XXX client can not do early lock cancel of OST lock
13086         # during unlink (LU-4206), so cancel osc lock now.
13087         sleep 2
13088         cancel_lru_locks osc
13089         can1=$(do_facet mds1 \
13090                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13091                awk '/ldlm_cancel/ {print $2}')
13092         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13093                awk '/ldlm_bl_callback/ {print $2}')
13094         unlink $DIR/$tdir/f1
13095         sleep 5
13096         can2=$(do_facet mds1 \
13097                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13098                awk '/ldlm_cancel/ {print $2}')
13099         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13100                awk '/ldlm_bl_callback/ {print $2}')
13101         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13102                 $LCTL dk $TMP/cancel.debug.txt
13103         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13104                 $LCTL dk $TMP/blocking.debug.txt
13105         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13106         lru_resize_enable mdc
13107         lru_resize_enable osc
13108 }
13109 run_test 120e "Early Lock Cancel: unlink test"
13110
13111 test_120f() {
13112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13113         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13114                 skip_env "no early lock cancel on server"
13115         remote_mds_nodsh && skip "remote MDS with nodsh"
13116
13117         test_mkdir -i0 -c1 $DIR/$tdir
13118         lru_resize_disable mdc
13119         lru_resize_disable osc
13120         test_mkdir -i0 -c1 $DIR/$tdir/d1
13121         test_mkdir -i0 -c1 $DIR/$tdir/d2
13122         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13123         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13124         cancel_lru_locks mdc
13125         cancel_lru_locks osc
13126         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13127         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13128         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13129         # XXX client can not do early lock cancel of OST lock
13130         # during rename (LU-4206), so cancel osc lock now.
13131         sleep 2
13132         cancel_lru_locks osc
13133         can1=$(do_facet mds1 \
13134                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13135                awk '/ldlm_cancel/ {print $2}')
13136         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13137                awk '/ldlm_bl_callback/ {print $2}')
13138         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13139         sleep 5
13140         can2=$(do_facet mds1 \
13141                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13142                awk '/ldlm_cancel/ {print $2}')
13143         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13144                awk '/ldlm_bl_callback/ {print $2}')
13145         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13146         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13147         lru_resize_enable mdc
13148         lru_resize_enable osc
13149 }
13150 run_test 120f "Early Lock Cancel: rename test"
13151
13152 test_120g() {
13153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13154         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13155                 skip_env "no early lock cancel on server"
13156         remote_mds_nodsh && skip "remote MDS with nodsh"
13157
13158         lru_resize_disable mdc
13159         lru_resize_disable osc
13160         count=10000
13161         echo create $count files
13162         test_mkdir $DIR/$tdir
13163         cancel_lru_locks mdc
13164         cancel_lru_locks osc
13165         t0=$(date +%s)
13166
13167         can0=$(do_facet $SINGLEMDS \
13168                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13169                awk '/ldlm_cancel/ {print $2}')
13170         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13171                awk '/ldlm_bl_callback/ {print $2}')
13172         createmany -o $DIR/$tdir/f $count
13173         sync
13174         can1=$(do_facet $SINGLEMDS \
13175                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13176                awk '/ldlm_cancel/ {print $2}')
13177         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13178                awk '/ldlm_bl_callback/ {print $2}')
13179         t1=$(date +%s)
13180         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13181         echo rm $count files
13182         rm -r $DIR/$tdir
13183         sync
13184         can2=$(do_facet $SINGLEMDS \
13185                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13186                awk '/ldlm_cancel/ {print $2}')
13187         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13188                awk '/ldlm_bl_callback/ {print $2}')
13189         t2=$(date +%s)
13190         echo total: $count removes in $((t2-t1))
13191         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13192         sleep 2
13193         # wait for commitment of removal
13194         lru_resize_enable mdc
13195         lru_resize_enable osc
13196 }
13197 run_test 120g "Early Lock Cancel: performance test"
13198
13199 test_121() { #bug #10589
13200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13201
13202         rm -rf $DIR/$tfile
13203         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13204 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13205         lctl set_param fail_loc=0x310
13206         cancel_lru_locks osc > /dev/null
13207         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13208         lctl set_param fail_loc=0
13209         [[ $reads -eq $writes ]] ||
13210                 error "read $reads blocks, must be $writes blocks"
13211 }
13212 run_test 121 "read cancel race ========="
13213
13214 test_123a_base() { # was test 123, statahead(bug 11401)
13215         local lsx="$1"
13216
13217         SLOWOK=0
13218         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13219                 log "testing UP system. Performance may be lower than expected."
13220                 SLOWOK=1
13221         fi
13222         running_in_vm && SLOWOK=1
13223
13224         rm -rf $DIR/$tdir
13225         test_mkdir $DIR/$tdir
13226         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13227         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13228         MULT=10
13229         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13230                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13231
13232                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13233                 lctl set_param -n llite.*.statahead_max 0
13234                 lctl get_param llite.*.statahead_max
13235                 cancel_lru_locks mdc
13236                 cancel_lru_locks osc
13237                 stime=$(date +%s)
13238                 time $lsx $DIR/$tdir | wc -l
13239                 etime=$(date +%s)
13240                 delta=$((etime - stime))
13241                 log "$lsx $i files without statahead: $delta sec"
13242                 lctl set_param llite.*.statahead_max=$max
13243
13244                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13245                          awk '/statahead.wrong:/ { print $NF }')
13246                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13247                 cancel_lru_locks mdc
13248                 cancel_lru_locks osc
13249                 stime=$(date +%s)
13250                 time $lsx $DIR/$tdir | wc -l
13251                 etime=$(date +%s)
13252                 delta_sa=$((etime - stime))
13253                 log "$lsx $i files with statahead: $delta_sa sec"
13254                 lctl get_param -n llite.*.statahead_stats
13255                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13256                          awk '/statahead.wrong:/ { print $NF }')
13257
13258                 [[ $swrong -lt $ewrong ]] &&
13259                         log "statahead was stopped, maybe too many locks held!"
13260                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13261
13262                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13263                         max=$(lctl get_param -n llite.*.statahead_max |
13264                                 head -n 1)
13265                         lctl set_param -n llite.*.statahead_max 0
13266                         lctl get_param llite.*.statahead_max
13267                         cancel_lru_locks mdc
13268                         cancel_lru_locks osc
13269                         stime=$(date +%s)
13270                         time $lsx $DIR/$tdir | wc -l
13271                         etime=$(date +%s)
13272                         delta=$((etime - stime))
13273                         log "$lsx $i files again without statahead: $delta sec"
13274                         lctl set_param llite.*.statahead_max=$max
13275                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13276                                 if [ $SLOWOK -eq 0 ]; then
13277                                         error "$lsx $i files is slower with statahead!"
13278                                 else
13279                                         log "$lsx $i files is slower with statahead!"
13280                                 fi
13281                                 break
13282                         fi
13283                 fi
13284
13285                 [ $delta -gt 20 ] && break
13286                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13287                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13288         done
13289         log "$lsx done"
13290
13291         stime=$(date +%s)
13292         rm -r $DIR/$tdir
13293         sync
13294         etime=$(date +%s)
13295         delta=$((etime - stime))
13296         log "rm -r $DIR/$tdir/: $delta seconds"
13297         log "rm done"
13298         lctl get_param -n llite.*.statahead_stats
13299 }
13300
13301 test_123aa() {
13302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13303
13304         test_123a_base "ls -l"
13305 }
13306 run_test 123aa "verify statahead work"
13307
13308 test_123ab() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310
13311         statx_supported || skip_env "Test must be statx() syscall supported"
13312
13313         test_123a_base "$STATX -l"
13314 }
13315 run_test 123ab "verify statahead work by using statx"
13316
13317 test_123ac() {
13318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13319
13320         statx_supported || skip_env "Test must be statx() syscall supported"
13321
13322         local rpcs_before
13323         local rpcs_after
13324         local agl_before
13325         local agl_after
13326
13327         cancel_lru_locks $OSC
13328         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13329         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13330                      awk '/agl.total:/ { print $NF }')
13331         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13332         test_123a_base "$STATX --cached=always -D"
13333         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13334                     awk '/agl.total:/ { print $NF }')
13335         [ $agl_before -eq $agl_after ] ||
13336                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13337         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13338         [ $rpcs_after -eq $rpcs_before ] ||
13339                 error "$STATX should not send glimpse RPCs to $OSC"
13340 }
13341 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13342
13343 test_123b () { # statahead(bug 15027)
13344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13345
13346         test_mkdir $DIR/$tdir
13347         createmany -o $DIR/$tdir/$tfile-%d 1000
13348
13349         cancel_lru_locks mdc
13350         cancel_lru_locks osc
13351
13352 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13353         lctl set_param fail_loc=0x80000803
13354         ls -lR $DIR/$tdir > /dev/null
13355         log "ls done"
13356         lctl set_param fail_loc=0x0
13357         lctl get_param -n llite.*.statahead_stats
13358         rm -r $DIR/$tdir
13359         sync
13360
13361 }
13362 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13363
13364 test_123c() {
13365         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13366
13367         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13368         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13369         touch $DIR/$tdir.1/{1..3}
13370         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13371
13372         remount_client $MOUNT
13373
13374         $MULTIOP $DIR/$tdir.0 Q
13375
13376         # let statahead to complete
13377         ls -l $DIR/$tdir.0 > /dev/null
13378
13379         testid=$(echo $TESTNAME | tr '_' ' ')
13380         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13381                 error "statahead warning" || true
13382 }
13383 run_test 123c "Can not initialize inode warning on DNE statahead"
13384
13385 test_123d() {
13386         local num=100
13387         local swrong
13388         local ewrong
13389
13390         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13391         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13392                 error "setdirstripe $DIR/$tdir failed"
13393         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13394         remount_client $MOUNT
13395         $LCTL get_param llite.*.statahead_max
13396         $LCTL set_param llite.*.statahead_stats=0 ||
13397                 error "clear statahead_stats failed"
13398         swrong=$(lctl get_param -n llite.*.statahead_stats |
13399                  awk '/statahead.wrong:/ { print $NF }')
13400         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13401         # wait for statahead thread finished to update hit/miss stats.
13402         sleep 1
13403         $LCTL get_param -n llite.*.statahead_stats
13404         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13405                  awk '/statahead.wrong:/ { print $NF }')
13406         (( $swrong == $ewrong )) ||
13407                 log "statahead was stopped, maybe too many locks held!"
13408 }
13409 run_test 123d "Statahead on striped directories works correctly"
13410
13411 test_124a() {
13412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13413         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13414                 skip_env "no lru resize on server"
13415
13416         local NR=2000
13417
13418         test_mkdir $DIR/$tdir
13419
13420         log "create $NR files at $DIR/$tdir"
13421         createmany -o $DIR/$tdir/f $NR ||
13422                 error "failed to create $NR files in $DIR/$tdir"
13423
13424         cancel_lru_locks mdc
13425         ls -l $DIR/$tdir > /dev/null
13426
13427         local NSDIR=""
13428         local LRU_SIZE=0
13429         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13430                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13431                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13432                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13433                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13434                         log "NSDIR=$NSDIR"
13435                         log "NS=$(basename $NSDIR)"
13436                         break
13437                 fi
13438         done
13439
13440         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13441                 skip "Not enough cached locks created!"
13442         fi
13443         log "LRU=$LRU_SIZE"
13444
13445         local SLEEP=30
13446
13447         # We know that lru resize allows one client to hold $LIMIT locks
13448         # for 10h. After that locks begin to be killed by client.
13449         local MAX_HRS=10
13450         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13451         log "LIMIT=$LIMIT"
13452         if [ $LIMIT -lt $LRU_SIZE ]; then
13453                 skip "Limit is too small $LIMIT"
13454         fi
13455
13456         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13457         # killing locks. Some time was spent for creating locks. This means
13458         # that up to the moment of sleep finish we must have killed some of
13459         # them (10-100 locks). This depends on how fast ther were created.
13460         # Many of them were touched in almost the same moment and thus will
13461         # be killed in groups.
13462         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13463
13464         # Use $LRU_SIZE_B here to take into account real number of locks
13465         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13466         local LRU_SIZE_B=$LRU_SIZE
13467         log "LVF=$LVF"
13468         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13469         log "OLD_LVF=$OLD_LVF"
13470         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13471
13472         # Let's make sure that we really have some margin. Client checks
13473         # cached locks every 10 sec.
13474         SLEEP=$((SLEEP+20))
13475         log "Sleep ${SLEEP} sec"
13476         local SEC=0
13477         while ((SEC<$SLEEP)); do
13478                 echo -n "..."
13479                 sleep 5
13480                 SEC=$((SEC+5))
13481                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13482                 echo -n "$LRU_SIZE"
13483         done
13484         echo ""
13485         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13486         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13487
13488         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13489                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13490                 unlinkmany $DIR/$tdir/f $NR
13491                 return
13492         }
13493
13494         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13495         log "unlink $NR files at $DIR/$tdir"
13496         unlinkmany $DIR/$tdir/f $NR
13497 }
13498 run_test 124a "lru resize ======================================="
13499
13500 get_max_pool_limit()
13501 {
13502         local limit=$($LCTL get_param \
13503                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13504         local max=0
13505         for l in $limit; do
13506                 if [[ $l -gt $max ]]; then
13507                         max=$l
13508                 fi
13509         done
13510         echo $max
13511 }
13512
13513 test_124b() {
13514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13515         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13516                 skip_env "no lru resize on server"
13517
13518         LIMIT=$(get_max_pool_limit)
13519
13520         NR=$(($(default_lru_size)*20))
13521         if [[ $NR -gt $LIMIT ]]; then
13522                 log "Limit lock number by $LIMIT locks"
13523                 NR=$LIMIT
13524         fi
13525
13526         IFree=$(mdsrate_inodes_available)
13527         if [ $IFree -lt $NR ]; then
13528                 log "Limit lock number by $IFree inodes"
13529                 NR=$IFree
13530         fi
13531
13532         lru_resize_disable mdc
13533         test_mkdir -p $DIR/$tdir/disable_lru_resize
13534
13535         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13536         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13537         cancel_lru_locks mdc
13538         stime=`date +%s`
13539         PID=""
13540         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13541         PID="$PID $!"
13542         sleep 2
13543         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13544         PID="$PID $!"
13545         sleep 2
13546         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13547         PID="$PID $!"
13548         wait $PID
13549         etime=`date +%s`
13550         nolruresize_delta=$((etime-stime))
13551         log "ls -la time: $nolruresize_delta seconds"
13552         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13553         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13554
13555         lru_resize_enable mdc
13556         test_mkdir -p $DIR/$tdir/enable_lru_resize
13557
13558         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13559         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13560         cancel_lru_locks mdc
13561         stime=`date +%s`
13562         PID=""
13563         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13564         PID="$PID $!"
13565         sleep 2
13566         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13567         PID="$PID $!"
13568         sleep 2
13569         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13570         PID="$PID $!"
13571         wait $PID
13572         etime=`date +%s`
13573         lruresize_delta=$((etime-stime))
13574         log "ls -la time: $lruresize_delta seconds"
13575         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13576
13577         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13578                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13579         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13580                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13581         else
13582                 log "lru resize performs the same with no lru resize"
13583         fi
13584         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13585 }
13586 run_test 124b "lru resize (performance test) ======================="
13587
13588 test_124c() {
13589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13590         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13591                 skip_env "no lru resize on server"
13592
13593         # cache ununsed locks on client
13594         local nr=100
13595         cancel_lru_locks mdc
13596         test_mkdir $DIR/$tdir
13597         createmany -o $DIR/$tdir/f $nr ||
13598                 error "failed to create $nr files in $DIR/$tdir"
13599         ls -l $DIR/$tdir > /dev/null
13600
13601         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13602         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13603         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13604         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13605         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13606
13607         # set lru_max_age to 1 sec
13608         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13609         echo "sleep $((recalc_p * 2)) seconds..."
13610         sleep $((recalc_p * 2))
13611
13612         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13613         # restore lru_max_age
13614         $LCTL set_param -n $nsdir.lru_max_age $max_age
13615         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13616         unlinkmany $DIR/$tdir/f $nr
13617 }
13618 run_test 124c "LRUR cancel very aged locks"
13619
13620 test_124d() {
13621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13622         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13623                 skip_env "no lru resize on server"
13624
13625         # cache ununsed locks on client
13626         local nr=100
13627
13628         lru_resize_disable mdc
13629         stack_trap "lru_resize_enable mdc" EXIT
13630
13631         cancel_lru_locks mdc
13632
13633         # asynchronous object destroy at MDT could cause bl ast to client
13634         test_mkdir $DIR/$tdir
13635         createmany -o $DIR/$tdir/f $nr ||
13636                 error "failed to create $nr files in $DIR/$tdir"
13637         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13638
13639         ls -l $DIR/$tdir > /dev/null
13640
13641         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13642         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13643         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13644         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13645
13646         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13647
13648         # set lru_max_age to 1 sec
13649         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13650         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13651
13652         echo "sleep $((recalc_p * 2)) seconds..."
13653         sleep $((recalc_p * 2))
13654
13655         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13656
13657         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13658 }
13659 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13660
13661 test_125() { # 13358
13662         $LCTL get_param -n llite.*.client_type | grep -q local ||
13663                 skip "must run as local client"
13664         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13665                 skip_env "must have acl enabled"
13666         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13667
13668         test_mkdir $DIR/$tdir
13669         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13670         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13671                 error "setfacl $DIR/$tdir failed"
13672         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13673 }
13674 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13675
13676 test_126() { # bug 12829/13455
13677         $GSS && skip_env "must run as gss disabled"
13678         $LCTL get_param -n llite.*.client_type | grep -q local ||
13679                 skip "must run as local client"
13680         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13681
13682         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13683         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13684         rm -f $DIR/$tfile
13685         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13686 }
13687 run_test 126 "check that the fsgid provided by the client is taken into account"
13688
13689 test_127a() { # bug 15521
13690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13691         local name count samp unit min max sum sumsq
13692         local tmpfile=$TMP/$tfile.tmp
13693
13694         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13695         echo "stats before reset"
13696         stack_trap "rm -f $tmpfile"
13697         local now=$(date +%s)
13698
13699         $LCTL get_param osc.*.stats | tee $tmpfile
13700
13701         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13702         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13703         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13704         local uptime=$(awk '{ print $1 }' /proc/uptime)
13705
13706         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13707         (( ${snapshot_time%\.*} >= $now - 5 &&
13708            ${snapshot_time%\.*} <= $now + 5 )) ||
13709                 error "snapshot_time=$snapshot_time != now=$now"
13710         # elapsed _should_ be from mount, but at least less than uptime
13711         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13712                 error "elapsed=$elapsed > uptime=$uptime"
13713         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13714            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13715                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13716
13717         $LCTL set_param osc.*.stats=0
13718         local reset=$(date +%s)
13719         local fsize=$((2048 * 1024))
13720
13721         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13722         cancel_lru_locks osc
13723         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13724
13725         now=$(date +%s)
13726         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13727         while read name count samp unit min max sum sumsq; do
13728                 [[ "$samp" == "samples" ]] || continue
13729
13730                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13731                 [ ! $min ] && error "Missing min value for $name proc entry"
13732                 eval $name=$count || error "Wrong proc format"
13733
13734                 case $name in
13735                 read_bytes|write_bytes)
13736                         [[ "$unit" =~ "bytes" ]] ||
13737                                 error "unit is not 'bytes': $unit"
13738                         (( $min >= 4096 )) || error "min is too small: $min"
13739                         (( $min <= $fsize )) || error "min is too big: $min"
13740                         (( $max >= 4096 )) || error "max is too small: $max"
13741                         (( $max <= $fsize )) || error "max is too big: $max"
13742                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13743                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13744                                 error "sumsquare is too small: $sumsq"
13745                         (( $sumsq <= $fsize * $fsize )) ||
13746                                 error "sumsquare is too big: $sumsq"
13747                         ;;
13748                 ost_read|ost_write)
13749                         [[ "$unit" =~ "usec" ]] ||
13750                                 error "unit is not 'usec': $unit"
13751                         ;;
13752                 *)      ;;
13753                 esac
13754         done < $tmpfile
13755
13756         #check that we actually got some stats
13757         [ "$read_bytes" ] || error "Missing read_bytes stats"
13758         [ "$write_bytes" ] || error "Missing write_bytes stats"
13759         [ "$read_bytes" != 0 ] || error "no read done"
13760         [ "$write_bytes" != 0 ] || error "no write done"
13761
13762         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13763         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13764         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13765
13766         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13767         (( ${snapshot_time%\.*} >= $now - 5 &&
13768            ${snapshot_time%\.*} <= $now + 5 )) ||
13769                 error "reset snapshot_time=$snapshot_time != now=$now"
13770         # elapsed should be from time of stats reset
13771         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13772            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13773                 error "reset elapsed=$elapsed > $now - $reset"
13774         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13775            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13776                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13777 }
13778 run_test 127a "verify the client stats are sane"
13779
13780 test_127b() { # bug LU-333
13781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13782         local name count samp unit min max sum sumsq
13783
13784         echo "stats before reset"
13785         $LCTL get_param llite.*.stats
13786         $LCTL set_param llite.*.stats=0
13787
13788         # perform 2 reads and writes so MAX is different from SUM.
13789         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13790         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13791         cancel_lru_locks osc
13792         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13793         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13794
13795         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13796         stack_trap "rm -f $TMP/$tfile.tmp"
13797         while read name count samp unit min max sum sumsq; do
13798                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13799                 eval $name=$count || error "Wrong proc format"
13800
13801                 case $name in
13802                 read_bytes|write_bytes)
13803                         [[ "$unit" =~ "bytes" ]] ||
13804                                 error "unit is not 'bytes': $unit"
13805                         (( $count == 2 )) || error "count is not 2: $count"
13806                         (( $min == $PAGE_SIZE )) ||
13807                                 error "min is not $PAGE_SIZE: $min"
13808                         (( $max == $PAGE_SIZE )) ||
13809                                 error "max is not $PAGE_SIZE: $max"
13810                         (( $sum == $PAGE_SIZE * 2 )) ||
13811                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13812                         ;;
13813                 read|write)
13814                         [[ "$unit" =~ "usec" ]] ||
13815                                 error "unit is not 'usec': $unit"
13816                         ;;
13817                 *)      ;;
13818                 esac
13819         done < $TMP/$tfile.tmp
13820
13821         #check that we actually got some stats
13822         [ "$read_bytes" ] || error "Missing read_bytes stats"
13823         [ "$write_bytes" ] || error "Missing write_bytes stats"
13824         [ "$read_bytes" != 0 ] || error "no read done"
13825         [ "$write_bytes" != 0 ] || error "no write done"
13826 }
13827 run_test 127b "verify the llite client stats are sane"
13828
13829 test_127c() { # LU-12394
13830         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13831         local size
13832         local bsize
13833         local reads
13834         local writes
13835         local count
13836
13837         $LCTL set_param llite.*.extents_stats=1
13838         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13839
13840         # Use two stripes so there is enough space in default config
13841         $LFS setstripe -c 2 $DIR/$tfile
13842
13843         # Extent stats start at 0-4K and go in power of two buckets
13844         # LL_HIST_START = 12 --> 2^12 = 4K
13845         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13846         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13847         # small configs
13848         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13849                 do
13850                 # Write and read, 2x each, second time at a non-zero offset
13851                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13852                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13853                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13854                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13855                 rm -f $DIR/$tfile
13856         done
13857
13858         $LCTL get_param llite.*.extents_stats
13859
13860         count=2
13861         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13862                 do
13863                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13864                                 grep -m 1 $bsize)
13865                 reads=$(echo $bucket | awk '{print $5}')
13866                 writes=$(echo $bucket | awk '{print $9}')
13867                 [ "$reads" -eq $count ] ||
13868                         error "$reads reads in < $bsize bucket, expect $count"
13869                 [ "$writes" -eq $count ] ||
13870                         error "$writes writes in < $bsize bucket, expect $count"
13871         done
13872
13873         # Test mmap write and read
13874         $LCTL set_param llite.*.extents_stats=c
13875         size=512
13876         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13877         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13878         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13879
13880         $LCTL get_param llite.*.extents_stats
13881
13882         count=$(((size*1024) / PAGE_SIZE))
13883
13884         bsize=$((2 * PAGE_SIZE / 1024))K
13885
13886         bucket=$($LCTL get_param -n llite.*.extents_stats |
13887                         grep -m 1 $bsize)
13888         reads=$(echo $bucket | awk '{print $5}')
13889         writes=$(echo $bucket | awk '{print $9}')
13890         # mmap writes fault in the page first, creating an additonal read
13891         [ "$reads" -eq $((2 * count)) ] ||
13892                 error "$reads reads in < $bsize bucket, expect $count"
13893         [ "$writes" -eq $count ] ||
13894                 error "$writes writes in < $bsize bucket, expect $count"
13895 }
13896 run_test 127c "test llite extent stats with regular & mmap i/o"
13897
13898 test_128() { # bug 15212
13899         touch $DIR/$tfile
13900         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13901                 find $DIR/$tfile
13902                 find $DIR/$tfile
13903         EOF
13904
13905         result=$(grep error $TMP/$tfile.log)
13906         rm -f $DIR/$tfile $TMP/$tfile.log
13907         [ -z "$result" ] ||
13908                 error "consecutive find's under interactive lfs failed"
13909 }
13910 run_test 128 "interactive lfs for 2 consecutive find's"
13911
13912 set_dir_limits () {
13913         local mntdev
13914         local canondev
13915         local node
13916
13917         local ldproc=/proc/fs/ldiskfs
13918         local facets=$(get_facets MDS)
13919
13920         for facet in ${facets//,/ }; do
13921                 canondev=$(ldiskfs_canon \
13922                            *.$(convert_facet2label $facet).mntdev $facet)
13923                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13924                         ldproc=/sys/fs/ldiskfs
13925                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13926                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13927         done
13928 }
13929
13930 check_mds_dmesg() {
13931         local facets=$(get_facets MDS)
13932         for facet in ${facets//,/ }; do
13933                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13934         done
13935         return 1
13936 }
13937
13938 test_129() {
13939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13940         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13941                 skip "Need MDS version with at least 2.5.56"
13942         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13943                 skip_env "ldiskfs only test"
13944         fi
13945         remote_mds_nodsh && skip "remote MDS with nodsh"
13946
13947         local ENOSPC=28
13948         local has_warning=false
13949
13950         rm -rf $DIR/$tdir
13951         mkdir -p $DIR/$tdir
13952
13953         # block size of mds1
13954         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13955         set_dir_limits $maxsize $((maxsize * 6 / 8))
13956         stack_trap "set_dir_limits 0 0"
13957         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13958         local dirsize=$(stat -c%s "$DIR/$tdir")
13959         local nfiles=0
13960         while (( $dirsize <= $maxsize )); do
13961                 $MCREATE $DIR/$tdir/file_base_$nfiles
13962                 rc=$?
13963                 # check two errors:
13964                 # ENOSPC for ext4 max_dir_size, which has been used since
13965                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13966                 if (( rc == ENOSPC )); then
13967                         set_dir_limits 0 0
13968                         echo "rc=$rc returned as expected after $nfiles files"
13969
13970                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13971                                 error "create failed w/o dir size limit"
13972
13973                         # messages may be rate limited if test is run repeatedly
13974                         check_mds_dmesg '"is approaching max"' ||
13975                                 echo "warning message should be output"
13976                         check_mds_dmesg '"has reached max"' ||
13977                                 echo "reached message should be output"
13978
13979                         dirsize=$(stat -c%s "$DIR/$tdir")
13980
13981                         [[ $dirsize -ge $maxsize ]] && return 0
13982                         error "dirsize $dirsize < $maxsize after $nfiles files"
13983                 elif (( rc != 0 )); then
13984                         break
13985                 fi
13986                 nfiles=$((nfiles + 1))
13987                 dirsize=$(stat -c%s "$DIR/$tdir")
13988         done
13989
13990         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13991 }
13992 run_test 129 "test directory size limit ========================"
13993
13994 OLDIFS="$IFS"
13995 cleanup_130() {
13996         trap 0
13997         IFS="$OLDIFS"
13998 }
13999
14000 test_130a() {
14001         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14002         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14003
14004         trap cleanup_130 EXIT RETURN
14005
14006         local fm_file=$DIR/$tfile
14007         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14008         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14009                 error "dd failed for $fm_file"
14010
14011         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14012         filefrag -ves $fm_file
14013         local rc=$?
14014         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14015                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14016         (( $rc == 0 )) || error "filefrag $fm_file failed"
14017
14018         filefrag_op=$(filefrag -ve -k $fm_file |
14019                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14020         local lun=$($LFS getstripe -i $fm_file)
14021
14022         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14023         IFS=$'\n'
14024         local tot_len=0
14025         for line in $filefrag_op; do
14026                 local frag_lun=$(echo $line | cut -d: -f5)
14027                 local ext_len=$(echo $line | cut -d: -f4)
14028
14029                 if (( $frag_lun != $lun )); then
14030                         error "FIEMAP on 1-stripe file($fm_file) failed"
14031                         return
14032                 fi
14033                 (( tot_len += ext_len ))
14034         done
14035
14036         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14037                 error "FIEMAP on 1-stripe file($fm_file) failed"
14038                 return
14039         fi
14040
14041         echo "FIEMAP on single striped file succeeded"
14042 }
14043 run_test 130a "FIEMAP (1-stripe file)"
14044
14045 test_130b() {
14046         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14047
14048         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14049         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14050         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14051                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14052
14053         trap cleanup_130 EXIT RETURN
14054
14055         local fm_file=$DIR/$tfile
14056         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14057                 error "setstripe on $fm_file"
14058
14059         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14060                 error "dd failed on $fm_file"
14061
14062         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14063         filefrag_op=$(filefrag -ve -k $fm_file |
14064                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14065
14066         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14067                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14068
14069         IFS=$'\n'
14070         local tot_len=0
14071         local num_luns=1
14072
14073         for line in $filefrag_op; do
14074                 local frag_lun=$(echo $line | cut -d: -f5 |
14075                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14076                 local ext_len=$(echo $line | cut -d: -f4)
14077                 if (( $frag_lun != $last_lun )); then
14078                         if (( tot_len != 1024 )); then
14079                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14080                                 return
14081                         else
14082                                 (( num_luns += 1 ))
14083                                 tot_len=0
14084                         fi
14085                 fi
14086                 (( tot_len += ext_len ))
14087                 last_lun=$frag_lun
14088         done
14089         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14090                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14091                 return
14092         fi
14093
14094         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14095 }
14096 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14097
14098 test_130c() {
14099         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14100
14101         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14102         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14103         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14104                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14105
14106         trap cleanup_130 EXIT RETURN
14107
14108         local fm_file=$DIR/$tfile
14109         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14110
14111         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14112                 error "dd failed on $fm_file"
14113
14114         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14115         filefrag_op=$(filefrag -ve -k $fm_file |
14116                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14117
14118         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14119                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14120
14121         IFS=$'\n'
14122         local tot_len=0
14123         local num_luns=1
14124         for line in $filefrag_op; do
14125                 local frag_lun=$(echo $line | cut -d: -f5 |
14126                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14127                 local ext_len=$(echo $line | cut -d: -f4)
14128                 if (( $frag_lun != $last_lun )); then
14129                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14130                         if (( logical != 512 )); then
14131                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14132                                 return
14133                         fi
14134                         if (( tot_len != 512 )); then
14135                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14136                                 return
14137                         else
14138                                 (( num_luns += 1 ))
14139                                 tot_len=0
14140                         fi
14141                 fi
14142                 (( tot_len += ext_len ))
14143                 last_lun=$frag_lun
14144         done
14145         if (( num_luns != 2 || tot_len != 512 )); then
14146                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14147                 return
14148         fi
14149
14150         echo "FIEMAP on 2-stripe file with hole succeeded"
14151 }
14152 run_test 130c "FIEMAP (2-stripe file with hole)"
14153
14154 test_130d() {
14155         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14156
14157         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14158         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14159         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14160                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14161
14162         trap cleanup_130 EXIT RETURN
14163
14164         local fm_file=$DIR/$tfile
14165         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14166                         error "setstripe on $fm_file"
14167
14168         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14169         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14170                 error "dd failed on $fm_file"
14171
14172         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14173         filefrag_op=$(filefrag -ve -k $fm_file |
14174                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14175
14176         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14177                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14178
14179         IFS=$'\n'
14180         local tot_len=0
14181         local num_luns=1
14182         for line in $filefrag_op; do
14183                 local frag_lun=$(echo $line | cut -d: -f5 |
14184                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14185                 local ext_len=$(echo $line | cut -d: -f4)
14186                 if (( $frag_lun != $last_lun )); then
14187                         if (( tot_len != 1024 )); then
14188                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14189                                 return
14190                         else
14191                                 (( num_luns += 1 ))
14192                                 local tot_len=0
14193                         fi
14194                 fi
14195                 (( tot_len += ext_len ))
14196                 last_lun=$frag_lun
14197         done
14198         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14199                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14200                 return
14201         fi
14202
14203         echo "FIEMAP on N-stripe file succeeded"
14204 }
14205 run_test 130d "FIEMAP (N-stripe file)"
14206
14207 test_130e() {
14208         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14209
14210         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14211         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14212         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14213                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14214
14215         trap cleanup_130 EXIT RETURN
14216
14217         local fm_file=$DIR/$tfile
14218         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14219
14220         local num_blks=512
14221         local expected_len=$(( (num_blks / 2) * 64 ))
14222         for ((i = 0; i < $num_blks; i++)); do
14223                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14224                         conv=notrunc > /dev/null 2>&1
14225         done
14226
14227         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14228         filefrag_op=$(filefrag -ve -k $fm_file |
14229                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14230
14231         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14232
14233         IFS=$'\n'
14234         local tot_len=0
14235         local num_luns=1
14236         for line in $filefrag_op; do
14237                 local frag_lun=$(echo $line | cut -d: -f5)
14238                 local ext_len=$(echo $line | cut -d: -f4)
14239                 if (( $frag_lun != $last_lun )); then
14240                         if (( tot_len != $expected_len )); then
14241                                 error "OST$last_lun $tot_len != $expected_len"
14242                         else
14243                                 (( num_luns += 1 ))
14244                                 tot_len=0
14245                         fi
14246                 fi
14247                 (( tot_len += ext_len ))
14248                 last_lun=$frag_lun
14249         done
14250         if (( num_luns != 2 || tot_len != $expected_len )); then
14251                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14252         fi
14253
14254         echo "FIEMAP with continuation calls succeeded"
14255 }
14256 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14257
14258 test_130f() {
14259         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14260         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14261         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14262                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14263
14264         local fm_file=$DIR/$tfile
14265         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14266                 error "multiop create with lov_delay_create on $fm_file"
14267
14268         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14269         filefrag_extents=$(filefrag -vek $fm_file |
14270                            awk '/extents? found/ { print $2 }')
14271         if (( $filefrag_extents != 0 )); then
14272                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14273         fi
14274
14275         rm -f $fm_file
14276 }
14277 run_test 130f "FIEMAP (unstriped file)"
14278
14279 test_130g() {
14280         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14281                 skip "Need MDS version with at least 2.12.53 for overstriping"
14282         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14283         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14284         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14285                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14286
14287         local file=$DIR/$tfile
14288         local nr=$((OSTCOUNT * 100))
14289
14290         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14291
14292         stack_trap "rm -f $file"
14293         dd if=/dev/zero of=$file count=$nr bs=1M
14294         sync
14295         nr=$($LFS getstripe -c $file)
14296
14297         local extents=$(filefrag -v $file |
14298                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14299
14300         echo "filefrag list $extents extents in file with stripecount $nr"
14301         if (( extents < nr )); then
14302                 $LFS getstripe $file
14303                 filefrag -v $file
14304                 error "filefrag printed $extents < $nr extents"
14305         fi
14306 }
14307 run_test 130g "FIEMAP (overstripe file)"
14308
14309 # Test for writev/readv
14310 test_131a() {
14311         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14312                 error "writev test failed"
14313         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14314                 error "readv failed"
14315         rm -f $DIR/$tfile
14316 }
14317 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14318
14319 test_131b() {
14320         local fsize=$((524288 + 1048576 + 1572864))
14321         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14322                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14323                         error "append writev test failed"
14324
14325         ((fsize += 1572864 + 1048576))
14326         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14327                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14328                         error "append writev test failed"
14329         rm -f $DIR/$tfile
14330 }
14331 run_test 131b "test append writev"
14332
14333 test_131c() {
14334         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14335         error "NOT PASS"
14336 }
14337 run_test 131c "test read/write on file w/o objects"
14338
14339 test_131d() {
14340         rwv -f $DIR/$tfile -w -n 1 1572864
14341         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14342         if [ "$NOB" != 1572864 ]; then
14343                 error "Short read filed: read $NOB bytes instead of 1572864"
14344         fi
14345         rm -f $DIR/$tfile
14346 }
14347 run_test 131d "test short read"
14348
14349 test_131e() {
14350         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14351         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14352         error "read hitting hole failed"
14353         rm -f $DIR/$tfile
14354 }
14355 run_test 131e "test read hitting hole"
14356
14357 check_stats() {
14358         local facet=$1
14359         local op=$2
14360         local want=${3:-0}
14361         local res
14362
14363         # open             11 samples [usecs] 468 4793 13658 35791898
14364         case $facet in
14365         mds*) res=($(do_facet $facet \
14366                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14367                  ;;
14368         ost*) res=($(do_facet $facet \
14369                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14370                  ;;
14371         *) error "Wrong facet '$facet'" ;;
14372         esac
14373         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14374         # if $want is zero, it means any stat increment is ok.
14375         if (( $want > 0 )); then
14376                 local count=${res[1]}
14377
14378                 if (( $count != $want )); then
14379                         if [[ $facet =~ "mds" ]]; then
14380                                 do_nodes $(comma_list $(mdts_nodes)) \
14381                                         $LCTL get_param mdt.*.md_stats
14382                         else
14383                                 do_nodes $(comma_list $(osts-nodes)) \
14384                                         $LCTL get_param obdfilter.*.stats
14385                         fi
14386                         error "The $op counter on $facet is $count, not $want"
14387                 fi
14388         fi
14389 }
14390
14391 test_133a() {
14392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14393         remote_ost_nodsh && skip "remote OST with nodsh"
14394         remote_mds_nodsh && skip "remote MDS with nodsh"
14395         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14396                 skip_env "MDS doesn't support rename stats"
14397
14398         local testdir=$DIR/${tdir}/stats_testdir
14399
14400         mkdir -p $DIR/${tdir}
14401
14402         # clear stats.
14403         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14404         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14405
14406         # verify mdt stats first.
14407         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14408         check_stats $SINGLEMDS "mkdir" 1
14409
14410         # clear "open" from "lfs mkdir" above
14411         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14412         touch ${testdir}/${tfile} || error "touch failed"
14413         check_stats $SINGLEMDS "open" 1
14414         check_stats $SINGLEMDS "close" 1
14415         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14416                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14417                 check_stats $SINGLEMDS "mknod" 2
14418         }
14419         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14420         check_stats $SINGLEMDS "unlink" 1
14421         rm -f ${testdir}/${tfile} || error "file remove failed"
14422         check_stats $SINGLEMDS "unlink" 2
14423
14424         # remove working dir and check mdt stats again.
14425         rmdir ${testdir} || error "rmdir failed"
14426         check_stats $SINGLEMDS "rmdir" 1
14427
14428         local testdir1=$DIR/${tdir}/stats_testdir1
14429         mkdir_on_mdt0 -p ${testdir}
14430         mkdir_on_mdt0 -p ${testdir1}
14431         touch ${testdir1}/test1
14432         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14433         check_stats $SINGLEMDS "crossdir_rename" 1
14434
14435         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14436         check_stats $SINGLEMDS "samedir_rename" 1
14437
14438         rm -rf $DIR/${tdir}
14439 }
14440 run_test 133a "Verifying MDT stats ========================================"
14441
14442 test_133b() {
14443         local res
14444
14445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14446         remote_ost_nodsh && skip "remote OST with nodsh"
14447         remote_mds_nodsh && skip "remote MDS with nodsh"
14448
14449         local testdir=$DIR/${tdir}/stats_testdir
14450
14451         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14452         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14453         touch ${testdir}/${tfile} || error "touch failed"
14454         cancel_lru_locks mdc
14455
14456         # clear stats.
14457         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14458         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14459
14460         # extra mdt stats verification.
14461         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14462         check_stats $SINGLEMDS "setattr" 1
14463         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14464         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14465         then            # LU-1740
14466                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14467                 check_stats $SINGLEMDS "getattr" 1
14468         fi
14469         rm -rf $DIR/${tdir}
14470
14471         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14472         # so the check below is not reliable
14473         [ $MDSCOUNT -eq 1 ] || return 0
14474
14475         # Sleep to avoid a cached response.
14476         #define OBD_STATFS_CACHE_SECONDS 1
14477         sleep 2
14478         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14479         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14480         $LFS df || error "lfs failed"
14481         check_stats $SINGLEMDS "statfs" 1
14482
14483         # check aggregated statfs (LU-10018)
14484         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14485                 return 0
14486         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14487                 return 0
14488         sleep 2
14489         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14490         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14491         df $DIR
14492         check_stats $SINGLEMDS "statfs" 1
14493
14494         # We want to check that the client didn't send OST_STATFS to
14495         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14496         # extra care is needed here.
14497         if remote_mds; then
14498                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14499                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14500
14501                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14502                 [ "$res" ] && error "OST got STATFS"
14503         fi
14504
14505         return 0
14506 }
14507 run_test 133b "Verifying extra MDT stats =================================="
14508
14509 test_133c() {
14510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14511         remote_ost_nodsh && skip "remote OST with nodsh"
14512         remote_mds_nodsh && skip "remote MDS with nodsh"
14513
14514         local testdir=$DIR/$tdir/stats_testdir
14515
14516         test_mkdir -p $testdir
14517
14518         # verify obdfilter stats.
14519         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14520         sync
14521         cancel_lru_locks osc
14522         wait_delete_completed
14523
14524         # clear stats.
14525         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14526         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14527
14528         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14529                 error "dd failed"
14530         sync
14531         cancel_lru_locks osc
14532         check_stats ost1 "write" 1
14533
14534         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14535         check_stats ost1 "read" 1
14536
14537         > $testdir/$tfile || error "truncate failed"
14538         check_stats ost1 "punch" 1
14539
14540         rm -f $testdir/$tfile || error "file remove failed"
14541         wait_delete_completed
14542         check_stats ost1 "destroy" 1
14543
14544         rm -rf $DIR/$tdir
14545 }
14546 run_test 133c "Verifying OST stats ========================================"
14547
14548 order_2() {
14549         local value=$1
14550         local orig=$value
14551         local order=1
14552
14553         while [ $value -ge 2 ]; do
14554                 order=$((order*2))
14555                 value=$((value/2))
14556         done
14557
14558         if [ $orig -gt $order ]; then
14559                 order=$((order*2))
14560         fi
14561         echo $order
14562 }
14563
14564 size_in_KMGT() {
14565     local value=$1
14566     local size=('K' 'M' 'G' 'T');
14567     local i=0
14568     local size_string=$value
14569
14570     while [ $value -ge 1024 ]; do
14571         if [ $i -gt 3 ]; then
14572             #T is the biggest unit we get here, if that is bigger,
14573             #just return XXXT
14574             size_string=${value}T
14575             break
14576         fi
14577         value=$((value >> 10))
14578         if [ $value -lt 1024 ]; then
14579             size_string=${value}${size[$i]}
14580             break
14581         fi
14582         i=$((i + 1))
14583     done
14584
14585     echo $size_string
14586 }
14587
14588 get_rename_size() {
14589         local size=$1
14590         local context=${2:-.}
14591         local sample=$(do_facet $SINGLEMDS $LCTL \
14592                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14593                 grep -A1 $context |
14594                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14595         echo $sample
14596 }
14597
14598 test_133d() {
14599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14600         remote_ost_nodsh && skip "remote OST with nodsh"
14601         remote_mds_nodsh && skip "remote MDS with nodsh"
14602         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14603                 skip_env "MDS doesn't support rename stats"
14604
14605         local testdir1=$DIR/${tdir}/stats_testdir1
14606         local testdir2=$DIR/${tdir}/stats_testdir2
14607         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14608
14609         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14610
14611         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14612         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14613
14614         createmany -o $testdir1/test 512 || error "createmany failed"
14615
14616         # check samedir rename size
14617         mv ${testdir1}/test0 ${testdir1}/test_0
14618
14619         local testdir1_size=$(ls -l $DIR/${tdir} |
14620                 awk '/stats_testdir1/ {print $5}')
14621         local testdir2_size=$(ls -l $DIR/${tdir} |
14622                 awk '/stats_testdir2/ {print $5}')
14623
14624         testdir1_size=$(order_2 $testdir1_size)
14625         testdir2_size=$(order_2 $testdir2_size)
14626
14627         testdir1_size=$(size_in_KMGT $testdir1_size)
14628         testdir2_size=$(size_in_KMGT $testdir2_size)
14629
14630         echo "source rename dir size: ${testdir1_size}"
14631         echo "target rename dir size: ${testdir2_size}"
14632
14633         local cmd="do_facet $SINGLEMDS $LCTL "
14634         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14635
14636         eval $cmd || error "$cmd failed"
14637         local samedir=$($cmd | grep 'same_dir')
14638         local same_sample=$(get_rename_size $testdir1_size)
14639         [ -z "$samedir" ] && error "samedir_rename_size count error"
14640         [[ $same_sample -eq 1 ]] ||
14641                 error "samedir_rename_size error $same_sample"
14642         echo "Check same dir rename stats success"
14643
14644         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14645
14646         # check crossdir rename size
14647         mv ${testdir1}/test_0 ${testdir2}/test_0
14648
14649         testdir1_size=$(ls -l $DIR/${tdir} |
14650                 awk '/stats_testdir1/ {print $5}')
14651         testdir2_size=$(ls -l $DIR/${tdir} |
14652                 awk '/stats_testdir2/ {print $5}')
14653
14654         testdir1_size=$(order_2 $testdir1_size)
14655         testdir2_size=$(order_2 $testdir2_size)
14656
14657         testdir1_size=$(size_in_KMGT $testdir1_size)
14658         testdir2_size=$(size_in_KMGT $testdir2_size)
14659
14660         echo "source rename dir size: ${testdir1_size}"
14661         echo "target rename dir size: ${testdir2_size}"
14662
14663         eval $cmd || error "$cmd failed"
14664         local crossdir=$($cmd | grep 'crossdir')
14665         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14666         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14667         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14668         [[ $src_sample -eq 1 ]] ||
14669                 error "crossdir_rename_size error $src_sample"
14670         [[ $tgt_sample -eq 1 ]] ||
14671                 error "crossdir_rename_size error $tgt_sample"
14672         echo "Check cross dir rename stats success"
14673         rm -rf $DIR/${tdir}
14674 }
14675 run_test 133d "Verifying rename_stats ========================================"
14676
14677 test_133e() {
14678         remote_mds_nodsh && skip "remote MDS with nodsh"
14679         remote_ost_nodsh && skip "remote OST with nodsh"
14680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14681
14682         local testdir=$DIR/${tdir}/stats_testdir
14683         local ctr f0 f1 bs=32768 count=42 sum
14684
14685         mkdir -p ${testdir} || error "mkdir failed"
14686
14687         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14688
14689         for ctr in {write,read}_bytes; do
14690                 sync
14691                 cancel_lru_locks osc
14692
14693                 do_facet ost1 $LCTL set_param -n \
14694                         "obdfilter.*.exports.clear=clear"
14695
14696                 if [ $ctr = write_bytes ]; then
14697                         f0=/dev/zero
14698                         f1=${testdir}/${tfile}
14699                 else
14700                         f0=${testdir}/${tfile}
14701                         f1=/dev/null
14702                 fi
14703
14704                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14705                         error "dd failed"
14706                 sync
14707                 cancel_lru_locks osc
14708
14709                 sum=$(do_facet ost1 $LCTL get_param \
14710                         "obdfilter.*.exports.*.stats" |
14711                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14712                                 $1 == ctr { sum += $7 }
14713                                 END { printf("%0.0f", sum) }')
14714
14715                 if ((sum != bs * count)); then
14716                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14717                 fi
14718         done
14719
14720         rm -rf $DIR/${tdir}
14721 }
14722 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14723
14724 test_133f() {
14725         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14726                 skip "too old lustre for get_param -R ($facet_ver)"
14727
14728         # verifying readability.
14729         $LCTL get_param -R '*' &> /dev/null
14730
14731         # Verifing writability with badarea_io.
14732         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14733         local skipped_params='force_lbug|changelog_mask|daemon_file'
14734         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14735                 egrep -v "$skipped_params" |
14736                 xargs -n 1 find $proc_dirs -name |
14737                 xargs -n 1 badarea_io ||
14738                 error "client badarea_io failed"
14739
14740         # remount the FS in case writes/reads /proc break the FS
14741         cleanup || error "failed to unmount"
14742         setup || error "failed to setup"
14743 }
14744 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14745
14746 test_133g() {
14747         remote_mds_nodsh && skip "remote MDS with nodsh"
14748         remote_ost_nodsh && skip "remote OST with nodsh"
14749
14750         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14751         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14752         local facet
14753         for facet in mds1 ost1; do
14754                 local facet_ver=$(lustre_version_code $facet)
14755                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14756                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14757                 else
14758                         log "$facet: too old lustre for get_param -R"
14759                 fi
14760                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14761                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14762                                 tr -d = | egrep -v $skipped_params |
14763                                 xargs -n 1 find $proc_dirs -name |
14764                                 xargs -n 1 badarea_io" ||
14765                                         error "$facet badarea_io failed"
14766                 else
14767                         skip_noexit "$facet: too old lustre for get_param -R"
14768                 fi
14769         done
14770
14771         # remount the FS in case writes/reads /proc break the FS
14772         cleanup || error "failed to unmount"
14773         setup || error "failed to setup"
14774 }
14775 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14776
14777 test_133h() {
14778         remote_mds_nodsh && skip "remote MDS with nodsh"
14779         remote_ost_nodsh && skip "remote OST with nodsh"
14780         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14781                 skip "Need MDS version at least 2.9.54"
14782
14783         local facet
14784         for facet in client mds1 ost1; do
14785                 # Get the list of files that are missing the terminating newline
14786                 local plist=$(do_facet $facet
14787                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14788                 local ent
14789                 for ent in $plist; do
14790                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14791                                 awk -v FS='\v' -v RS='\v\v' \
14792                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14793                                         print FILENAME}'" 2>/dev/null)
14794                         [ -z $missing ] || {
14795                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14796                                 error "file does not end with newline: $facet-$ent"
14797                         }
14798                 done
14799         done
14800 }
14801 run_test 133h "Proc files should end with newlines"
14802
14803 test_134a() {
14804         remote_mds_nodsh && skip "remote MDS with nodsh"
14805         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14806                 skip "Need MDS version at least 2.7.54"
14807
14808         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14809         cancel_lru_locks mdc
14810
14811         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14812         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14813         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14814
14815         local nr=1000
14816         createmany -o $DIR/$tdir/f $nr ||
14817                 error "failed to create $nr files in $DIR/$tdir"
14818         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14819
14820         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14821         do_facet mds1 $LCTL set_param fail_loc=0x327
14822         do_facet mds1 $LCTL set_param fail_val=500
14823         touch $DIR/$tdir/m
14824
14825         echo "sleep 10 seconds ..."
14826         sleep 10
14827         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14828
14829         do_facet mds1 $LCTL set_param fail_loc=0
14830         do_facet mds1 $LCTL set_param fail_val=0
14831         [ $lck_cnt -lt $unused ] ||
14832                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14833
14834         rm $DIR/$tdir/m
14835         unlinkmany $DIR/$tdir/f $nr
14836 }
14837 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14838
14839 test_134b() {
14840         remote_mds_nodsh && skip "remote MDS with nodsh"
14841         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14842                 skip "Need MDS version at least 2.7.54"
14843
14844         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14845         cancel_lru_locks mdc
14846
14847         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14848                         ldlm.lock_reclaim_threshold_mb)
14849         # disable reclaim temporarily
14850         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14851
14852         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14853         do_facet mds1 $LCTL set_param fail_loc=0x328
14854         do_facet mds1 $LCTL set_param fail_val=500
14855
14856         $LCTL set_param debug=+trace
14857
14858         local nr=600
14859         createmany -o $DIR/$tdir/f $nr &
14860         local create_pid=$!
14861
14862         echo "Sleep $TIMEOUT seconds ..."
14863         sleep $TIMEOUT
14864         if ! ps -p $create_pid  > /dev/null 2>&1; then
14865                 do_facet mds1 $LCTL set_param fail_loc=0
14866                 do_facet mds1 $LCTL set_param fail_val=0
14867                 do_facet mds1 $LCTL set_param \
14868                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14869                 error "createmany finished incorrectly!"
14870         fi
14871         do_facet mds1 $LCTL set_param fail_loc=0
14872         do_facet mds1 $LCTL set_param fail_val=0
14873         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14874         wait $create_pid || return 1
14875
14876         unlinkmany $DIR/$tdir/f $nr
14877 }
14878 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14879
14880 test_135() {
14881         remote_mds_nodsh && skip "remote MDS with nodsh"
14882         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14883                 skip "Need MDS version at least 2.13.50"
14884         local fname
14885
14886         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14887
14888 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14889         #set only one record at plain llog
14890         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14891
14892         #fill already existed plain llog each 64767
14893         #wrapping whole catalog
14894         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14895
14896         createmany -o $DIR/$tdir/$tfile_ 64700
14897         for (( i = 0; i < 64700; i = i + 2 ))
14898         do
14899                 rm $DIR/$tdir/$tfile_$i &
14900                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14901                 local pid=$!
14902                 wait $pid
14903         done
14904
14905         #waiting osp synchronization
14906         wait_delete_completed
14907 }
14908 run_test 135 "Race catalog processing"
14909
14910 test_136() {
14911         remote_mds_nodsh && skip "remote MDS with nodsh"
14912         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14913                 skip "Need MDS version at least 2.13.50"
14914         local fname
14915
14916         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14917         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14918         #set only one record at plain llog
14919 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14920         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14921
14922         #fill already existed 2 plain llogs each 64767
14923         #wrapping whole catalog
14924         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14925         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14926         wait_delete_completed
14927
14928         createmany -o $DIR/$tdir/$tfile_ 10
14929         sleep 25
14930
14931         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14932         for (( i = 0; i < 10; i = i + 3 ))
14933         do
14934                 rm $DIR/$tdir/$tfile_$i &
14935                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14936                 local pid=$!
14937                 wait $pid
14938                 sleep 7
14939                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14940         done
14941
14942         #waiting osp synchronization
14943         wait_delete_completed
14944 }
14945 run_test 136 "Race catalog processing 2"
14946
14947 test_140() { #bug-17379
14948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14949
14950         test_mkdir $DIR/$tdir
14951         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14952         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14953
14954         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14955         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14956         local i=0
14957         while i=$((i + 1)); do
14958                 test_mkdir $i
14959                 cd $i || error "Changing to $i"
14960                 ln -s ../stat stat || error "Creating stat symlink"
14961                 # Read the symlink until ELOOP present,
14962                 # not LBUGing the system is considered success,
14963                 # we didn't overrun the stack.
14964                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14965                 if [ $ret -ne 0 ]; then
14966                         if [ $ret -eq 40 ]; then
14967                                 break  # -ELOOP
14968                         else
14969                                 error "Open stat symlink"
14970                                         return
14971                         fi
14972                 fi
14973         done
14974         i=$((i - 1))
14975         echo "The symlink depth = $i"
14976         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14977                 error "Invalid symlink depth"
14978
14979         # Test recursive symlink
14980         ln -s symlink_self symlink_self
14981         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14982         echo "open symlink_self returns $ret"
14983         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14984 }
14985 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14986
14987 test_150a() {
14988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14989
14990         local TF="$TMP/$tfile"
14991
14992         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14993         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14994         cp $TF $DIR/$tfile
14995         cancel_lru_locks $OSC
14996         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14997         remount_client $MOUNT
14998         df -P $MOUNT
14999         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15000
15001         $TRUNCATE $TF 6000
15002         $TRUNCATE $DIR/$tfile 6000
15003         cancel_lru_locks $OSC
15004         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15005
15006         echo "12345" >>$TF
15007         echo "12345" >>$DIR/$tfile
15008         cancel_lru_locks $OSC
15009         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15010
15011         echo "12345" >>$TF
15012         echo "12345" >>$DIR/$tfile
15013         cancel_lru_locks $OSC
15014         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15015 }
15016 run_test 150a "truncate/append tests"
15017
15018 test_150b() {
15019         check_set_fallocate_or_skip
15020         local out
15021
15022         touch $DIR/$tfile
15023         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15024         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15025                 skip_eopnotsupp "$out|check_fallocate failed"
15026 }
15027 run_test 150b "Verify fallocate (prealloc) functionality"
15028
15029 test_150bb() {
15030         check_set_fallocate_or_skip
15031
15032         touch $DIR/$tfile
15033         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15034         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15035         > $DIR/$tfile
15036         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15037         # precomputed md5sum for 20MB of zeroes
15038         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15039         local sum=($(md5sum $DIR/$tfile))
15040
15041         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15042
15043         check_set_fallocate 1
15044
15045         > $DIR/$tfile
15046         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15047         sum=($(md5sum $DIR/$tfile))
15048
15049         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15050 }
15051 run_test 150bb "Verify fallocate modes both zero space"
15052
15053 test_150c() {
15054         check_set_fallocate_or_skip
15055         local striping="-c2"
15056
15057         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15058         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15059         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15060         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15061         local want=$((OSTCOUNT * 1048576))
15062
15063         # Must allocate all requested space, not more than 5% extra
15064         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15065                 error "bytes $bytes is not $want"
15066
15067         rm -f $DIR/$tfile
15068
15069         echo "verify fallocate on PFL file"
15070
15071         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15072
15073         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15074                 error "Create $DIR/$tfile failed"
15075         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15076         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15077         want=$((512 * 1048576))
15078
15079         # Must allocate all requested space, not more than 5% extra
15080         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15081                 error "bytes $bytes is not $want"
15082 }
15083 run_test 150c "Verify fallocate Size and Blocks"
15084
15085 test_150d() {
15086         check_set_fallocate_or_skip
15087         local striping="-c2"
15088
15089         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15090
15091         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15092         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15093                 error "setstripe failed"
15094         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15095         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15096         local want=$((OSTCOUNT * 1048576))
15097
15098         # Must allocate all requested space, not more than 5% extra
15099         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15100                 error "bytes $bytes is not $want"
15101 }
15102 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15103
15104 test_150e() {
15105         check_set_fallocate_or_skip
15106
15107         echo "df before:"
15108         $LFS df
15109         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15110         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15111                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15112
15113         # Find OST with Minimum Size
15114         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15115                        sort -un | head -1)
15116
15117         # Get 100MB per OST of the available space to reduce run time
15118         # else 60% of the available space if we are running SLOW tests
15119         if [ $SLOW == "no" ]; then
15120                 local space=$((1024 * 100 * OSTCOUNT))
15121         else
15122                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15123         fi
15124
15125         fallocate -l${space}k $DIR/$tfile ||
15126                 error "fallocate ${space}k $DIR/$tfile failed"
15127         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15128
15129         # get size immediately after fallocate. This should be correctly
15130         # updated
15131         local size=$(stat -c '%s' $DIR/$tfile)
15132         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15133
15134         # Sleep for a while for statfs to get updated. And not pull from cache.
15135         sleep 2
15136
15137         echo "df after fallocate:"
15138         $LFS df
15139
15140         (( size / 1024 == space )) || error "size $size != requested $space"
15141         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15142                 error "used $used < space $space"
15143
15144         rm $DIR/$tfile || error "rm failed"
15145         sync
15146         wait_delete_completed
15147
15148         echo "df after unlink:"
15149         $LFS df
15150 }
15151 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15152
15153 test_150f() {
15154         local size
15155         local blocks
15156         local want_size_before=20480 # in bytes
15157         local want_blocks_before=40 # 512 sized blocks
15158         local want_blocks_after=24  # 512 sized blocks
15159         local length=$(((want_blocks_before - want_blocks_after) * 512))
15160
15161         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15162                 skip "need at least 2.14.0 for fallocate punch"
15163
15164         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15165                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15166         fi
15167
15168         check_set_fallocate_or_skip
15169         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15170
15171         [[ "x$DOM" == "xyes" ]] &&
15172                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15173
15174         echo "Verify fallocate punch: Range within the file range"
15175         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15176                 error "dd failed for bs 4096 and count 5"
15177
15178         # Call fallocate with punch range which is within the file range
15179         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15180                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15181         # client must see changes immediately after fallocate
15182         size=$(stat -c '%s' $DIR/$tfile)
15183         blocks=$(stat -c '%b' $DIR/$tfile)
15184
15185         # Verify punch worked.
15186         (( blocks == want_blocks_after )) ||
15187                 error "punch failed: blocks $blocks != $want_blocks_after"
15188
15189         (( size == want_size_before )) ||
15190                 error "punch failed: size $size != $want_size_before"
15191
15192         # Verify there is hole in file
15193         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15194         # precomputed md5sum
15195         local expect="4a9a834a2db02452929c0a348273b4aa"
15196
15197         cksum=($(md5sum $DIR/$tfile))
15198         [[ "${cksum[0]}" == "$expect" ]] ||
15199                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15200
15201         # Start second sub-case for fallocate punch.
15202         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15203         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15204                 error "dd failed for bs 4096 and count 5"
15205
15206         # Punch range less than block size will have no change in block count
15207         want_blocks_after=40  # 512 sized blocks
15208
15209         # Punch overlaps two blocks and less than blocksize
15210         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15211                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15212         size=$(stat -c '%s' $DIR/$tfile)
15213         blocks=$(stat -c '%b' $DIR/$tfile)
15214
15215         # Verify punch worked.
15216         (( blocks == want_blocks_after )) ||
15217                 error "punch failed: blocks $blocks != $want_blocks_after"
15218
15219         (( size == want_size_before )) ||
15220                 error "punch failed: size $size != $want_size_before"
15221
15222         # Verify if range is really zero'ed out. We expect Zeros.
15223         # precomputed md5sum
15224         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15225         cksum=($(md5sum $DIR/$tfile))
15226         [[ "${cksum[0]}" == "$expect" ]] ||
15227                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15228 }
15229 run_test 150f "Verify fallocate punch functionality"
15230
15231 test_150g() {
15232         local space
15233         local size
15234         local blocks
15235         local blocks_after
15236         local size_after
15237         local BS=4096 # Block size in bytes
15238
15239         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15240                 skip "need at least 2.14.0 for fallocate punch"
15241
15242         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15243                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15244         fi
15245
15246         check_set_fallocate_or_skip
15247         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15248
15249         if [[ "x$DOM" == "xyes" ]]; then
15250                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15251                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15252         else
15253                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15254                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15255         fi
15256
15257         # Get 100MB per OST of the available space to reduce run time
15258         # else 60% of the available space if we are running SLOW tests
15259         if [ $SLOW == "no" ]; then
15260                 space=$((1024 * 100 * OSTCOUNT))
15261         else
15262                 # Find OST with Minimum Size
15263                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15264                         sort -un | head -1)
15265                 echo "min size OST: $space"
15266                 space=$(((space * 60)/100 * OSTCOUNT))
15267         fi
15268         # space in 1k units, round to 4k blocks
15269         local blkcount=$((space * 1024 / $BS))
15270
15271         echo "Verify fallocate punch: Very large Range"
15272         fallocate -l${space}k $DIR/$tfile ||
15273                 error "fallocate ${space}k $DIR/$tfile failed"
15274         # write 1M at the end, start and in the middle
15275         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15276                 error "dd failed: bs $BS count 256"
15277         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15278                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15279         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15280                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15281
15282         # Gather stats.
15283         size=$(stat -c '%s' $DIR/$tfile)
15284
15285         # gather punch length.
15286         local punch_size=$((size - (BS * 2)))
15287
15288         echo "punch_size = $punch_size"
15289         echo "size - punch_size: $((size - punch_size))"
15290         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15291
15292         # Call fallocate to punch all except 2 blocks. We leave the
15293         # first and the last block
15294         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15295         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15296                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15297
15298         size_after=$(stat -c '%s' $DIR/$tfile)
15299         blocks_after=$(stat -c '%b' $DIR/$tfile)
15300
15301         # Verify punch worked.
15302         # Size should be kept
15303         (( size == size_after )) ||
15304                 error "punch failed: size $size != $size_after"
15305
15306         # two 4k data blocks to remain plus possible 1 extra extent block
15307         (( blocks_after <= ((BS / 512) * 3) )) ||
15308                 error "too many blocks remains: $blocks_after"
15309
15310         # Verify that file has hole between the first and the last blocks
15311         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15312         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15313
15314         echo "Hole at [$hole_start, $hole_end)"
15315         (( hole_start == BS )) ||
15316                 error "no hole at offset $BS after punch"
15317
15318         (( hole_end == BS + punch_size )) ||
15319                 error "data at offset $hole_end < $((BS + punch_size))"
15320 }
15321 run_test 150g "Verify fallocate punch on large range"
15322
15323 test_150h() {
15324         local file=$DIR/$tfile
15325         local size
15326
15327         check_set_fallocate_or_skip
15328         statx_supported || skip_env "Test must be statx() syscall supported"
15329
15330         # fallocate() does not update the size information on the MDT
15331         fallocate -l 16K $file || error "failed to fallocate $file"
15332         cancel_lru_locks $OSC
15333         # STATX with cached-always mode will not send glimpse RPCs to OST,
15334         # it uses the caching attrs on the client side as much as possible.
15335         size=$($STATX --cached=always -c %s $file)
15336         [ $size == 16384 ] ||
15337                 error "size after fallocate() is $size, expected 16384"
15338 }
15339 run_test 150h "Verify extend fallocate updates the file size"
15340
15341 #LU-2902 roc_hit was not able to read all values from lproc
15342 function roc_hit_init() {
15343         local list=$(comma_list $(osts_nodes))
15344         local dir=$DIR/$tdir-check
15345         local file=$dir/$tfile
15346         local BEFORE
15347         local AFTER
15348         local idx
15349
15350         test_mkdir $dir
15351         #use setstripe to do a write to every ost
15352         for i in $(seq 0 $((OSTCOUNT-1))); do
15353                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15354                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15355                 idx=$(printf %04x $i)
15356                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15357                         awk '$1 == "cache_access" {sum += $7}
15358                                 END { printf("%0.0f", sum) }')
15359
15360                 cancel_lru_locks osc
15361                 cat $file >/dev/null
15362
15363                 AFTER=$(get_osd_param $list *OST*$idx stats |
15364                         awk '$1 == "cache_access" {sum += $7}
15365                                 END { printf("%0.0f", sum) }')
15366
15367                 echo BEFORE:$BEFORE AFTER:$AFTER
15368                 if ! let "AFTER - BEFORE == 4"; then
15369                         rm -rf $dir
15370                         error "roc_hit is not safe to use"
15371                 fi
15372                 rm $file
15373         done
15374
15375         rm -rf $dir
15376 }
15377
15378 function roc_hit() {
15379         local list=$(comma_list $(osts_nodes))
15380         echo $(get_osd_param $list '' stats |
15381                 awk '$1 == "cache_hit" {sum += $7}
15382                         END { printf("%0.0f", sum) }')
15383 }
15384
15385 function set_cache() {
15386         local on=1
15387
15388         if [ "$2" == "off" ]; then
15389                 on=0;
15390         fi
15391         local list=$(comma_list $(osts_nodes))
15392         set_osd_param $list '' $1_cache_enable $on
15393
15394         cancel_lru_locks osc
15395 }
15396
15397 test_151() {
15398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15399         remote_ost_nodsh && skip "remote OST with nodsh"
15400
15401         local CPAGES=3
15402         local list=$(comma_list $(osts_nodes))
15403
15404         # check whether obdfilter is cache capable at all
15405         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15406                 skip "not cache-capable obdfilter"
15407         fi
15408
15409         # check cache is enabled on all obdfilters
15410         if get_osd_param $list '' read_cache_enable | grep 0; then
15411                 skip "oss cache is disabled"
15412         fi
15413
15414         set_osd_param $list '' writethrough_cache_enable 1
15415
15416         # check write cache is enabled on all obdfilters
15417         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15418                 skip "oss write cache is NOT enabled"
15419         fi
15420
15421         roc_hit_init
15422
15423         #define OBD_FAIL_OBD_NO_LRU  0x609
15424         do_nodes $list $LCTL set_param fail_loc=0x609
15425
15426         # pages should be in the case right after write
15427         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15428                 error "dd failed"
15429
15430         local BEFORE=$(roc_hit)
15431         cancel_lru_locks osc
15432         cat $DIR/$tfile >/dev/null
15433         local AFTER=$(roc_hit)
15434
15435         do_nodes $list $LCTL set_param fail_loc=0
15436
15437         if ! let "AFTER - BEFORE == CPAGES"; then
15438                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15439         fi
15440
15441         cancel_lru_locks osc
15442         # invalidates OST cache
15443         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15444         set_osd_param $list '' read_cache_enable 0
15445         cat $DIR/$tfile >/dev/null
15446
15447         # now data shouldn't be found in the cache
15448         BEFORE=$(roc_hit)
15449         cancel_lru_locks osc
15450         cat $DIR/$tfile >/dev/null
15451         AFTER=$(roc_hit)
15452         if let "AFTER - BEFORE != 0"; then
15453                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15454         fi
15455
15456         set_osd_param $list '' read_cache_enable 1
15457         rm -f $DIR/$tfile
15458 }
15459 run_test 151 "test cache on oss and controls ==============================="
15460
15461 test_152() {
15462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15463
15464         local TF="$TMP/$tfile"
15465
15466         # simulate ENOMEM during write
15467 #define OBD_FAIL_OST_NOMEM      0x226
15468         lctl set_param fail_loc=0x80000226
15469         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15470         cp $TF $DIR/$tfile
15471         sync || error "sync failed"
15472         lctl set_param fail_loc=0
15473
15474         # discard client's cache
15475         cancel_lru_locks osc
15476
15477         # simulate ENOMEM during read
15478         lctl set_param fail_loc=0x80000226
15479         cmp $TF $DIR/$tfile || error "cmp failed"
15480         lctl set_param fail_loc=0
15481
15482         rm -f $TF
15483 }
15484 run_test 152 "test read/write with enomem ============================"
15485
15486 test_153() {
15487         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15488 }
15489 run_test 153 "test if fdatasync does not crash ======================="
15490
15491 dot_lustre_fid_permission_check() {
15492         local fid=$1
15493         local ffid=$MOUNT/.lustre/fid/$fid
15494         local test_dir=$2
15495
15496         echo "stat fid $fid"
15497         stat $ffid || error "stat $ffid failed."
15498         echo "touch fid $fid"
15499         touch $ffid || error "touch $ffid failed."
15500         echo "write to fid $fid"
15501         cat /etc/hosts > $ffid || error "write $ffid failed."
15502         echo "read fid $fid"
15503         diff /etc/hosts $ffid || error "read $ffid failed."
15504         echo "append write to fid $fid"
15505         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15506         echo "rename fid $fid"
15507         mv $ffid $test_dir/$tfile.1 &&
15508                 error "rename $ffid to $tfile.1 should fail."
15509         touch $test_dir/$tfile.1
15510         mv $test_dir/$tfile.1 $ffid &&
15511                 error "rename $tfile.1 to $ffid should fail."
15512         rm -f $test_dir/$tfile.1
15513         echo "truncate fid $fid"
15514         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15515         echo "link fid $fid"
15516         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15517         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15518                 echo "setfacl fid $fid"
15519                 setfacl -R -m u:$USER0:rwx $ffid ||
15520                         error "setfacl $ffid failed"
15521                 echo "getfacl fid $fid"
15522                 getfacl $ffid || error "getfacl $ffid failed."
15523         fi
15524         echo "unlink fid $fid"
15525         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15526         echo "mknod fid $fid"
15527         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15528
15529         fid=[0xf00000400:0x1:0x0]
15530         ffid=$MOUNT/.lustre/fid/$fid
15531
15532         echo "stat non-exist fid $fid"
15533         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15534         echo "write to non-exist fid $fid"
15535         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15536         echo "link new fid $fid"
15537         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15538
15539         mkdir -p $test_dir/$tdir
15540         touch $test_dir/$tdir/$tfile
15541         fid=$($LFS path2fid $test_dir/$tdir)
15542         rc=$?
15543         [ $rc -ne 0 ] &&
15544                 error "error: could not get fid for $test_dir/$dir/$tfile."
15545
15546         ffid=$MOUNT/.lustre/fid/$fid
15547
15548         echo "ls $fid"
15549         ls $ffid || error "ls $ffid failed."
15550         echo "touch $fid/$tfile.1"
15551         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15552
15553         echo "touch $MOUNT/.lustre/fid/$tfile"
15554         touch $MOUNT/.lustre/fid/$tfile && \
15555                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15556
15557         echo "setxattr to $MOUNT/.lustre/fid"
15558         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15559
15560         echo "listxattr for $MOUNT/.lustre/fid"
15561         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15562
15563         echo "delxattr from $MOUNT/.lustre/fid"
15564         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15565
15566         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15567         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15568                 error "touch invalid fid should fail."
15569
15570         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15571         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15572                 error "touch non-normal fid should fail."
15573
15574         echo "rename $tdir to $MOUNT/.lustre/fid"
15575         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15576                 error "rename to $MOUNT/.lustre/fid should fail."
15577
15578         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15579         then            # LU-3547
15580                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15581                 local new_obf_mode=777
15582
15583                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15584                 chmod $new_obf_mode $DIR/.lustre/fid ||
15585                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15586
15587                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15588                 [ $obf_mode -eq $new_obf_mode ] ||
15589                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15590
15591                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15592                 chmod $old_obf_mode $DIR/.lustre/fid ||
15593                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15594         fi
15595
15596         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15597         fid=$($LFS path2fid $test_dir/$tfile-2)
15598
15599         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15600         then # LU-5424
15601                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15602                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15603                         error "create lov data thru .lustre failed"
15604         fi
15605         echo "cp /etc/passwd $test_dir/$tfile-2"
15606         cp /etc/passwd $test_dir/$tfile-2 ||
15607                 error "copy to $test_dir/$tfile-2 failed."
15608         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15609         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15610                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15611
15612         rm -rf $test_dir/tfile.lnk
15613         rm -rf $test_dir/$tfile-2
15614 }
15615
15616 test_154A() {
15617         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15618                 skip "Need MDS version at least 2.4.1"
15619
15620         local tf=$DIR/$tfile
15621         touch $tf
15622
15623         local fid=$($LFS path2fid $tf)
15624         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15625
15626         # check that we get the same pathname back
15627         local rootpath
15628         local found
15629         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15630                 echo "$rootpath $fid"
15631                 found=$($LFS fid2path $rootpath "$fid")
15632                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15633                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15634         done
15635
15636         # check wrong root path format
15637         rootpath=$MOUNT"_wrong"
15638         found=$($LFS fid2path $rootpath "$fid")
15639         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15640 }
15641 run_test 154A "lfs path2fid and fid2path basic checks"
15642
15643 test_154B() {
15644         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15645                 skip "Need MDS version at least 2.4.1"
15646
15647         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15648         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15649         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15650         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15651
15652         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15653         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15654
15655         # check that we get the same pathname
15656         echo "PFID: $PFID, name: $name"
15657         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15658         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15659         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15660                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15661
15662         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15663 }
15664 run_test 154B "verify the ll_decode_linkea tool"
15665
15666 test_154a() {
15667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15668         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15669         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15670                 skip "Need MDS version at least 2.2.51"
15671         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15672
15673         cp /etc/hosts $DIR/$tfile
15674
15675         fid=$($LFS path2fid $DIR/$tfile)
15676         rc=$?
15677         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15678
15679         dot_lustre_fid_permission_check "$fid" $DIR ||
15680                 error "dot lustre permission check $fid failed"
15681
15682         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15683
15684         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15685
15686         touch $MOUNT/.lustre/file &&
15687                 error "creation is not allowed under .lustre"
15688
15689         mkdir $MOUNT/.lustre/dir &&
15690                 error "mkdir is not allowed under .lustre"
15691
15692         rm -rf $DIR/$tfile
15693 }
15694 run_test 154a "Open-by-FID"
15695
15696 test_154b() {
15697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15698         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15699         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15700         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15701                 skip "Need MDS version at least 2.2.51"
15702
15703         local remote_dir=$DIR/$tdir/remote_dir
15704         local MDTIDX=1
15705         local rc=0
15706
15707         mkdir -p $DIR/$tdir
15708         $LFS mkdir -i $MDTIDX $remote_dir ||
15709                 error "create remote directory failed"
15710
15711         cp /etc/hosts $remote_dir/$tfile
15712
15713         fid=$($LFS path2fid $remote_dir/$tfile)
15714         rc=$?
15715         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15716
15717         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15718                 error "dot lustre permission check $fid failed"
15719         rm -rf $DIR/$tdir
15720 }
15721 run_test 154b "Open-by-FID for remote directory"
15722
15723 test_154c() {
15724         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15725                 skip "Need MDS version at least 2.4.1"
15726
15727         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15728         local FID1=$($LFS path2fid $DIR/$tfile.1)
15729         local FID2=$($LFS path2fid $DIR/$tfile.2)
15730         local FID3=$($LFS path2fid $DIR/$tfile.3)
15731
15732         local N=1
15733         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15734                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15735                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15736                 local want=FID$N
15737                 [ "$FID" = "${!want}" ] ||
15738                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15739                 N=$((N + 1))
15740         done
15741
15742         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15743         do
15744                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15745                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15746                 N=$((N + 1))
15747         done
15748 }
15749 run_test 154c "lfs path2fid and fid2path multiple arguments"
15750
15751 test_154d() {
15752         remote_mds_nodsh && skip "remote MDS with nodsh"
15753         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15754                 skip "Need MDS version at least 2.5.53"
15755
15756         if remote_mds; then
15757                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15758         else
15759                 nid="0@lo"
15760         fi
15761         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15762         local fd
15763         local cmd
15764
15765         rm -f $DIR/$tfile
15766         touch $DIR/$tfile
15767
15768         local fid=$($LFS path2fid $DIR/$tfile)
15769         # Open the file
15770         fd=$(free_fd)
15771         cmd="exec $fd<$DIR/$tfile"
15772         eval $cmd
15773         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15774         echo "$fid_list" | grep "$fid"
15775         rc=$?
15776
15777         cmd="exec $fd>/dev/null"
15778         eval $cmd
15779         if [ $rc -ne 0 ]; then
15780                 error "FID $fid not found in open files list $fid_list"
15781         fi
15782 }
15783 run_test 154d "Verify open file fid"
15784
15785 test_154e()
15786 {
15787         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15788                 skip "Need MDS version at least 2.6.50"
15789
15790         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15791                 error ".lustre returned by readdir"
15792         fi
15793 }
15794 run_test 154e ".lustre is not returned by readdir"
15795
15796 test_154f() {
15797         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15798
15799         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15800         mkdir_on_mdt0 $DIR/$tdir
15801         # test dirs inherit from its stripe
15802         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15803         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15804         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15805         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15806         touch $DIR/f
15807
15808         # get fid of parents
15809         local FID0=$($LFS path2fid $DIR/$tdir)
15810         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15811         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15812         local FID3=$($LFS path2fid $DIR)
15813
15814         # check that path2fid --parents returns expected <parent_fid>/name
15815         # 1) test for a directory (single parent)
15816         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15817         [ "$parent" == "$FID0/foo1" ] ||
15818                 error "expected parent: $FID0/foo1, got: $parent"
15819
15820         # 2) test for a file with nlink > 1 (multiple parents)
15821         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15822         echo "$parent" | grep -F "$FID1/$tfile" ||
15823                 error "$FID1/$tfile not returned in parent list"
15824         echo "$parent" | grep -F "$FID2/link" ||
15825                 error "$FID2/link not returned in parent list"
15826
15827         # 3) get parent by fid
15828         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15829         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15830         echo "$parent" | grep -F "$FID1/$tfile" ||
15831                 error "$FID1/$tfile not returned in parent list (by fid)"
15832         echo "$parent" | grep -F "$FID2/link" ||
15833                 error "$FID2/link not returned in parent list (by fid)"
15834
15835         # 4) test for entry in root directory
15836         parent=$($LFS path2fid --parents $DIR/f)
15837         echo "$parent" | grep -F "$FID3/f" ||
15838                 error "$FID3/f not returned in parent list"
15839
15840         # 5) test it on root directory
15841         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15842                 error "$MOUNT should not have parents"
15843
15844         # enable xattr caching and check that linkea is correctly updated
15845         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15846         save_lustre_params client "llite.*.xattr_cache" > $save
15847         lctl set_param llite.*.xattr_cache 1
15848
15849         # 6.1) linkea update on rename
15850         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15851
15852         # get parents by fid
15853         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15854         # foo1 should no longer be returned in parent list
15855         echo "$parent" | grep -F "$FID1" &&
15856                 error "$FID1 should no longer be in parent list"
15857         # the new path should appear
15858         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15859                 error "$FID2/$tfile.moved is not in parent list"
15860
15861         # 6.2) linkea update on unlink
15862         rm -f $DIR/$tdir/foo2/link
15863         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15864         # foo2/link should no longer be returned in parent list
15865         echo "$parent" | grep -F "$FID2/link" &&
15866                 error "$FID2/link should no longer be in parent list"
15867         true
15868
15869         rm -f $DIR/f
15870         restore_lustre_params < $save
15871         rm -f $save
15872 }
15873 run_test 154f "get parent fids by reading link ea"
15874
15875 test_154g()
15876 {
15877         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15878            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15879                 skip "Need MDS version at least 2.6.92"
15880
15881         mkdir_on_mdt0 $DIR/$tdir
15882         llapi_fid_test -d $DIR/$tdir
15883 }
15884 run_test 154g "various llapi FID tests"
15885
15886 test_155_small_load() {
15887     local temp=$TMP/$tfile
15888     local file=$DIR/$tfile
15889
15890     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15891         error "dd of=$temp bs=6096 count=1 failed"
15892     cp $temp $file
15893     cancel_lru_locks $OSC
15894     cmp $temp $file || error "$temp $file differ"
15895
15896     $TRUNCATE $temp 6000
15897     $TRUNCATE $file 6000
15898     cmp $temp $file || error "$temp $file differ (truncate1)"
15899
15900     echo "12345" >>$temp
15901     echo "12345" >>$file
15902     cmp $temp $file || error "$temp $file differ (append1)"
15903
15904     echo "12345" >>$temp
15905     echo "12345" >>$file
15906     cmp $temp $file || error "$temp $file differ (append2)"
15907
15908     rm -f $temp $file
15909     true
15910 }
15911
15912 test_155_big_load() {
15913         remote_ost_nodsh && skip "remote OST with nodsh"
15914
15915         local temp=$TMP/$tfile
15916         local file=$DIR/$tfile
15917
15918         free_min_max
15919         local cache_size=$(do_facet ost$((MAXI+1)) \
15920                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15921
15922         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15923         # pre-set value
15924         if [ -z "$cache_size" ]; then
15925                 cache_size=256
15926         fi
15927         local large_file_size=$((cache_size * 2))
15928
15929         echo "OSS cache size: $cache_size KB"
15930         echo "Large file size: $large_file_size KB"
15931
15932         [ $MAXV -le $large_file_size ] &&
15933                 skip_env "max available OST size needs > $large_file_size KB"
15934
15935         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15936
15937         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15938                 error "dd of=$temp bs=$large_file_size count=1k failed"
15939         cp $temp $file
15940         ls -lh $temp $file
15941         cancel_lru_locks osc
15942         cmp $temp $file || error "$temp $file differ"
15943
15944         rm -f $temp $file
15945         true
15946 }
15947
15948 save_writethrough() {
15949         local facets=$(get_facets OST)
15950
15951         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15952 }
15953
15954 test_155a() {
15955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15956
15957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15958
15959         save_writethrough $p
15960
15961         set_cache read on
15962         set_cache writethrough on
15963         test_155_small_load
15964         restore_lustre_params < $p
15965         rm -f $p
15966 }
15967 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15968
15969 test_155b() {
15970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15971
15972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15973
15974         save_writethrough $p
15975
15976         set_cache read on
15977         set_cache writethrough off
15978         test_155_small_load
15979         restore_lustre_params < $p
15980         rm -f $p
15981 }
15982 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15983
15984 test_155c() {
15985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15986
15987         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15988
15989         save_writethrough $p
15990
15991         set_cache read off
15992         set_cache writethrough on
15993         test_155_small_load
15994         restore_lustre_params < $p
15995         rm -f $p
15996 }
15997 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15998
15999 test_155d() {
16000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16001
16002         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16003
16004         save_writethrough $p
16005
16006         set_cache read off
16007         set_cache writethrough off
16008         test_155_small_load
16009         restore_lustre_params < $p
16010         rm -f $p
16011 }
16012 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16013
16014 test_155e() {
16015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16016
16017         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16018
16019         save_writethrough $p
16020
16021         set_cache read on
16022         set_cache writethrough on
16023         test_155_big_load
16024         restore_lustre_params < $p
16025         rm -f $p
16026 }
16027 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16028
16029 test_155f() {
16030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16031
16032         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16033
16034         save_writethrough $p
16035
16036         set_cache read on
16037         set_cache writethrough off
16038         test_155_big_load
16039         restore_lustre_params < $p
16040         rm -f $p
16041 }
16042 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16043
16044 test_155g() {
16045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16046
16047         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16048
16049         save_writethrough $p
16050
16051         set_cache read off
16052         set_cache writethrough on
16053         test_155_big_load
16054         restore_lustre_params < $p
16055         rm -f $p
16056 }
16057 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16058
16059 test_155h() {
16060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16061
16062         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16063
16064         save_writethrough $p
16065
16066         set_cache read off
16067         set_cache writethrough off
16068         test_155_big_load
16069         restore_lustre_params < $p
16070         rm -f $p
16071 }
16072 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16073
16074 test_156() {
16075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16076         remote_ost_nodsh && skip "remote OST with nodsh"
16077         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16078                 skip "stats not implemented on old servers"
16079         [ "$ost1_FSTYPE" = "zfs" ] &&
16080                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16081
16082         local CPAGES=3
16083         local BEFORE
16084         local AFTER
16085         local file="$DIR/$tfile"
16086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16087
16088         save_writethrough $p
16089         roc_hit_init
16090
16091         log "Turn on read and write cache"
16092         set_cache read on
16093         set_cache writethrough on
16094
16095         log "Write data and read it back."
16096         log "Read should be satisfied from the cache."
16097         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16098         BEFORE=$(roc_hit)
16099         cancel_lru_locks osc
16100         cat $file >/dev/null
16101         AFTER=$(roc_hit)
16102         if ! let "AFTER - BEFORE == CPAGES"; then
16103                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16104         else
16105                 log "cache hits: before: $BEFORE, after: $AFTER"
16106         fi
16107
16108         log "Read again; it should be satisfied from the cache."
16109         BEFORE=$AFTER
16110         cancel_lru_locks osc
16111         cat $file >/dev/null
16112         AFTER=$(roc_hit)
16113         if ! let "AFTER - BEFORE == CPAGES"; then
16114                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16115         else
16116                 log "cache hits:: before: $BEFORE, after: $AFTER"
16117         fi
16118
16119         log "Turn off the read cache and turn on the write cache"
16120         set_cache read off
16121         set_cache writethrough on
16122
16123         log "Read again; it should be satisfied from the cache."
16124         BEFORE=$(roc_hit)
16125         cancel_lru_locks osc
16126         cat $file >/dev/null
16127         AFTER=$(roc_hit)
16128         if ! let "AFTER - BEFORE == CPAGES"; then
16129                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16130         else
16131                 log "cache hits:: before: $BEFORE, after: $AFTER"
16132         fi
16133
16134         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16135                 # > 2.12.56 uses pagecache if cached
16136                 log "Read again; it should not be satisfied from the cache."
16137                 BEFORE=$AFTER
16138                 cancel_lru_locks osc
16139                 cat $file >/dev/null
16140                 AFTER=$(roc_hit)
16141                 if ! let "AFTER - BEFORE == 0"; then
16142                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16143                 else
16144                         log "cache hits:: before: $BEFORE, after: $AFTER"
16145                 fi
16146         fi
16147
16148         log "Write data and read it back."
16149         log "Read should be satisfied from the cache."
16150         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16151         BEFORE=$(roc_hit)
16152         cancel_lru_locks osc
16153         cat $file >/dev/null
16154         AFTER=$(roc_hit)
16155         if ! let "AFTER - BEFORE == CPAGES"; then
16156                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16157         else
16158                 log "cache hits:: before: $BEFORE, after: $AFTER"
16159         fi
16160
16161         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16162                 # > 2.12.56 uses pagecache if cached
16163                 log "Read again; it should not be satisfied from the cache."
16164                 BEFORE=$AFTER
16165                 cancel_lru_locks osc
16166                 cat $file >/dev/null
16167                 AFTER=$(roc_hit)
16168                 if ! let "AFTER - BEFORE == 0"; then
16169                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16170                 else
16171                         log "cache hits:: before: $BEFORE, after: $AFTER"
16172                 fi
16173         fi
16174
16175         log "Turn off read and write cache"
16176         set_cache read off
16177         set_cache writethrough off
16178
16179         log "Write data and read it back"
16180         log "It should not be satisfied from the cache."
16181         rm -f $file
16182         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16183         cancel_lru_locks osc
16184         BEFORE=$(roc_hit)
16185         cat $file >/dev/null
16186         AFTER=$(roc_hit)
16187         if ! let "AFTER - BEFORE == 0"; then
16188                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16189         else
16190                 log "cache hits:: before: $BEFORE, after: $AFTER"
16191         fi
16192
16193         log "Turn on the read cache and turn off the write cache"
16194         set_cache read on
16195         set_cache writethrough off
16196
16197         log "Write data and read it back"
16198         log "It should not be satisfied from the cache."
16199         rm -f $file
16200         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16201         BEFORE=$(roc_hit)
16202         cancel_lru_locks osc
16203         cat $file >/dev/null
16204         AFTER=$(roc_hit)
16205         if ! let "AFTER - BEFORE == 0"; then
16206                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16207         else
16208                 log "cache hits:: before: $BEFORE, after: $AFTER"
16209         fi
16210
16211         log "Read again; it should be satisfied from the cache."
16212         BEFORE=$(roc_hit)
16213         cancel_lru_locks osc
16214         cat $file >/dev/null
16215         AFTER=$(roc_hit)
16216         if ! let "AFTER - BEFORE == CPAGES"; then
16217                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16218         else
16219                 log "cache hits:: before: $BEFORE, after: $AFTER"
16220         fi
16221
16222         restore_lustre_params < $p
16223         rm -f $p $file
16224 }
16225 run_test 156 "Verification of tunables"
16226
16227 test_160a() {
16228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16229         remote_mds_nodsh && skip "remote MDS with nodsh"
16230         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16231                 skip "Need MDS version at least 2.2.0"
16232
16233         changelog_register || error "changelog_register failed"
16234         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16235         changelog_users $SINGLEMDS | grep -q $cl_user ||
16236                 error "User $cl_user not found in changelog_users"
16237
16238         mkdir_on_mdt0 $DIR/$tdir
16239
16240         # change something
16241         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16242         changelog_clear 0 || error "changelog_clear failed"
16243         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16244         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16245         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16246         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16247         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16248         rm $DIR/$tdir/pics/desktop.jpg
16249
16250         echo "verifying changelog mask"
16251         changelog_chmask "-MKDIR"
16252         changelog_chmask "-CLOSE"
16253
16254         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16255         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16256
16257         changelog_chmask "+MKDIR"
16258         changelog_chmask "+CLOSE"
16259
16260         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16261         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16262
16263         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16264         CLOSES=$(changelog_dump | grep -c "CLOSE")
16265         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16266         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16267
16268         # verify contents
16269         echo "verifying target fid"
16270         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16271         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16272         [ "$fidc" == "$fidf" ] ||
16273                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16274         echo "verifying parent fid"
16275         # The FID returned from the Changelog may be the directory shard on
16276         # a different MDT, and not the FID returned by path2fid on the parent.
16277         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16278         # since this is what will matter when recreating this file in the tree.
16279         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16280         local pathp=$($LFS fid2path $MOUNT "$fidp")
16281         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16282                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16283
16284         echo "getting records for $cl_user"
16285         changelog_users $SINGLEMDS
16286         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16287         local nclr=3
16288         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16289                 error "changelog_clear failed"
16290         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16291         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16292         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16293                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16294
16295         local min0_rec=$(changelog_users $SINGLEMDS |
16296                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16297         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16298                           awk '{ print $1; exit; }')
16299
16300         changelog_dump | tail -n 5
16301         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16302         [ $first_rec == $((min0_rec + 1)) ] ||
16303                 error "first index should be $min0_rec + 1 not $first_rec"
16304
16305         # LU-3446 changelog index reset on MDT restart
16306         local cur_rec1=$(changelog_users $SINGLEMDS |
16307                          awk '/^current.index:/ { print $NF }')
16308         changelog_clear 0 ||
16309                 error "clear all changelog records for $cl_user failed"
16310         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16311         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16312                 error "Fail to start $SINGLEMDS"
16313         local cur_rec2=$(changelog_users $SINGLEMDS |
16314                          awk '/^current.index:/ { print $NF }')
16315         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16316         [ $cur_rec1 == $cur_rec2 ] ||
16317                 error "current index should be $cur_rec1 not $cur_rec2"
16318
16319         echo "verifying users from this test are deregistered"
16320         changelog_deregister || error "changelog_deregister failed"
16321         changelog_users $SINGLEMDS | grep -q $cl_user &&
16322                 error "User '$cl_user' still in changelog_users"
16323
16324         # lctl get_param -n mdd.*.changelog_users
16325         # current_index: 144
16326         # ID    index (idle seconds)
16327         # cl3   144   (2) mask=<list>
16328         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16329                 # this is the normal case where all users were deregistered
16330                 # make sure no new records are added when no users are present
16331                 local last_rec1=$(changelog_users $SINGLEMDS |
16332                                   awk '/^current.index:/ { print $NF }')
16333                 touch $DIR/$tdir/chloe
16334                 local last_rec2=$(changelog_users $SINGLEMDS |
16335                                   awk '/^current.index:/ { print $NF }')
16336                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16337                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16338         else
16339                 # any changelog users must be leftovers from a previous test
16340                 changelog_users $SINGLEMDS
16341                 echo "other changelog users; can't verify off"
16342         fi
16343 }
16344 run_test 160a "changelog sanity"
16345
16346 test_160b() { # LU-3587
16347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16348         remote_mds_nodsh && skip "remote MDS with nodsh"
16349         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16350                 skip "Need MDS version at least 2.2.0"
16351
16352         changelog_register || error "changelog_register failed"
16353         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16354         changelog_users $SINGLEMDS | grep -q $cl_user ||
16355                 error "User '$cl_user' not found in changelog_users"
16356
16357         local longname1=$(str_repeat a 255)
16358         local longname2=$(str_repeat b 255)
16359
16360         cd $DIR
16361         echo "creating very long named file"
16362         touch $longname1 || error "create of '$longname1' failed"
16363         echo "renaming very long named file"
16364         mv $longname1 $longname2
16365
16366         changelog_dump | grep RENME | tail -n 5
16367         rm -f $longname2
16368 }
16369 run_test 160b "Verify that very long rename doesn't crash in changelog"
16370
16371 test_160c() {
16372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16373         remote_mds_nodsh && skip "remote MDS with nodsh"
16374
16375         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16376                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16377                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16378                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16379
16380         local rc=0
16381
16382         # Registration step
16383         changelog_register || error "changelog_register failed"
16384
16385         rm -rf $DIR/$tdir
16386         mkdir -p $DIR/$tdir
16387         $MCREATE $DIR/$tdir/foo_160c
16388         changelog_chmask "-TRUNC"
16389         $TRUNCATE $DIR/$tdir/foo_160c 200
16390         changelog_chmask "+TRUNC"
16391         $TRUNCATE $DIR/$tdir/foo_160c 199
16392         changelog_dump | tail -n 5
16393         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16394         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16395 }
16396 run_test 160c "verify that changelog log catch the truncate event"
16397
16398 test_160d() {
16399         remote_mds_nodsh && skip "remote MDS with nodsh"
16400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16402         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16403                 skip "Need MDS version at least 2.7.60"
16404
16405         # Registration step
16406         changelog_register || error "changelog_register failed"
16407
16408         mkdir -p $DIR/$tdir/migrate_dir
16409         changelog_clear 0 || error "changelog_clear failed"
16410
16411         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16412         changelog_dump | tail -n 5
16413         local migrates=$(changelog_dump | grep -c "MIGRT")
16414         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16415 }
16416 run_test 160d "verify that changelog log catch the migrate event"
16417
16418 test_160e() {
16419         remote_mds_nodsh && skip "remote MDS with nodsh"
16420
16421         # Create a user
16422         changelog_register || error "changelog_register failed"
16423
16424         local MDT0=$(facet_svc $SINGLEMDS)
16425         local rc
16426
16427         # No user (expect fail)
16428         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16429         rc=$?
16430         if [ $rc -eq 0 ]; then
16431                 error "Should fail without user"
16432         elif [ $rc -ne 4 ]; then
16433                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16434         fi
16435
16436         # Delete a future user (expect fail)
16437         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16438         rc=$?
16439         if [ $rc -eq 0 ]; then
16440                 error "Deleted non-existant user cl77"
16441         elif [ $rc -ne 2 ]; then
16442                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16443         fi
16444
16445         # Clear to a bad index (1 billion should be safe)
16446         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16447         rc=$?
16448
16449         if [ $rc -eq 0 ]; then
16450                 error "Successfully cleared to invalid CL index"
16451         elif [ $rc -ne 22 ]; then
16452                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16453         fi
16454 }
16455 run_test 160e "changelog negative testing (should return errors)"
16456
16457 test_160f() {
16458         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16459         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16460                 skip "Need MDS version at least 2.10.56"
16461
16462         local mdts=$(comma_list $(mdts_nodes))
16463
16464         # Create a user
16465         changelog_register || error "first changelog_register failed"
16466         changelog_register || error "second changelog_register failed"
16467         local cl_users
16468         declare -A cl_user1
16469         declare -A cl_user2
16470         local user_rec1
16471         local user_rec2
16472         local i
16473
16474         # generate some changelog records to accumulate on each MDT
16475         # use all_char because created files should be evenly distributed
16476         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16477                 error "test_mkdir $tdir failed"
16478         log "$(date +%s): creating first files"
16479         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16480                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16481                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16482         done
16483
16484         # check changelogs have been generated
16485         local start=$SECONDS
16486         local idle_time=$((MDSCOUNT * 5 + 5))
16487         local nbcl=$(changelog_dump | wc -l)
16488         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16489
16490         for param in "changelog_max_idle_time=$idle_time" \
16491                      "changelog_gc=1" \
16492                      "changelog_min_gc_interval=2" \
16493                      "changelog_min_free_cat_entries=3"; do
16494                 local MDT0=$(facet_svc $SINGLEMDS)
16495                 local var="${param%=*}"
16496                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16497
16498                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16499                 do_nodes $mdts $LCTL set_param mdd.*.$param
16500         done
16501
16502         # force cl_user2 to be idle (1st part), but also cancel the
16503         # cl_user1 records so that it is not evicted later in the test.
16504         local sleep1=$((idle_time / 2))
16505         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16506         sleep $sleep1
16507
16508         # simulate changelog catalog almost full
16509         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16510         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16511
16512         for i in $(seq $MDSCOUNT); do
16513                 cl_users=(${CL_USERS[mds$i]})
16514                 cl_user1[mds$i]="${cl_users[0]}"
16515                 cl_user2[mds$i]="${cl_users[1]}"
16516
16517                 [ -n "${cl_user1[mds$i]}" ] ||
16518                         error "mds$i: no user registered"
16519                 [ -n "${cl_user2[mds$i]}" ] ||
16520                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16521
16522                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16523                 [ -n "$user_rec1" ] ||
16524                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16525                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16526                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16527                 [ -n "$user_rec2" ] ||
16528                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16529                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16530                      "$user_rec1 + 2 == $user_rec2"
16531                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16532                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16533                               "$user_rec1 + 2, but is $user_rec2"
16534                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16535                 [ -n "$user_rec2" ] ||
16536                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16537                 [ $user_rec1 == $user_rec2 ] ||
16538                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16539                               "$user_rec1, but is $user_rec2"
16540         done
16541
16542         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16543         local sleep2=$((idle_time - (SECONDS - start) + 1))
16544         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16545         sleep $sleep2
16546
16547         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16548         # cl_user1 should be OK because it recently processed records.
16549         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16550         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16551                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16552                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16553         done
16554
16555         # ensure gc thread is done
16556         for i in $(mdts_nodes); do
16557                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16558                         error "$i: GC-thread not done"
16559         done
16560
16561         local first_rec
16562         for (( i = 1; i <= MDSCOUNT; i++ )); do
16563                 # check cl_user1 still registered
16564                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16565                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16566                 # check cl_user2 unregistered
16567                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16568                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16569
16570                 # check changelogs are present and starting at $user_rec1 + 1
16571                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16572                 [ -n "$user_rec1" ] ||
16573                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16574                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16575                             awk '{ print $1; exit; }')
16576
16577                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16578                 [ $((user_rec1 + 1)) == $first_rec ] ||
16579                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16580         done
16581 }
16582 run_test 160f "changelog garbage collect (timestamped users)"
16583
16584 test_160g() {
16585         remote_mds_nodsh && skip "remote MDS with nodsh"
16586         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16587                 skip "Need MDS version at least 2.14.55"
16588
16589         local mdts=$(comma_list $(mdts_nodes))
16590
16591         # Create a user
16592         changelog_register || error "first changelog_register failed"
16593         changelog_register || error "second changelog_register failed"
16594         local cl_users
16595         declare -A cl_user1
16596         declare -A cl_user2
16597         local user_rec1
16598         local user_rec2
16599         local i
16600
16601         # generate some changelog records to accumulate on each MDT
16602         # use all_char because created files should be evenly distributed
16603         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16604                 error "test_mkdir $tdir failed"
16605         for ((i = 0; i < MDSCOUNT; i++)); do
16606                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16607                         error "create $DIR/$tdir/d$i.1 failed"
16608         done
16609
16610         # check changelogs have been generated
16611         local nbcl=$(changelog_dump | wc -l)
16612         (( $nbcl > 0 )) || error "no changelogs found"
16613
16614         # reduce the max_idle_indexes value to make sure we exceed it
16615         for param in "changelog_max_idle_indexes=2" \
16616                      "changelog_gc=1" \
16617                      "changelog_min_gc_interval=2"; do
16618                 local MDT0=$(facet_svc $SINGLEMDS)
16619                 local var="${param%=*}"
16620                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16621
16622                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16623                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16624                         error "unable to set mdd.*.$param"
16625         done
16626
16627         local start=$SECONDS
16628         for i in $(seq $MDSCOUNT); do
16629                 cl_users=(${CL_USERS[mds$i]})
16630                 cl_user1[mds$i]="${cl_users[0]}"
16631                 cl_user2[mds$i]="${cl_users[1]}"
16632
16633                 [ -n "${cl_user1[mds$i]}" ] ||
16634                         error "mds$i: user1 is not registered"
16635                 [ -n "${cl_user2[mds$i]}" ] ||
16636                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16637
16638                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16639                 [ -n "$user_rec1" ] ||
16640                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16641                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16642                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16643                 [ -n "$user_rec2" ] ||
16644                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16645                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16646                      "$user_rec1 + 2 == $user_rec2"
16647                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16648                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16649                               "expected $user_rec1 + 2, but is $user_rec2"
16650                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16651                 [ -n "$user_rec2" ] ||
16652                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16653                 [ $user_rec1 == $user_rec2 ] ||
16654                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16655                               "expected $user_rec1, but is $user_rec2"
16656         done
16657
16658         # ensure we are past the previous changelog_min_gc_interval set above
16659         local sleep2=$((start + 2 - SECONDS))
16660         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16661         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16662         # cl_user1 should be OK because it recently processed records.
16663         for ((i = 0; i < MDSCOUNT; i++)); do
16664                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16665                         error "create $DIR/$tdir/d$i.3 failed"
16666         done
16667
16668         # ensure gc thread is done
16669         for i in $(mdts_nodes); do
16670                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16671                         error "$i: GC-thread not done"
16672         done
16673
16674         local first_rec
16675         for (( i = 1; i <= MDSCOUNT; i++ )); do
16676                 # check cl_user1 still registered
16677                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16678                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16679                 # check cl_user2 unregistered
16680                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16681                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16682
16683                 # check changelogs are present and starting at $user_rec1 + 1
16684                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16685                 [ -n "$user_rec1" ] ||
16686                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16687                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16688                             awk '{ print $1; exit; }')
16689
16690                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16691                 [ $((user_rec1 + 1)) == $first_rec ] ||
16692                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16693         done
16694 }
16695 run_test 160g "changelog garbage collect on idle records"
16696
16697 test_160h() {
16698         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16699         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16700                 skip "Need MDS version at least 2.10.56"
16701
16702         local mdts=$(comma_list $(mdts_nodes))
16703
16704         # Create a user
16705         changelog_register || error "first changelog_register failed"
16706         changelog_register || error "second changelog_register failed"
16707         local cl_users
16708         declare -A cl_user1
16709         declare -A cl_user2
16710         local user_rec1
16711         local user_rec2
16712         local i
16713
16714         # generate some changelog records to accumulate on each MDT
16715         # use all_char because created files should be evenly distributed
16716         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16717                 error "test_mkdir $tdir failed"
16718         for ((i = 0; i < MDSCOUNT; i++)); do
16719                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16720                         error "create $DIR/$tdir/d$i.1 failed"
16721         done
16722
16723         # check changelogs have been generated
16724         local nbcl=$(changelog_dump | wc -l)
16725         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16726
16727         for param in "changelog_max_idle_time=10" \
16728                      "changelog_gc=1" \
16729                      "changelog_min_gc_interval=2"; do
16730                 local MDT0=$(facet_svc $SINGLEMDS)
16731                 local var="${param%=*}"
16732                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16733
16734                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16735                 do_nodes $mdts $LCTL set_param mdd.*.$param
16736         done
16737
16738         # force cl_user2 to be idle (1st part)
16739         sleep 9
16740
16741         for i in $(seq $MDSCOUNT); do
16742                 cl_users=(${CL_USERS[mds$i]})
16743                 cl_user1[mds$i]="${cl_users[0]}"
16744                 cl_user2[mds$i]="${cl_users[1]}"
16745
16746                 [ -n "${cl_user1[mds$i]}" ] ||
16747                         error "mds$i: no user registered"
16748                 [ -n "${cl_user2[mds$i]}" ] ||
16749                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16750
16751                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16752                 [ -n "$user_rec1" ] ||
16753                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16754                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16755                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16756                 [ -n "$user_rec2" ] ||
16757                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16758                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16759                      "$user_rec1 + 2 == $user_rec2"
16760                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16761                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16762                               "$user_rec1 + 2, but is $user_rec2"
16763                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16764                 [ -n "$user_rec2" ] ||
16765                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16766                 [ $user_rec1 == $user_rec2 ] ||
16767                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16768                               "$user_rec1, but is $user_rec2"
16769         done
16770
16771         # force cl_user2 to be idle (2nd part) and to reach
16772         # changelog_max_idle_time
16773         sleep 2
16774
16775         # force each GC-thread start and block then
16776         # one per MDT/MDD, set fail_val accordingly
16777         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16778         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16779
16780         # generate more changelogs to trigger fail_loc
16781         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16782                 error "create $DIR/$tdir/${tfile}bis failed"
16783
16784         # stop MDT to stop GC-thread, should be done in back-ground as it will
16785         # block waiting for the thread to be released and exit
16786         declare -A stop_pids
16787         for i in $(seq $MDSCOUNT); do
16788                 stop mds$i &
16789                 stop_pids[mds$i]=$!
16790         done
16791
16792         for i in $(mdts_nodes); do
16793                 local facet
16794                 local nb=0
16795                 local facets=$(facets_up_on_host $i)
16796
16797                 for facet in ${facets//,/ }; do
16798                         if [[ $facet == mds* ]]; then
16799                                 nb=$((nb + 1))
16800                         fi
16801                 done
16802                 # ensure each MDS's gc threads are still present and all in "R"
16803                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16804                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16805                         error "$i: expected $nb GC-thread"
16806                 wait_update $i \
16807                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16808                         "R" 20 ||
16809                         error "$i: GC-thread not found in R-state"
16810                 # check umounts of each MDT on MDS have reached kthread_stop()
16811                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16812                         error "$i: expected $nb umount"
16813                 wait_update $i \
16814                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16815                         error "$i: umount not found in D-state"
16816         done
16817
16818         # release all GC-threads
16819         do_nodes $mdts $LCTL set_param fail_loc=0
16820
16821         # wait for MDT stop to complete
16822         for i in $(seq $MDSCOUNT); do
16823                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16824         done
16825
16826         # XXX
16827         # may try to check if any orphan changelog records are present
16828         # via ldiskfs/zfs and llog_reader...
16829
16830         # re-start/mount MDTs
16831         for i in $(seq $MDSCOUNT); do
16832                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16833                         error "Fail to start mds$i"
16834         done
16835
16836         local first_rec
16837         for i in $(seq $MDSCOUNT); do
16838                 # check cl_user1 still registered
16839                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16840                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16841                 # check cl_user2 unregistered
16842                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16843                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16844
16845                 # check changelogs are present and starting at $user_rec1 + 1
16846                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16847                 [ -n "$user_rec1" ] ||
16848                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16849                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16850                             awk '{ print $1; exit; }')
16851
16852                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16853                 [ $((user_rec1 + 1)) == $first_rec ] ||
16854                         error "mds$i: first index should be $user_rec1 + 1, " \
16855                               "but is $first_rec"
16856         done
16857 }
16858 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16859               "during mount"
16860
16861 test_160i() {
16862
16863         local mdts=$(comma_list $(mdts_nodes))
16864
16865         changelog_register || error "first changelog_register failed"
16866
16867         # generate some changelog records to accumulate on each MDT
16868         # use all_char because created files should be evenly distributed
16869         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16870                 error "test_mkdir $tdir failed"
16871         for ((i = 0; i < MDSCOUNT; i++)); do
16872                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16873                         error "create $DIR/$tdir/d$i.1 failed"
16874         done
16875
16876         # check changelogs have been generated
16877         local nbcl=$(changelog_dump | wc -l)
16878         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16879
16880         # simulate race between register and unregister
16881         # XXX as fail_loc is set per-MDS, with DNE configs the race
16882         # simulation will only occur for one MDT per MDS and for the
16883         # others the normal race scenario will take place
16884         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16885         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16886         do_nodes $mdts $LCTL set_param fail_val=1
16887
16888         # unregister 1st user
16889         changelog_deregister &
16890         local pid1=$!
16891         # wait some time for deregister work to reach race rdv
16892         sleep 2
16893         # register 2nd user
16894         changelog_register || error "2nd user register failed"
16895
16896         wait $pid1 || error "1st user deregister failed"
16897
16898         local i
16899         local last_rec
16900         declare -A LAST_REC
16901         for i in $(seq $MDSCOUNT); do
16902                 if changelog_users mds$i | grep "^cl"; then
16903                         # make sure new records are added with one user present
16904                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16905                                           awk '/^current.index:/ { print $NF }')
16906                 else
16907                         error "mds$i has no user registered"
16908                 fi
16909         done
16910
16911         # generate more changelog records to accumulate on each MDT
16912         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16913                 error "create $DIR/$tdir/${tfile}bis failed"
16914
16915         for i in $(seq $MDSCOUNT); do
16916                 last_rec=$(changelog_users $SINGLEMDS |
16917                            awk '/^current.index:/ { print $NF }')
16918                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16919                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16920                         error "changelogs are off on mds$i"
16921         done
16922 }
16923 run_test 160i "changelog user register/unregister race"
16924
16925 test_160j() {
16926         remote_mds_nodsh && skip "remote MDS with nodsh"
16927         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16928                 skip "Need MDS version at least 2.12.56"
16929
16930         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16931         stack_trap "umount $MOUNT2" EXIT
16932
16933         changelog_register || error "first changelog_register failed"
16934         stack_trap "changelog_deregister" EXIT
16935
16936         # generate some changelog
16937         # use all_char because created files should be evenly distributed
16938         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16939                 error "mkdir $tdir failed"
16940         for ((i = 0; i < MDSCOUNT; i++)); do
16941                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16942                         error "create $DIR/$tdir/d$i.1 failed"
16943         done
16944
16945         # open the changelog device
16946         exec 3>/dev/changelog-$FSNAME-MDT0000
16947         stack_trap "exec 3>&-" EXIT
16948         exec 4</dev/changelog-$FSNAME-MDT0000
16949         stack_trap "exec 4<&-" EXIT
16950
16951         # umount the first lustre mount
16952         umount $MOUNT
16953         stack_trap "mount_client $MOUNT" EXIT
16954
16955         # read changelog, which may or may not fail, but should not crash
16956         cat <&4 >/dev/null
16957
16958         # clear changelog
16959         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16960         changelog_users $SINGLEMDS | grep -q $cl_user ||
16961                 error "User $cl_user not found in changelog_users"
16962
16963         printf 'clear:'$cl_user':0' >&3
16964 }
16965 run_test 160j "client can be umounted while its chanangelog is being used"
16966
16967 test_160k() {
16968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16969         remote_mds_nodsh && skip "remote MDS with nodsh"
16970
16971         mkdir -p $DIR/$tdir/1/1
16972
16973         changelog_register || error "changelog_register failed"
16974         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16975
16976         changelog_users $SINGLEMDS | grep -q $cl_user ||
16977                 error "User '$cl_user' not found in changelog_users"
16978 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16979         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16980         rmdir $DIR/$tdir/1/1 & sleep 1
16981         mkdir $DIR/$tdir/2
16982         touch $DIR/$tdir/2/2
16983         rm -rf $DIR/$tdir/2
16984
16985         wait
16986         sleep 4
16987
16988         changelog_dump | grep rmdir || error "rmdir not recorded"
16989 }
16990 run_test 160k "Verify that changelog records are not lost"
16991
16992 # Verifies that a file passed as a parameter has recently had an operation
16993 # performed on it that has generated an MTIME changelog which contains the
16994 # correct parent FID. As files might reside on a different MDT from the
16995 # parent directory in DNE configurations, the FIDs are translated to paths
16996 # before being compared, which should be identical
16997 compare_mtime_changelog() {
16998         local file="${1}"
16999         local mdtidx
17000         local mtime
17001         local cl_fid
17002         local pdir
17003         local dir
17004
17005         mdtidx=$($LFS getstripe --mdt-index $file)
17006         mdtidx=$(printf "%04x" $mdtidx)
17007
17008         # Obtain the parent FID from the MTIME changelog
17009         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17010         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17011
17012         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17013         [ -z "$cl_fid" ] && error "parent FID not present"
17014
17015         # Verify that the path for the parent FID is the same as the path for
17016         # the test directory
17017         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17018
17019         dir=$(dirname $1)
17020
17021         [[ "${pdir%/}" == "$dir" ]] ||
17022                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17023 }
17024
17025 test_160l() {
17026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17027
17028         remote_mds_nodsh && skip "remote MDS with nodsh"
17029         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17030                 skip "Need MDS version at least 2.13.55"
17031
17032         local cl_user
17033
17034         changelog_register || error "changelog_register failed"
17035         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17036
17037         changelog_users $SINGLEMDS | grep -q $cl_user ||
17038                 error "User '$cl_user' not found in changelog_users"
17039
17040         # Clear some types so that MTIME changelogs are generated
17041         changelog_chmask "-CREAT"
17042         changelog_chmask "-CLOSE"
17043
17044         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17045
17046         # Test CL_MTIME during setattr
17047         touch $DIR/$tdir/$tfile
17048         compare_mtime_changelog $DIR/$tdir/$tfile
17049
17050         # Test CL_MTIME during close
17051         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17052         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17053 }
17054 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17055
17056 test_160m() {
17057         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17058         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17059                 skip "Need MDS version at least 2.14.51"
17060         local cl_users
17061         local cl_user1
17062         local cl_user2
17063         local pid1
17064
17065         # Create a user
17066         changelog_register || error "first changelog_register failed"
17067         changelog_register || error "second changelog_register failed"
17068
17069         cl_users=(${CL_USERS[mds1]})
17070         cl_user1="${cl_users[0]}"
17071         cl_user2="${cl_users[1]}"
17072         # generate some changelog records to accumulate on MDT0
17073         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17074         createmany -m $DIR/$tdir/$tfile 50 ||
17075                 error "create $DIR/$tdir/$tfile failed"
17076         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17077         rm -f $DIR/$tdir
17078
17079         # check changelogs have been generated
17080         local nbcl=$(changelog_dump | wc -l)
17081         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17082
17083 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17084         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17085
17086         __changelog_clear mds1 $cl_user1 +10
17087         __changelog_clear mds1 $cl_user2 0 &
17088         pid1=$!
17089         sleep 2
17090         __changelog_clear mds1 $cl_user1 0 ||
17091                 error "fail to cancel record for $cl_user1"
17092         wait $pid1
17093         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17094 }
17095 run_test 160m "Changelog clear race"
17096
17097 test_160n() {
17098         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17099         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17100                 skip "Need MDS version at least 2.14.51"
17101         local cl_users
17102         local cl_user1
17103         local cl_user2
17104         local pid1
17105         local first_rec
17106         local last_rec=0
17107
17108         # Create a user
17109         changelog_register || error "first changelog_register failed"
17110
17111         cl_users=(${CL_USERS[mds1]})
17112         cl_user1="${cl_users[0]}"
17113
17114         # generate some changelog records to accumulate on MDT0
17115         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17116         first_rec=$(changelog_users $SINGLEMDS |
17117                         awk '/^current.index:/ { print $NF }')
17118         while (( last_rec < (( first_rec + 65000)) )); do
17119                 createmany -m $DIR/$tdir/$tfile 10000 ||
17120                         error "create $DIR/$tdir/$tfile failed"
17121
17122                 for i in $(seq 0 10000); do
17123                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17124                                 > /dev/null
17125                 done
17126
17127                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17128                         error "unlinkmany failed unlink"
17129                 last_rec=$(changelog_users $SINGLEMDS |
17130                         awk '/^current.index:/ { print $NF }')
17131                 echo last record $last_rec
17132                 (( last_rec == 0 )) && error "no changelog found"
17133         done
17134
17135 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17136         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17137
17138         __changelog_clear mds1 $cl_user1 0 &
17139         pid1=$!
17140         sleep 2
17141         __changelog_clear mds1 $cl_user1 0 ||
17142                 error "fail to cancel record for $cl_user1"
17143         wait $pid1
17144         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17145 }
17146 run_test 160n "Changelog destroy race"
17147
17148 test_160o() {
17149         local mdt="$(facet_svc $SINGLEMDS)"
17150
17151         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17152         remote_mds_nodsh && skip "remote MDS with nodsh"
17153         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17154                 skip "Need MDS version at least 2.14.52"
17155
17156         changelog_register --user test_160o -m unlnk+close+open ||
17157                 error "changelog_register failed"
17158
17159         do_facet $SINGLEMDS $LCTL --device $mdt \
17160                                 changelog_register -u "Tt3_-#" &&
17161                 error "bad symbols in name should fail"
17162
17163         do_facet $SINGLEMDS $LCTL --device $mdt \
17164                                 changelog_register -u test_160o &&
17165                 error "the same name registration should fail"
17166
17167         do_facet $SINGLEMDS $LCTL --device $mdt \
17168                         changelog_register -u test_160toolongname &&
17169                 error "too long name registration should fail"
17170
17171         changelog_chmask "MARK+HSM"
17172         lctl get_param mdd.*.changelog*mask
17173         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17174         changelog_users $SINGLEMDS | grep -q $cl_user ||
17175                 error "User $cl_user not found in changelog_users"
17176         #verify username
17177         echo $cl_user | grep -q test_160o ||
17178                 error "User $cl_user has no specific name 'test160o'"
17179
17180         # change something
17181         changelog_clear 0 || error "changelog_clear failed"
17182         # generate some changelog records to accumulate on MDT0
17183         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17184         touch $DIR/$tdir/$tfile                 # open 1
17185
17186         OPENS=$(changelog_dump | grep -c "OPEN")
17187         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17188
17189         # must be no MKDIR it wasn't set as user mask
17190         MKDIR=$(changelog_dump | grep -c "MKDIR")
17191         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17192
17193         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17194                                 mdd.$mdt.changelog_current_mask -n)
17195         # register maskless user
17196         changelog_register || error "changelog_register failed"
17197         # effective mask should be not changed because it is not minimal
17198         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17199                                 mdd.$mdt.changelog_current_mask -n)
17200         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17201         # set server mask to minimal value
17202         changelog_chmask "MARK"
17203         # check effective mask again, should be treated as DEFMASK now
17204         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17205                                 mdd.$mdt.changelog_current_mask -n)
17206         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17207
17208         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17209                 # set server mask back to some value
17210                 changelog_chmask "CLOSE,UNLNK"
17211                 # check effective mask again, should not remain as DEFMASK
17212                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17213                                 mdd.$mdt.changelog_current_mask -n)
17214                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17215         fi
17216
17217         do_facet $SINGLEMDS $LCTL --device $mdt \
17218                                 changelog_deregister -u test_160o ||
17219                 error "cannot deregister by name"
17220 }
17221 run_test 160o "changelog user name and mask"
17222
17223 test_160p() {
17224         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17225         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17226                 skip "Need MDS version at least 2.14.51"
17227         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17228         local cl_users
17229         local cl_user1
17230         local entry_count
17231
17232         # Create a user
17233         changelog_register || error "first changelog_register failed"
17234
17235         cl_users=(${CL_USERS[mds1]})
17236         cl_user1="${cl_users[0]}"
17237
17238         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17239         createmany -m $DIR/$tdir/$tfile 50 ||
17240                 error "create $DIR/$tdir/$tfile failed"
17241         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17242         rm -rf $DIR/$tdir
17243
17244         # check changelogs have been generated
17245         entry_count=$(changelog_dump | wc -l)
17246         ((entry_count != 0)) || error "no changelog entries found"
17247
17248         # remove changelog_users and check that orphan entries are removed
17249         stop mds1
17250         local dev=$(mdsdevname 1)
17251         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17252         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17253         entry_count=$(changelog_dump | wc -l)
17254         ((entry_count == 0)) ||
17255                 error "found $entry_count changelog entries, expected none"
17256 }
17257 run_test 160p "Changelog orphan cleanup with no users"
17258
17259 test_160q() {
17260         local mdt="$(facet_svc $SINGLEMDS)"
17261         local clu
17262
17263         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17264         remote_mds_nodsh && skip "remote MDS with nodsh"
17265         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17266                 skip "Need MDS version at least 2.14.54"
17267
17268         # set server mask to minimal value like server init does
17269         changelog_chmask "MARK"
17270         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17271                 error "changelog_register failed"
17272         # check effective mask again, should be treated as DEFMASK now
17273         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17274                                 mdd.$mdt.changelog_current_mask -n)
17275         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17276                 error "changelog_deregister failed"
17277         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17278 }
17279 run_test 160q "changelog effective mask is DEFMASK if not set"
17280
17281 test_160s() {
17282         remote_mds_nodsh && skip "remote MDS with nodsh"
17283         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17284                 skip "Need MDS version at least 2.14.55"
17285
17286         local mdts=$(comma_list $(mdts_nodes))
17287
17288         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17289         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17290                                        fail_val=$((24 * 3600 * 10))
17291
17292         # Create a user which is 10 days old
17293         changelog_register || error "first changelog_register failed"
17294         local cl_users
17295         declare -A cl_user1
17296         local i
17297
17298         # generate some changelog records to accumulate on each MDT
17299         # use all_char because created files should be evenly distributed
17300         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17301                 error "test_mkdir $tdir failed"
17302         for ((i = 0; i < MDSCOUNT; i++)); do
17303                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17304                         error "create $DIR/$tdir/d$i.1 failed"
17305         done
17306
17307         # check changelogs have been generated
17308         local nbcl=$(changelog_dump | wc -l)
17309         (( nbcl > 0 )) || error "no changelogs found"
17310
17311         # reduce the max_idle_indexes value to make sure we exceed it
17312         for param in "changelog_max_idle_indexes=2097446912" \
17313                      "changelog_max_idle_time=2592000" \
17314                      "changelog_gc=1" \
17315                      "changelog_min_gc_interval=2"; do
17316                 local MDT0=$(facet_svc $SINGLEMDS)
17317                 local var="${param%=*}"
17318                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17319
17320                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17321                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17322                         error "unable to set mdd.*.$param"
17323         done
17324
17325         local start=$SECONDS
17326         for i in $(seq $MDSCOUNT); do
17327                 cl_users=(${CL_USERS[mds$i]})
17328                 cl_user1[mds$i]="${cl_users[0]}"
17329
17330                 [[ -n "${cl_user1[mds$i]}" ]] ||
17331                         error "mds$i: no user registered"
17332         done
17333
17334         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17335         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17336
17337         # ensure we are past the previous changelog_min_gc_interval set above
17338         local sleep2=$((start + 2 - SECONDS))
17339         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17340
17341         # Generate one more changelog to trigger GC
17342         for ((i = 0; i < MDSCOUNT; i++)); do
17343                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17344                         error "create $DIR/$tdir/d$i.3 failed"
17345         done
17346
17347         # ensure gc thread is done
17348         for node in $(mdts_nodes); do
17349                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17350                         error "$node: GC-thread not done"
17351         done
17352
17353         do_nodes $mdts $LCTL set_param fail_loc=0
17354
17355         for (( i = 1; i <= MDSCOUNT; i++ )); do
17356                 # check cl_user1 is purged
17357                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17358                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17359         done
17360         return 0
17361 }
17362 run_test 160s "changelog garbage collect on idle records * time"
17363
17364 test_160t() {
17365         remote_mds_nodsh && skip "remote MDS with nodsh"
17366         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17367                 skip "Need MDS version at least 2.15.50"
17368
17369         local MDT0=$(facet_svc $SINGLEMDS)
17370         local cl_users
17371         local cl_user1
17372         local cl_user2
17373         local start
17374
17375         changelog_register --user user1 -m all ||
17376                 error "user1 failed to register"
17377
17378         mkdir_on_mdt0 $DIR/$tdir
17379         # create default overstripe to maximize changelog size
17380         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17381         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17382         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17383
17384         # user2 consumes less records so less space
17385         changelog_register --user user2 || error "user2 failed to register"
17386         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17387         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17388
17389         # check changelogs have been generated
17390         local nbcl=$(changelog_dump | wc -l)
17391         (( nbcl > 0 )) || error "no changelogs found"
17392
17393         # reduce the changelog_min_gc_interval to force check
17394         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17395                 local var="${param%=*}"
17396                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17397
17398                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17399                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17400                         error "unable to set mdd.*.$param"
17401         done
17402
17403         start=$SECONDS
17404         cl_users=(${CL_USERS[mds1]})
17405         cl_user1="${cl_users[0]}"
17406         cl_user2="${cl_users[1]}"
17407
17408         [[ -n $cl_user1 ]] ||
17409                 error "mds1: user #1 isn't registered"
17410         [[ -n $cl_user2 ]] ||
17411                 error "mds1: user #2 isn't registered"
17412
17413         # ensure we are past the previous changelog_min_gc_interval set above
17414         local sleep2=$((start + 2 - SECONDS))
17415         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17416
17417         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17418         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17419                         fail_val=$(((llog_size1 + llog_size2) / 2))
17420
17421         # Generate more changelog to trigger GC
17422         createmany -o $DIR/$tdir/u3_ 4 ||
17423                 error "create failed for more files"
17424
17425         # ensure gc thread is done
17426         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17427                 error "mds1: GC-thread not done"
17428
17429         do_facet mds1 $LCTL set_param fail_loc=0
17430
17431         # check cl_user1 is purged
17432         changelog_users mds1 | grep -q "$cl_user1" &&
17433                 error "User $cl_user1 is registered"
17434         # check cl_user2 is not purged
17435         changelog_users mds1 | grep -q "$cl_user2" ||
17436                 error "User $cl_user2 is not registered"
17437 }
17438 run_test 160t "changelog garbage collect on lack of space"
17439
17440 test_161a() {
17441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17442
17443         test_mkdir -c1 $DIR/$tdir
17444         cp /etc/hosts $DIR/$tdir/$tfile
17445         test_mkdir -c1 $DIR/$tdir/foo1
17446         test_mkdir -c1 $DIR/$tdir/foo2
17447         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17448         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17449         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17450         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17451         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17452         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17453                 $LFS fid2path $DIR $FID
17454                 error "bad link ea"
17455         fi
17456         # middle
17457         rm $DIR/$tdir/foo2/zachary
17458         # last
17459         rm $DIR/$tdir/foo2/thor
17460         # first
17461         rm $DIR/$tdir/$tfile
17462         # rename
17463         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17464         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17465                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17466         rm $DIR/$tdir/foo2/maggie
17467
17468         # overflow the EA
17469         local longname=$tfile.avg_len_is_thirty_two_
17470         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17471                 error_noexit 'failed to unlink many hardlinks'" EXIT
17472         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17473                 error "failed to hardlink many files"
17474         links=$($LFS fid2path $DIR $FID | wc -l)
17475         echo -n "${links}/1000 links in link EA"
17476         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17477 }
17478 run_test 161a "link ea sanity"
17479
17480 test_161b() {
17481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17482         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17483
17484         local MDTIDX=1
17485         local remote_dir=$DIR/$tdir/remote_dir
17486
17487         mkdir -p $DIR/$tdir
17488         $LFS mkdir -i $MDTIDX $remote_dir ||
17489                 error "create remote directory failed"
17490
17491         cp /etc/hosts $remote_dir/$tfile
17492         mkdir -p $remote_dir/foo1
17493         mkdir -p $remote_dir/foo2
17494         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17495         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17496         ln $remote_dir/$tfile $remote_dir/foo1/luna
17497         ln $remote_dir/$tfile $remote_dir/foo2/thor
17498
17499         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17500                      tr -d ']')
17501         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17502                 $LFS fid2path $DIR $FID
17503                 error "bad link ea"
17504         fi
17505         # middle
17506         rm $remote_dir/foo2/zachary
17507         # last
17508         rm $remote_dir/foo2/thor
17509         # first
17510         rm $remote_dir/$tfile
17511         # rename
17512         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17513         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17514         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17515                 $LFS fid2path $DIR $FID
17516                 error "bad link rename"
17517         fi
17518         rm $remote_dir/foo2/maggie
17519
17520         # overflow the EA
17521         local longname=filename_avg_len_is_thirty_two_
17522         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17523                 error "failed to hardlink many files"
17524         links=$($LFS fid2path $DIR $FID | wc -l)
17525         echo -n "${links}/1000 links in link EA"
17526         [[ ${links} -gt 60 ]] ||
17527                 error "expected at least 60 links in link EA"
17528         unlinkmany $remote_dir/foo2/$longname 1000 ||
17529         error "failed to unlink many hardlinks"
17530 }
17531 run_test 161b "link ea sanity under remote directory"
17532
17533 test_161c() {
17534         remote_mds_nodsh && skip "remote MDS with nodsh"
17535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17536         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17537                 skip "Need MDS version at least 2.1.5"
17538
17539         # define CLF_RENAME_LAST 0x0001
17540         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17541         changelog_register || error "changelog_register failed"
17542
17543         rm -rf $DIR/$tdir
17544         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17545         touch $DIR/$tdir/foo_161c
17546         touch $DIR/$tdir/bar_161c
17547         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17548         changelog_dump | grep RENME | tail -n 5
17549         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17550         changelog_clear 0 || error "changelog_clear failed"
17551         if [ x$flags != "x0x1" ]; then
17552                 error "flag $flags is not 0x1"
17553         fi
17554
17555         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17556         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17557         touch $DIR/$tdir/foo_161c
17558         touch $DIR/$tdir/bar_161c
17559         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17560         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17561         changelog_dump | grep RENME | tail -n 5
17562         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17563         changelog_clear 0 || error "changelog_clear failed"
17564         if [ x$flags != "x0x0" ]; then
17565                 error "flag $flags is not 0x0"
17566         fi
17567         echo "rename overwrite a target having nlink > 1," \
17568                 "changelog record has flags of $flags"
17569
17570         # rename doesn't overwrite a target (changelog flag 0x0)
17571         touch $DIR/$tdir/foo_161c
17572         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17573         changelog_dump | grep RENME | tail -n 5
17574         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17575         changelog_clear 0 || error "changelog_clear failed"
17576         if [ x$flags != "x0x0" ]; then
17577                 error "flag $flags is not 0x0"
17578         fi
17579         echo "rename doesn't overwrite a target," \
17580                 "changelog record has flags of $flags"
17581
17582         # define CLF_UNLINK_LAST 0x0001
17583         # unlink a file having nlink = 1 (changelog flag 0x1)
17584         rm -f $DIR/$tdir/foo2_161c
17585         changelog_dump | grep UNLNK | tail -n 5
17586         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17587         changelog_clear 0 || error "changelog_clear failed"
17588         if [ x$flags != "x0x1" ]; then
17589                 error "flag $flags is not 0x1"
17590         fi
17591         echo "unlink a file having nlink = 1," \
17592                 "changelog record has flags of $flags"
17593
17594         # unlink a file having nlink > 1 (changelog flag 0x0)
17595         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17596         rm -f $DIR/$tdir/foobar_161c
17597         changelog_dump | grep UNLNK | tail -n 5
17598         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17599         changelog_clear 0 || error "changelog_clear failed"
17600         if [ x$flags != "x0x0" ]; then
17601                 error "flag $flags is not 0x0"
17602         fi
17603         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17604 }
17605 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17606
17607 test_161d() {
17608         remote_mds_nodsh && skip "remote MDS with nodsh"
17609         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17610
17611         local pid
17612         local fid
17613
17614         changelog_register || error "changelog_register failed"
17615
17616         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17617         # interfer with $MOUNT/.lustre/fid/ access
17618         mkdir $DIR/$tdir
17619         [[ $? -eq 0 ]] || error "mkdir failed"
17620
17621         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17622         $LCTL set_param fail_loc=0x8000140c
17623         # 5s pause
17624         $LCTL set_param fail_val=5
17625
17626         # create file
17627         echo foofoo > $DIR/$tdir/$tfile &
17628         pid=$!
17629
17630         # wait for create to be delayed
17631         sleep 2
17632
17633         ps -p $pid
17634         [[ $? -eq 0 ]] || error "create should be blocked"
17635
17636         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17637         stack_trap "rm -f $tempfile"
17638         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17639         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17640         # some delay may occur during ChangeLog publishing and file read just
17641         # above, that could allow file write to happen finally
17642         [[ -s $tempfile ]] && echo "file should be empty"
17643
17644         $LCTL set_param fail_loc=0
17645
17646         wait $pid
17647         [[ $? -eq 0 ]] || error "create failed"
17648 }
17649 run_test 161d "create with concurrent .lustre/fid access"
17650
17651 check_path() {
17652         local expected="$1"
17653         shift
17654         local fid="$2"
17655
17656         local path
17657         path=$($LFS fid2path "$@")
17658         local rc=$?
17659
17660         if [ $rc -ne 0 ]; then
17661                 error "path looked up of '$expected' failed: rc=$rc"
17662         elif [ "$path" != "$expected" ]; then
17663                 error "path looked up '$path' instead of '$expected'"
17664         else
17665                 echo "FID '$fid' resolves to path '$path' as expected"
17666         fi
17667 }
17668
17669 test_162a() { # was test_162
17670         test_mkdir -p -c1 $DIR/$tdir/d2
17671         touch $DIR/$tdir/d2/$tfile
17672         touch $DIR/$tdir/d2/x1
17673         touch $DIR/$tdir/d2/x2
17674         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17675         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17676         # regular file
17677         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17678         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17679
17680         # softlink
17681         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17682         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17683         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17684
17685         # softlink to wrong file
17686         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17687         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17688         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17689
17690         # hardlink
17691         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17692         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17693         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17694         # fid2path dir/fsname should both work
17695         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17696         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17697
17698         # hardlink count: check that there are 2 links
17699         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17700         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17701
17702         # hardlink indexing: remove the first link
17703         rm $DIR/$tdir/d2/p/q/r/hlink
17704         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17705 }
17706 run_test 162a "path lookup sanity"
17707
17708 test_162b() {
17709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17710         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17711
17712         mkdir $DIR/$tdir
17713         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17714                                 error "create striped dir failed"
17715
17716         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17717                                         tail -n 1 | awk '{print $2}')
17718         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17719
17720         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17721         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17722
17723         # regular file
17724         for ((i=0;i<5;i++)); do
17725                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17726                         error "get fid for f$i failed"
17727                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17728
17729                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17730                         error "get fid for d$i failed"
17731                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17732         done
17733
17734         return 0
17735 }
17736 run_test 162b "striped directory path lookup sanity"
17737
17738 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17739 test_162c() {
17740         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17741                 skip "Need MDS version at least 2.7.51"
17742
17743         local lpath=$tdir.local
17744         local rpath=$tdir.remote
17745
17746         test_mkdir $DIR/$lpath
17747         test_mkdir $DIR/$rpath
17748
17749         for ((i = 0; i <= 101; i++)); do
17750                 lpath="$lpath/$i"
17751                 mkdir $DIR/$lpath
17752                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17753                         error "get fid for local directory $DIR/$lpath failed"
17754                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17755
17756                 rpath="$rpath/$i"
17757                 test_mkdir $DIR/$rpath
17758                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17759                         error "get fid for remote directory $DIR/$rpath failed"
17760                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17761         done
17762
17763         return 0
17764 }
17765 run_test 162c "fid2path works with paths 100 or more directories deep"
17766
17767 oalr_event_count() {
17768         local event="${1}"
17769         local trace="${2}"
17770
17771         awk -v name="${FSNAME}-OST0000" \
17772             -v event="${event}" \
17773             '$1 == "TRACE" && $2 == event && $3 == name' \
17774             "${trace}" |
17775         wc -l
17776 }
17777
17778 oalr_expect_event_count() {
17779         local event="${1}"
17780         local trace="${2}"
17781         local expect="${3}"
17782         local count
17783
17784         count=$(oalr_event_count "${event}" "${trace}")
17785         if ((count == expect)); then
17786                 return 0
17787         fi
17788
17789         error_noexit "${event} event count was '${count}', expected ${expect}"
17790         cat "${trace}" >&2
17791         exit 1
17792 }
17793
17794 cleanup_165() {
17795         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17796         stop ost1
17797         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17798 }
17799
17800 setup_165() {
17801         sync # Flush previous IOs so we can count log entries.
17802         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17803         stack_trap cleanup_165 EXIT
17804 }
17805
17806 test_165a() {
17807         local trace="/tmp/${tfile}.trace"
17808         local rc
17809         local count
17810
17811         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17812                 skip "OFD access log unsupported"
17813
17814         setup_165
17815         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17816         sleep 5
17817
17818         do_facet ost1 ofd_access_log_reader --list
17819         stop ost1
17820
17821         do_facet ost1 killall -TERM ofd_access_log_reader
17822         wait
17823         rc=$?
17824
17825         if ((rc != 0)); then
17826                 error "ofd_access_log_reader exited with rc = '${rc}'"
17827         fi
17828
17829         # Parse trace file for discovery events:
17830         oalr_expect_event_count alr_log_add "${trace}" 1
17831         oalr_expect_event_count alr_log_eof "${trace}" 1
17832         oalr_expect_event_count alr_log_free "${trace}" 1
17833 }
17834 run_test 165a "ofd access log discovery"
17835
17836 test_165b() {
17837         local trace="/tmp/${tfile}.trace"
17838         local file="${DIR}/${tfile}"
17839         local pfid1
17840         local pfid2
17841         local -a entry
17842         local rc
17843         local count
17844         local size
17845         local flags
17846
17847         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17848                 skip "OFD access log unsupported"
17849
17850         setup_165
17851         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17852         sleep 5
17853
17854         do_facet ost1 ofd_access_log_reader --list
17855
17856         lfs setstripe -c 1 -i 0 "${file}"
17857         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17858                 error "cannot create '${file}'"
17859
17860         sleep 5
17861         do_facet ost1 killall -TERM ofd_access_log_reader
17862         wait
17863         rc=$?
17864
17865         if ((rc != 0)); then
17866                 error "ofd_access_log_reader exited with rc = '${rc}'"
17867         fi
17868
17869         oalr_expect_event_count alr_log_entry "${trace}" 1
17870
17871         pfid1=$($LFS path2fid "${file}")
17872
17873         # 1     2             3   4    5     6   7    8    9     10
17874         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17875         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17876
17877         echo "entry = '${entry[*]}'" >&2
17878
17879         pfid2=${entry[4]}
17880         if [[ "${pfid1}" != "${pfid2}" ]]; then
17881                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17882         fi
17883
17884         size=${entry[8]}
17885         if ((size != 1048576)); then
17886                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17887         fi
17888
17889         flags=${entry[10]}
17890         if [[ "${flags}" != "w" ]]; then
17891                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17892         fi
17893
17894         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17895         sleep 5
17896
17897         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17898                 error "cannot read '${file}'"
17899         sleep 5
17900
17901         do_facet ost1 killall -TERM ofd_access_log_reader
17902         wait
17903         rc=$?
17904
17905         if ((rc != 0)); then
17906                 error "ofd_access_log_reader exited with rc = '${rc}'"
17907         fi
17908
17909         oalr_expect_event_count alr_log_entry "${trace}" 1
17910
17911         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17912         echo "entry = '${entry[*]}'" >&2
17913
17914         pfid2=${entry[4]}
17915         if [[ "${pfid1}" != "${pfid2}" ]]; then
17916                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17917         fi
17918
17919         size=${entry[8]}
17920         if ((size != 524288)); then
17921                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17922         fi
17923
17924         flags=${entry[10]}
17925         if [[ "${flags}" != "r" ]]; then
17926                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17927         fi
17928 }
17929 run_test 165b "ofd access log entries are produced and consumed"
17930
17931 test_165c() {
17932         local trace="/tmp/${tfile}.trace"
17933         local file="${DIR}/${tdir}/${tfile}"
17934
17935         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17936                 skip "OFD access log unsupported"
17937
17938         test_mkdir "${DIR}/${tdir}"
17939
17940         setup_165
17941         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17942         sleep 5
17943
17944         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17945
17946         # 4096 / 64 = 64. Create twice as many entries.
17947         for ((i = 0; i < 128; i++)); do
17948                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17949                         error "cannot create file"
17950         done
17951
17952         sync
17953
17954         do_facet ost1 killall -TERM ofd_access_log_reader
17955         wait
17956         rc=$?
17957         if ((rc != 0)); then
17958                 error "ofd_access_log_reader exited with rc = '${rc}'"
17959         fi
17960
17961         unlinkmany  "${file}-%d" 128
17962 }
17963 run_test 165c "full ofd access logs do not block IOs"
17964
17965 oal_get_read_count() {
17966         local stats="$1"
17967
17968         # STATS lustre-OST0001 alr_read_count 1
17969
17970         do_facet ost1 cat "${stats}" |
17971         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17972              END { print count; }'
17973 }
17974
17975 oal_expect_read_count() {
17976         local stats="$1"
17977         local count
17978         local expect="$2"
17979
17980         # Ask ofd_access_log_reader to write stats.
17981         do_facet ost1 killall -USR1 ofd_access_log_reader
17982
17983         # Allow some time for things to happen.
17984         sleep 1
17985
17986         count=$(oal_get_read_count "${stats}")
17987         if ((count == expect)); then
17988                 return 0
17989         fi
17990
17991         error_noexit "bad read count, got ${count}, expected ${expect}"
17992         do_facet ost1 cat "${stats}" >&2
17993         exit 1
17994 }
17995
17996 test_165d() {
17997         local stats="/tmp/${tfile}.stats"
17998         local file="${DIR}/${tdir}/${tfile}"
17999         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18000
18001         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18002                 skip "OFD access log unsupported"
18003
18004         test_mkdir "${DIR}/${tdir}"
18005
18006         setup_165
18007         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18008         sleep 5
18009
18010         lfs setstripe -c 1 -i 0 "${file}"
18011
18012         do_facet ost1 lctl set_param "${param}=rw"
18013         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18014                 error "cannot create '${file}'"
18015         oal_expect_read_count "${stats}" 1
18016
18017         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18018                 error "cannot read '${file}'"
18019         oal_expect_read_count "${stats}" 2
18020
18021         do_facet ost1 lctl set_param "${param}=r"
18022         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18023                 error "cannot create '${file}'"
18024         oal_expect_read_count "${stats}" 2
18025
18026         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18027                 error "cannot read '${file}'"
18028         oal_expect_read_count "${stats}" 3
18029
18030         do_facet ost1 lctl set_param "${param}=w"
18031         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18032                 error "cannot create '${file}'"
18033         oal_expect_read_count "${stats}" 4
18034
18035         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18036                 error "cannot read '${file}'"
18037         oal_expect_read_count "${stats}" 4
18038
18039         do_facet ost1 lctl set_param "${param}=0"
18040         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18041                 error "cannot create '${file}'"
18042         oal_expect_read_count "${stats}" 4
18043
18044         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18045                 error "cannot read '${file}'"
18046         oal_expect_read_count "${stats}" 4
18047
18048         do_facet ost1 killall -TERM ofd_access_log_reader
18049         wait
18050         rc=$?
18051         if ((rc != 0)); then
18052                 error "ofd_access_log_reader exited with rc = '${rc}'"
18053         fi
18054 }
18055 run_test 165d "ofd_access_log mask works"
18056
18057 test_165e() {
18058         local stats="/tmp/${tfile}.stats"
18059         local file0="${DIR}/${tdir}-0/${tfile}"
18060         local file1="${DIR}/${tdir}-1/${tfile}"
18061
18062         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18063                 skip "OFD access log unsupported"
18064
18065         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18066
18067         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18068         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18069
18070         lfs setstripe -c 1 -i 0 "${file0}"
18071         lfs setstripe -c 1 -i 0 "${file1}"
18072
18073         setup_165
18074         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18075         sleep 5
18076
18077         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18078                 error "cannot create '${file0}'"
18079         sync
18080         oal_expect_read_count "${stats}" 0
18081
18082         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18083                 error "cannot create '${file1}'"
18084         sync
18085         oal_expect_read_count "${stats}" 1
18086
18087         do_facet ost1 killall -TERM ofd_access_log_reader
18088         wait
18089         rc=$?
18090         if ((rc != 0)); then
18091                 error "ofd_access_log_reader exited with rc = '${rc}'"
18092         fi
18093 }
18094 run_test 165e "ofd_access_log MDT index filter works"
18095
18096 test_165f() {
18097         local trace="/tmp/${tfile}.trace"
18098         local rc
18099         local count
18100
18101         setup_165
18102         do_facet ost1 timeout 60 ofd_access_log_reader \
18103                 --exit-on-close --debug=- --trace=- > "${trace}" &
18104         sleep 5
18105         stop ost1
18106
18107         wait
18108         rc=$?
18109
18110         if ((rc != 0)); then
18111                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18112                 cat "${trace}"
18113                 exit 1
18114         fi
18115 }
18116 run_test 165f "ofd_access_log_reader --exit-on-close works"
18117
18118 test_169() {
18119         # do directio so as not to populate the page cache
18120         log "creating a 10 Mb file"
18121         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18122                 error "multiop failed while creating a file"
18123         log "starting reads"
18124         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18125         log "truncating the file"
18126         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18127                 error "multiop failed while truncating the file"
18128         log "killing dd"
18129         kill %+ || true # reads might have finished
18130         echo "wait until dd is finished"
18131         wait
18132         log "removing the temporary file"
18133         rm -rf $DIR/$tfile || error "tmp file removal failed"
18134 }
18135 run_test 169 "parallel read and truncate should not deadlock"
18136
18137 test_170() {
18138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18139
18140         $LCTL clear     # bug 18514
18141         $LCTL debug_daemon start $TMP/${tfile}_log_good
18142         touch $DIR/$tfile
18143         $LCTL debug_daemon stop
18144         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18145                 error "sed failed to read log_good"
18146
18147         $LCTL debug_daemon start $TMP/${tfile}_log_good
18148         rm -rf $DIR/$tfile
18149         $LCTL debug_daemon stop
18150
18151         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18152                error "lctl df log_bad failed"
18153
18154         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18155         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18156
18157         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18158         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18159
18160         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18161                 error "bad_line good_line1 good_line2 are empty"
18162
18163         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18164         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18165         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18166
18167         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18168         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18169         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18170
18171         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18172                 error "bad_line_new good_line_new are empty"
18173
18174         local expected_good=$((good_line1 + good_line2*2))
18175
18176         rm -f $TMP/${tfile}*
18177         # LU-231, short malformed line may not be counted into bad lines
18178         if [ $bad_line -ne $bad_line_new ] &&
18179                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18180                 error "expected $bad_line bad lines, but got $bad_line_new"
18181                 return 1
18182         fi
18183
18184         if [ $expected_good -ne $good_line_new ]; then
18185                 error "expected $expected_good good lines, but got $good_line_new"
18186                 return 2
18187         fi
18188         true
18189 }
18190 run_test 170 "test lctl df to handle corrupted log ====================="
18191
18192 test_171() { # bug20592
18193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18194
18195         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18196         $LCTL set_param fail_loc=0x50e
18197         $LCTL set_param fail_val=3000
18198         multiop_bg_pause $DIR/$tfile O_s || true
18199         local MULTIPID=$!
18200         kill -USR1 $MULTIPID
18201         # cause log dump
18202         sleep 3
18203         wait $MULTIPID
18204         if dmesg | grep "recursive fault"; then
18205                 error "caught a recursive fault"
18206         fi
18207         $LCTL set_param fail_loc=0
18208         true
18209 }
18210 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18211
18212 test_172() {
18213
18214         #define OBD_FAIL_OBD_CLEANUP  0x60e
18215         $LCTL set_param fail_loc=0x60e
18216         umount $MOUNT || error "umount $MOUNT failed"
18217         stack_trap "mount_client $MOUNT"
18218
18219         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18220                 error "no client OBDs are remained"
18221
18222         $LCTL dl | while read devno state type name foo; do
18223                 case $type in
18224                 lov|osc|lmv|mdc)
18225                         $LCTL --device $name cleanup
18226                         $LCTL --device $name detach
18227                         ;;
18228                 *)
18229                         # skip server devices
18230                         ;;
18231                 esac
18232         done
18233
18234         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18235                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18236                 error "some client OBDs are still remained"
18237         fi
18238
18239 }
18240 run_test 172 "manual device removal with lctl cleanup/detach ======"
18241
18242 # it would be good to share it with obdfilter-survey/iokit-libecho code
18243 setup_obdecho_osc () {
18244         local rc=0
18245         local ost_nid=$1
18246         local obdfilter_name=$2
18247         echo "Creating new osc for $obdfilter_name on $ost_nid"
18248         # make sure we can find loopback nid
18249         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18250
18251         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18252                            ${obdfilter_name}_osc_UUID || rc=2; }
18253         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18254                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18255         return $rc
18256 }
18257
18258 cleanup_obdecho_osc () {
18259         local obdfilter_name=$1
18260         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18261         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18262         return 0
18263 }
18264
18265 obdecho_test() {
18266         local OBD=$1
18267         local node=$2
18268         local pages=${3:-64}
18269         local rc=0
18270         local id
18271
18272         local count=10
18273         local obd_size=$(get_obd_size $node $OBD)
18274         local page_size=$(get_page_size $node)
18275         if [[ -n "$obd_size" ]]; then
18276                 local new_count=$((obd_size / (pages * page_size / 1024)))
18277                 [[ $new_count -ge $count ]] || count=$new_count
18278         fi
18279
18280         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18281         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18282                            rc=2; }
18283         if [ $rc -eq 0 ]; then
18284             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18285             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18286         fi
18287         echo "New object id is $id"
18288         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18289                            rc=4; }
18290         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18291                            "test_brw $count w v $pages $id" || rc=4; }
18292         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18293                            rc=4; }
18294         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18295                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18296         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18297                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18298         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18299         return $rc
18300 }
18301
18302 test_180a() {
18303         skip "obdecho on osc is no longer supported"
18304 }
18305 run_test 180a "test obdecho on osc"
18306
18307 test_180b() {
18308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18309         remote_ost_nodsh && skip "remote OST with nodsh"
18310
18311         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18312                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18313                 error "failed to load module obdecho"
18314
18315         local target=$(do_facet ost1 $LCTL dl |
18316                        awk '/obdfilter/ { print $4; exit; }')
18317
18318         if [ -n "$target" ]; then
18319                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18320         else
18321                 do_facet ost1 $LCTL dl
18322                 error "there is no obdfilter target on ost1"
18323         fi
18324 }
18325 run_test 180b "test obdecho directly on obdfilter"
18326
18327 test_180c() { # LU-2598
18328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18329         remote_ost_nodsh && skip "remote OST with nodsh"
18330         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18331                 skip "Need MDS version at least 2.4.0"
18332
18333         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18334                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18335                 error "failed to load module obdecho"
18336
18337         local target=$(do_facet ost1 $LCTL dl |
18338                        awk '/obdfilter/ { print $4; exit; }')
18339
18340         if [ -n "$target" ]; then
18341                 local pages=16384 # 64MB bulk I/O RPC size
18342
18343                 obdecho_test "$target" ost1 "$pages" ||
18344                         error "obdecho_test with pages=$pages failed with $?"
18345         else
18346                 do_facet ost1 $LCTL dl
18347                 error "there is no obdfilter target on ost1"
18348         fi
18349 }
18350 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18351
18352 test_181() { # bug 22177
18353         test_mkdir $DIR/$tdir
18354         # create enough files to index the directory
18355         createmany -o $DIR/$tdir/foobar 4000
18356         # print attributes for debug purpose
18357         lsattr -d .
18358         # open dir
18359         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18360         MULTIPID=$!
18361         # remove the files & current working dir
18362         unlinkmany $DIR/$tdir/foobar 4000
18363         rmdir $DIR/$tdir
18364         kill -USR1 $MULTIPID
18365         wait $MULTIPID
18366         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18367         return 0
18368 }
18369 run_test 181 "Test open-unlinked dir ========================"
18370
18371 test_182a() {
18372         local fcount=1000
18373         local tcount=10
18374
18375         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18376
18377         $LCTL set_param mdc.*.rpc_stats=clear
18378
18379         for (( i = 0; i < $tcount; i++ )) ; do
18380                 mkdir $DIR/$tdir/$i
18381         done
18382
18383         for (( i = 0; i < $tcount; i++ )) ; do
18384                 createmany -o $DIR/$tdir/$i/f- $fcount &
18385         done
18386         wait
18387
18388         for (( i = 0; i < $tcount; i++ )) ; do
18389                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18390         done
18391         wait
18392
18393         $LCTL get_param mdc.*.rpc_stats
18394
18395         rm -rf $DIR/$tdir
18396 }
18397 run_test 182a "Test parallel modify metadata operations from mdc"
18398
18399 test_182b() {
18400         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18401         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18402         local dcount=1000
18403         local tcount=10
18404         local stime
18405         local etime
18406         local delta
18407
18408         do_facet mds1 $LCTL list_param \
18409                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18410                 skip "MDS lacks parallel RPC handling"
18411
18412         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18413
18414         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18415                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18416
18417         stime=$(date +%s)
18418         createmany -i 0 -d $DIR/$tdir/t- $tcount
18419
18420         for (( i = 0; i < $tcount; i++ )) ; do
18421                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18422         done
18423         wait
18424         etime=$(date +%s)
18425         delta=$((etime - stime))
18426         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18427
18428         stime=$(date +%s)
18429         for (( i = 0; i < $tcount; i++ )) ; do
18430                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18431         done
18432         wait
18433         etime=$(date +%s)
18434         delta=$((etime - stime))
18435         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18436
18437         rm -rf $DIR/$tdir
18438
18439         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18440
18441         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18442
18443         stime=$(date +%s)
18444         createmany -i 0 -d $DIR/$tdir/t- $tcount
18445
18446         for (( i = 0; i < $tcount; i++ )) ; do
18447                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18448         done
18449         wait
18450         etime=$(date +%s)
18451         delta=$((etime - stime))
18452         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18453
18454         stime=$(date +%s)
18455         for (( i = 0; i < $tcount; i++ )) ; do
18456                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18457         done
18458         wait
18459         etime=$(date +%s)
18460         delta=$((etime - stime))
18461         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18462
18463         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18464 }
18465 run_test 182b "Test parallel modify metadata operations from osp"
18466
18467 test_183() { # LU-2275
18468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18469         remote_mds_nodsh && skip "remote MDS with nodsh"
18470         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18471                 skip "Need MDS version at least 2.3.56"
18472
18473         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18474         echo aaa > $DIR/$tdir/$tfile
18475
18476 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18477         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18478
18479         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18480         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18481
18482         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18483
18484         # Flush negative dentry cache
18485         touch $DIR/$tdir/$tfile
18486
18487         # We are not checking for any leaked references here, they'll
18488         # become evident next time we do cleanup with module unload.
18489         rm -rf $DIR/$tdir
18490 }
18491 run_test 183 "No crash or request leak in case of strange dispositions ========"
18492
18493 # test suite 184 is for LU-2016, LU-2017
18494 test_184a() {
18495         check_swap_layouts_support
18496
18497         dir0=$DIR/$tdir/$testnum
18498         test_mkdir -p -c1 $dir0
18499         ref1=/etc/passwd
18500         ref2=/etc/group
18501         file1=$dir0/f1
18502         file2=$dir0/f2
18503         $LFS setstripe -c1 $file1
18504         cp $ref1 $file1
18505         $LFS setstripe -c2 $file2
18506         cp $ref2 $file2
18507         gen1=$($LFS getstripe -g $file1)
18508         gen2=$($LFS getstripe -g $file2)
18509
18510         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18511         gen=$($LFS getstripe -g $file1)
18512         [[ $gen1 != $gen ]] ||
18513                 error "Layout generation on $file1 does not change"
18514         gen=$($LFS getstripe -g $file2)
18515         [[ $gen2 != $gen ]] ||
18516                 error "Layout generation on $file2 does not change"
18517
18518         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18519         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18520
18521         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18522 }
18523 run_test 184a "Basic layout swap"
18524
18525 test_184b() {
18526         check_swap_layouts_support
18527
18528         dir0=$DIR/$tdir/$testnum
18529         mkdir -p $dir0 || error "creating dir $dir0"
18530         file1=$dir0/f1
18531         file2=$dir0/f2
18532         file3=$dir0/f3
18533         dir1=$dir0/d1
18534         dir2=$dir0/d2
18535         mkdir $dir1 $dir2
18536         $LFS setstripe -c1 $file1
18537         $LFS setstripe -c2 $file2
18538         $LFS setstripe -c1 $file3
18539         chown $RUNAS_ID $file3
18540         gen1=$($LFS getstripe -g $file1)
18541         gen2=$($LFS getstripe -g $file2)
18542
18543         $LFS swap_layouts $dir1 $dir2 &&
18544                 error "swap of directories layouts should fail"
18545         $LFS swap_layouts $dir1 $file1 &&
18546                 error "swap of directory and file layouts should fail"
18547         $RUNAS $LFS swap_layouts $file1 $file2 &&
18548                 error "swap of file we cannot write should fail"
18549         $LFS swap_layouts $file1 $file3 &&
18550                 error "swap of file with different owner should fail"
18551         /bin/true # to clear error code
18552 }
18553 run_test 184b "Forbidden layout swap (will generate errors)"
18554
18555 test_184c() {
18556         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18557         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18558         check_swap_layouts_support
18559         check_swap_layout_no_dom $DIR
18560
18561         local dir0=$DIR/$tdir/$testnum
18562         mkdir -p $dir0 || error "creating dir $dir0"
18563
18564         local ref1=$dir0/ref1
18565         local ref2=$dir0/ref2
18566         local file1=$dir0/file1
18567         local file2=$dir0/file2
18568         # create a file large enough for the concurrent test
18569         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18570         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18571         echo "ref file size: ref1($(stat -c %s $ref1))," \
18572              "ref2($(stat -c %s $ref2))"
18573
18574         cp $ref2 $file2
18575         dd if=$ref1 of=$file1 bs=16k &
18576         local DD_PID=$!
18577
18578         # Make sure dd starts to copy file, but wait at most 5 seconds
18579         local loops=0
18580         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18581
18582         $LFS swap_layouts $file1 $file2
18583         local rc=$?
18584         wait $DD_PID
18585         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18586         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18587
18588         # how many bytes copied before swapping layout
18589         local copied=$(stat -c %s $file2)
18590         local remaining=$(stat -c %s $ref1)
18591         remaining=$((remaining - copied))
18592         echo "Copied $copied bytes before swapping layout..."
18593
18594         cmp -n $copied $file1 $ref2 | grep differ &&
18595                 error "Content mismatch [0, $copied) of ref2 and file1"
18596         cmp -n $copied $file2 $ref1 ||
18597                 error "Content mismatch [0, $copied) of ref1 and file2"
18598         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18599                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18600
18601         # clean up
18602         rm -f $ref1 $ref2 $file1 $file2
18603 }
18604 run_test 184c "Concurrent write and layout swap"
18605
18606 test_184d() {
18607         check_swap_layouts_support
18608         check_swap_layout_no_dom $DIR
18609         [ -z "$(which getfattr 2>/dev/null)" ] &&
18610                 skip_env "no getfattr command"
18611
18612         local file1=$DIR/$tdir/$tfile-1
18613         local file2=$DIR/$tdir/$tfile-2
18614         local file3=$DIR/$tdir/$tfile-3
18615         local lovea1
18616         local lovea2
18617
18618         mkdir -p $DIR/$tdir
18619         touch $file1 || error "create $file1 failed"
18620         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18621                 error "create $file2 failed"
18622         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18623                 error "create $file3 failed"
18624         lovea1=$(get_layout_param $file1)
18625
18626         $LFS swap_layouts $file2 $file3 ||
18627                 error "swap $file2 $file3 layouts failed"
18628         $LFS swap_layouts $file1 $file2 ||
18629                 error "swap $file1 $file2 layouts failed"
18630
18631         lovea2=$(get_layout_param $file2)
18632         echo "$lovea1"
18633         echo "$lovea2"
18634         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18635
18636         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18637         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18638 }
18639 run_test 184d "allow stripeless layouts swap"
18640
18641 test_184e() {
18642         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18643                 skip "Need MDS version at least 2.6.94"
18644         check_swap_layouts_support
18645         check_swap_layout_no_dom $DIR
18646         [ -z "$(which getfattr 2>/dev/null)" ] &&
18647                 skip_env "no getfattr command"
18648
18649         local file1=$DIR/$tdir/$tfile-1
18650         local file2=$DIR/$tdir/$tfile-2
18651         local file3=$DIR/$tdir/$tfile-3
18652         local lovea
18653
18654         mkdir -p $DIR/$tdir
18655         touch $file1 || error "create $file1 failed"
18656         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18657                 error "create $file2 failed"
18658         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18659                 error "create $file3 failed"
18660
18661         $LFS swap_layouts $file1 $file2 ||
18662                 error "swap $file1 $file2 layouts failed"
18663
18664         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18665         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18666
18667         echo 123 > $file1 || error "Should be able to write into $file1"
18668
18669         $LFS swap_layouts $file1 $file3 ||
18670                 error "swap $file1 $file3 layouts failed"
18671
18672         echo 123 > $file1 || error "Should be able to write into $file1"
18673
18674         rm -rf $file1 $file2 $file3
18675 }
18676 run_test 184e "Recreate layout after stripeless layout swaps"
18677
18678 test_184f() {
18679         # Create a file with name longer than sizeof(struct stat) ==
18680         # 144 to see if we can get chars from the file name to appear
18681         # in the returned striping. Note that 'f' == 0x66.
18682         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18683
18684         mkdir -p $DIR/$tdir
18685         mcreate $DIR/$tdir/$file
18686         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18687                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18688         fi
18689 }
18690 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18691
18692 test_185() { # LU-2441
18693         # LU-3553 - no volatile file support in old servers
18694         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18695                 skip "Need MDS version at least 2.3.60"
18696
18697         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18698         touch $DIR/$tdir/spoo
18699         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18700         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18701                 error "cannot create/write a volatile file"
18702         [ "$FILESET" == "" ] &&
18703         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18704                 error "FID is still valid after close"
18705
18706         multiop_bg_pause $DIR/$tdir vVw4096_c
18707         local multi_pid=$!
18708
18709         local OLD_IFS=$IFS
18710         IFS=":"
18711         local fidv=($fid)
18712         IFS=$OLD_IFS
18713         # assume that the next FID for this client is sequential, since stdout
18714         # is unfortunately eaten by multiop_bg_pause
18715         local n=$((${fidv[1]} + 1))
18716         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18717         if [ "$FILESET" == "" ]; then
18718                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18719                         error "FID is missing before close"
18720         fi
18721         kill -USR1 $multi_pid
18722         # 1 second delay, so if mtime change we will see it
18723         sleep 1
18724         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18725         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18726 }
18727 run_test 185 "Volatile file support"
18728
18729 function create_check_volatile() {
18730         local idx=$1
18731         local tgt
18732
18733         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18734         local PID=$!
18735         sleep 1
18736         local FID=$(cat /tmp/${tfile}.fid)
18737         [ "$FID" == "" ] && error "can't get FID for volatile"
18738         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18739         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18740         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18741         kill -USR1 $PID
18742         wait
18743         sleep 1
18744         cancel_lru_locks mdc # flush opencache
18745         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18746         return 0
18747 }
18748
18749 test_185a(){
18750         # LU-12516 - volatile creation via .lustre
18751         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18752                 skip "Need MDS version at least 2.3.55"
18753
18754         create_check_volatile 0
18755         [ $MDSCOUNT -lt 2 ] && return 0
18756
18757         # DNE case
18758         create_check_volatile 1
18759
18760         return 0
18761 }
18762 run_test 185a "Volatile file creation in .lustre/fid/"
18763
18764 test_187a() {
18765         remote_mds_nodsh && skip "remote MDS with nodsh"
18766         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18767                 skip "Need MDS version at least 2.3.0"
18768
18769         local dir0=$DIR/$tdir/$testnum
18770         mkdir -p $dir0 || error "creating dir $dir0"
18771
18772         local file=$dir0/file1
18773         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18774         local dv1=$($LFS data_version $file)
18775         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18776         local dv2=$($LFS data_version $file)
18777         [[ $dv1 != $dv2 ]] ||
18778                 error "data version did not change on write $dv1 == $dv2"
18779
18780         # clean up
18781         rm -f $file1
18782 }
18783 run_test 187a "Test data version change"
18784
18785 test_187b() {
18786         remote_mds_nodsh && skip "remote MDS with nodsh"
18787         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18788                 skip "Need MDS version at least 2.3.0"
18789
18790         local dir0=$DIR/$tdir/$testnum
18791         mkdir -p $dir0 || error "creating dir $dir0"
18792
18793         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18794         [[ ${DV[0]} != ${DV[1]} ]] ||
18795                 error "data version did not change on write"\
18796                       " ${DV[0]} == ${DV[1]}"
18797
18798         # clean up
18799         rm -f $file1
18800 }
18801 run_test 187b "Test data version change on volatile file"
18802
18803 test_200() {
18804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18805         remote_mgs_nodsh && skip "remote MGS with nodsh"
18806         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18807
18808         local POOL=${POOL:-cea1}
18809         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18810         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18811         # Pool OST targets
18812         local first_ost=0
18813         local last_ost=$(($OSTCOUNT - 1))
18814         local ost_step=2
18815         local ost_list=$(seq $first_ost $ost_step $last_ost)
18816         local ost_range="$first_ost $last_ost $ost_step"
18817         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18818         local file_dir=$POOL_ROOT/file_tst
18819         local subdir=$test_path/subdir
18820         local rc=0
18821
18822         while : ; do
18823                 # former test_200a test_200b
18824                 pool_add $POOL                          || { rc=$? ; break; }
18825                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18826                 # former test_200c test_200d
18827                 mkdir -p $test_path
18828                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18829                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18830                 mkdir -p $subdir
18831                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18832                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18833                                                         || { rc=$? ; break; }
18834                 # former test_200e test_200f
18835                 local files=$((OSTCOUNT*3))
18836                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18837                                                         || { rc=$? ; break; }
18838                 pool_create_files $POOL $file_dir $files "$ost_list" \
18839                                                         || { rc=$? ; break; }
18840                 # former test_200g test_200h
18841                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18842                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18843
18844                 # former test_201a test_201b test_201c
18845                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18846
18847                 local f=$test_path/$tfile
18848                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18849                 pool_remove $POOL $f                    || { rc=$? ; break; }
18850                 break
18851         done
18852
18853         destroy_test_pools
18854
18855         return $rc
18856 }
18857 run_test 200 "OST pools"
18858
18859 # usage: default_attr <count | size | offset>
18860 default_attr() {
18861         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18862 }
18863
18864 # usage: check_default_stripe_attr
18865 check_default_stripe_attr() {
18866         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18867         case $1 in
18868         --stripe-count|-c)
18869                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18870         --stripe-size|-S)
18871                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18872         --stripe-index|-i)
18873                 EXPECTED=-1;;
18874         *)
18875                 error "unknown getstripe attr '$1'"
18876         esac
18877
18878         [ $ACTUAL == $EXPECTED ] ||
18879                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18880 }
18881
18882 test_204a() {
18883         test_mkdir $DIR/$tdir
18884         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18885
18886         check_default_stripe_attr --stripe-count
18887         check_default_stripe_attr --stripe-size
18888         check_default_stripe_attr --stripe-index
18889 }
18890 run_test 204a "Print default stripe attributes"
18891
18892 test_204b() {
18893         test_mkdir $DIR/$tdir
18894         $LFS setstripe --stripe-count 1 $DIR/$tdir
18895
18896         check_default_stripe_attr --stripe-size
18897         check_default_stripe_attr --stripe-index
18898 }
18899 run_test 204b "Print default stripe size and offset"
18900
18901 test_204c() {
18902         test_mkdir $DIR/$tdir
18903         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18904
18905         check_default_stripe_attr --stripe-count
18906         check_default_stripe_attr --stripe-index
18907 }
18908 run_test 204c "Print default stripe count and offset"
18909
18910 test_204d() {
18911         test_mkdir $DIR/$tdir
18912         $LFS setstripe --stripe-index 0 $DIR/$tdir
18913
18914         check_default_stripe_attr --stripe-count
18915         check_default_stripe_attr --stripe-size
18916 }
18917 run_test 204d "Print default stripe count and size"
18918
18919 test_204e() {
18920         test_mkdir $DIR/$tdir
18921         $LFS setstripe -d $DIR/$tdir
18922
18923         check_default_stripe_attr --stripe-count --raw
18924         check_default_stripe_attr --stripe-size --raw
18925         check_default_stripe_attr --stripe-index --raw
18926 }
18927 run_test 204e "Print raw stripe attributes"
18928
18929 test_204f() {
18930         test_mkdir $DIR/$tdir
18931         $LFS setstripe --stripe-count 1 $DIR/$tdir
18932
18933         check_default_stripe_attr --stripe-size --raw
18934         check_default_stripe_attr --stripe-index --raw
18935 }
18936 run_test 204f "Print raw stripe size and offset"
18937
18938 test_204g() {
18939         test_mkdir $DIR/$tdir
18940         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18941
18942         check_default_stripe_attr --stripe-count --raw
18943         check_default_stripe_attr --stripe-index --raw
18944 }
18945 run_test 204g "Print raw stripe count and offset"
18946
18947 test_204h() {
18948         test_mkdir $DIR/$tdir
18949         $LFS setstripe --stripe-index 0 $DIR/$tdir
18950
18951         check_default_stripe_attr --stripe-count --raw
18952         check_default_stripe_attr --stripe-size --raw
18953 }
18954 run_test 204h "Print raw stripe count and size"
18955
18956 # Figure out which job scheduler is being used, if any,
18957 # or use a fake one
18958 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18959         JOBENV=SLURM_JOB_ID
18960 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18961         JOBENV=LSB_JOBID
18962 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18963         JOBENV=PBS_JOBID
18964 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18965         JOBENV=LOADL_STEP_ID
18966 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18967         JOBENV=JOB_ID
18968 else
18969         $LCTL list_param jobid_name > /dev/null 2>&1
18970         if [ $? -eq 0 ]; then
18971                 JOBENV=nodelocal
18972         else
18973                 JOBENV=FAKE_JOBID
18974         fi
18975 fi
18976 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18977
18978 verify_jobstats() {
18979         local cmd=($1)
18980         shift
18981         local facets="$@"
18982
18983 # we don't really need to clear the stats for this test to work, since each
18984 # command has a unique jobid, but it makes debugging easier if needed.
18985 #       for facet in $facets; do
18986 #               local dev=$(convert_facet2label $facet)
18987 #               # clear old jobstats
18988 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18989 #       done
18990
18991         # use a new JobID for each test, or we might see an old one
18992         [ "$JOBENV" = "FAKE_JOBID" ] &&
18993                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18994
18995         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18996
18997         [ "$JOBENV" = "nodelocal" ] && {
18998                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18999                 $LCTL set_param jobid_name=$FAKE_JOBID
19000                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19001         }
19002
19003         log "Test: ${cmd[*]}"
19004         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19005
19006         if [ $JOBENV = "FAKE_JOBID" ]; then
19007                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19008         else
19009                 ${cmd[*]}
19010         fi
19011
19012         # all files are created on OST0000
19013         for facet in $facets; do
19014                 local stats="*.$(convert_facet2label $facet).job_stats"
19015
19016                 # strip out libtool wrappers for in-tree executables
19017                 if (( $(do_facet $facet lctl get_param $stats |
19018                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19019                         do_facet $facet lctl get_param $stats
19020                         error "No jobstats for $JOBVAL found on $facet::$stats"
19021                 fi
19022         done
19023 }
19024
19025 jobstats_set() {
19026         local new_jobenv=$1
19027
19028         set_persistent_param_and_check client "jobid_var" \
19029                 "$FSNAME.sys.jobid_var" $new_jobenv
19030 }
19031
19032 test_205a() { # Job stats
19033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19034         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19035                 skip "Need MDS version with at least 2.7.1"
19036         remote_mgs_nodsh && skip "remote MGS with nodsh"
19037         remote_mds_nodsh && skip "remote MDS with nodsh"
19038         remote_ost_nodsh && skip "remote OST with nodsh"
19039         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19040                 skip "Server doesn't support jobstats"
19041         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19042
19043         local old_jobenv=$($LCTL get_param -n jobid_var)
19044         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19045
19046         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19047                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19048         else
19049                 stack_trap "do_facet mgs $PERM_CMD \
19050                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19051         fi
19052         changelog_register
19053
19054         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19055                                 mdt.*.job_cleanup_interval | head -n 1)
19056         local new_interval=5
19057         do_facet $SINGLEMDS \
19058                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19059         stack_trap "do_facet $SINGLEMDS \
19060                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19061         local start=$SECONDS
19062
19063         local cmd
19064         # mkdir
19065         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19066         verify_jobstats "$cmd" "$SINGLEMDS"
19067         # rmdir
19068         cmd="rmdir $DIR/$tdir"
19069         verify_jobstats "$cmd" "$SINGLEMDS"
19070         # mkdir on secondary MDT
19071         if [ $MDSCOUNT -gt 1 ]; then
19072                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19073                 verify_jobstats "$cmd" "mds2"
19074         fi
19075         # mknod
19076         cmd="mknod $DIR/$tfile c 1 3"
19077         verify_jobstats "$cmd" "$SINGLEMDS"
19078         # unlink
19079         cmd="rm -f $DIR/$tfile"
19080         verify_jobstats "$cmd" "$SINGLEMDS"
19081         # create all files on OST0000 so verify_jobstats can find OST stats
19082         # open & close
19083         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19084         verify_jobstats "$cmd" "$SINGLEMDS"
19085         # setattr
19086         cmd="touch $DIR/$tfile"
19087         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19088         # write
19089         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19090         verify_jobstats "$cmd" "ost1"
19091         # read
19092         cancel_lru_locks osc
19093         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19094         verify_jobstats "$cmd" "ost1"
19095         # truncate
19096         cmd="$TRUNCATE $DIR/$tfile 0"
19097         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19098         # rename
19099         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19100         verify_jobstats "$cmd" "$SINGLEMDS"
19101         # jobstats expiry - sleep until old stats should be expired
19102         local left=$((new_interval + 5 - (SECONDS - start)))
19103         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19104                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19105                         "0" $left
19106         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19107         verify_jobstats "$cmd" "$SINGLEMDS"
19108         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19109             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19110
19111         # Ensure that jobid are present in changelog (if supported by MDS)
19112         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19113                 changelog_dump | tail -10
19114                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19115                 [ $jobids -eq 9 ] ||
19116                         error "Wrong changelog jobid count $jobids != 9"
19117
19118                 # LU-5862
19119                 JOBENV="disable"
19120                 jobstats_set $JOBENV
19121                 touch $DIR/$tfile
19122                 changelog_dump | grep $tfile
19123                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19124                 [ $jobids -eq 0 ] ||
19125                         error "Unexpected jobids when jobid_var=$JOBENV"
19126         fi
19127
19128         # test '%j' access to environment variable - if supported
19129         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19130                 JOBENV="JOBCOMPLEX"
19131                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19132
19133                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19134         fi
19135
19136         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19137                 JOBENV="JOBCOMPLEX"
19138                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19139
19140                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19141         fi
19142
19143         # test '%j' access to per-session jobid - if supported
19144         if lctl list_param jobid_this_session > /dev/null 2>&1
19145         then
19146                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19147                 lctl set_param jobid_this_session=$USER
19148
19149                 JOBENV="JOBCOMPLEX"
19150                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19151
19152                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19153         fi
19154 }
19155 run_test 205a "Verify job stats"
19156
19157 # LU-13117, LU-13597
19158 test_205b() {
19159         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19160                 skip "Need MDS version at least 2.13.54.91"
19161
19162         local job_stats="mdt.*.job_stats"
19163         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19164
19165         do_facet mds1 $LCTL set_param $job_stats=clear
19166
19167         # Setting jobid_var to USER might not be supported
19168         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19169         $LCTL set_param jobid_var=USER || true
19170         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19171         $LCTL set_param jobid_name="%j.%e.%u"
19172
19173         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19174         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19175                 { do_facet mds1 $LCTL get_param $job_stats;
19176                   error "Unexpected jobid found"; }
19177         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19178                 { do_facet mds1 $LCTL get_param $job_stats;
19179                   error "wrong job_stats format found"; }
19180
19181         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19182                 echo "MDS does not yet escape jobid" && return 0
19183         $LCTL set_param jobid_var=TEST205b
19184         env -i TEST205b="has sp" touch $DIR/$tfile.2
19185         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19186                 { do_facet mds1 $LCTL get_param $job_stats;
19187                   error "jobid not escaped"; }
19188 }
19189 run_test 205b "Verify job stats jobid and output format"
19190
19191 # LU-13733
19192 test_205c() {
19193         $LCTL set_param llite.*.stats=0
19194         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19195         $LCTL get_param llite.*.stats
19196         $LCTL get_param llite.*.stats | grep \
19197                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19198                         error "wrong client stats format found"
19199 }
19200 run_test 205c "Verify client stats format"
19201
19202 test_205d() {
19203         local file=$DIR/$tdir/$tfile
19204
19205         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
19206                 skip "need lustre >= 2.15.51"
19207         (( $OST1_VERSION >= $(version_code 2.15.52) )) ||
19208                 skip "need lustre >= 2.15.51"
19209         verify_yaml_available || skip_env "YAML verification not installed"
19210
19211         test_mkdir $DIR/$tdir
19212         $LFS setstripe -E 1M -L mdt -E -1 $file || error "setstripe failed"
19213
19214         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19215                 error "failed to write data to $file"
19216         mv $file $file.2
19217
19218         echo -n 'verify rename_stats...'
19219         output=$(do_facet mds1 \
19220                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats")
19221         verify_yaml "$output" || error "rename_stats is not valid YAML"
19222         echo " OK"
19223
19224         echo -n 'verify mdt job_stats...'
19225         output=$(do_facet mds1 \
19226                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats")
19227         verify_yaml "$output" || error "job_stats on mds1 is not valid YAML"
19228         echo " OK"
19229
19230         echo -n 'verify ost job_stats...'
19231         output=$(do_facet ost1 \
19232                  "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats")
19233         verify_yaml "$output" || error "job_stats on ost1 is not valid YAML"
19234         echo " OK"
19235 }
19236 run_test 205d "verify the format of some stats files"
19237
19238 # LU-1480, LU-1773 and LU-1657
19239 test_206() {
19240         mkdir -p $DIR/$tdir
19241         $LFS setstripe -c -1 $DIR/$tdir
19242 #define OBD_FAIL_LOV_INIT 0x1403
19243         $LCTL set_param fail_loc=0xa0001403
19244         $LCTL set_param fail_val=1
19245         touch $DIR/$tdir/$tfile || true
19246 }
19247 run_test 206 "fail lov_init_raid0() doesn't lbug"
19248
19249 test_207a() {
19250         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19251         local fsz=`stat -c %s $DIR/$tfile`
19252         cancel_lru_locks mdc
19253
19254         # do not return layout in getattr intent
19255 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19256         $LCTL set_param fail_loc=0x170
19257         local sz=`stat -c %s $DIR/$tfile`
19258
19259         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19260
19261         rm -rf $DIR/$tfile
19262 }
19263 run_test 207a "can refresh layout at glimpse"
19264
19265 test_207b() {
19266         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19267         local cksum=`md5sum $DIR/$tfile`
19268         local fsz=`stat -c %s $DIR/$tfile`
19269         cancel_lru_locks mdc
19270         cancel_lru_locks osc
19271
19272         # do not return layout in getattr intent
19273 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19274         $LCTL set_param fail_loc=0x171
19275
19276         # it will refresh layout after the file is opened but before read issues
19277         echo checksum is "$cksum"
19278         echo "$cksum" |md5sum -c --quiet || error "file differs"
19279
19280         rm -rf $DIR/$tfile
19281 }
19282 run_test 207b "can refresh layout at open"
19283
19284 test_208() {
19285         # FIXME: in this test suite, only RD lease is used. This is okay
19286         # for now as only exclusive open is supported. After generic lease
19287         # is done, this test suite should be revised. - Jinshan
19288
19289         remote_mds_nodsh && skip "remote MDS with nodsh"
19290         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19291                 skip "Need MDS version at least 2.4.52"
19292
19293         echo "==== test 1: verify get lease work"
19294         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19295
19296         echo "==== test 2: verify lease can be broken by upcoming open"
19297         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19298         local PID=$!
19299         sleep 2
19300
19301         $MULTIOP $DIR/$tfile oO_RDWR:c
19302         kill -USR1 $PID && wait $PID || error "break lease error"
19303
19304         echo "==== test 3: verify lease can't be granted if an open already exists"
19305         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19306         local PID=$!
19307         sleep 2
19308
19309         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19310         kill -USR1 $PID && wait $PID || error "open file error"
19311
19312         echo "==== test 4: lease can sustain over recovery"
19313         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19314         PID=$!
19315         sleep 2
19316
19317         fail mds1
19318
19319         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19320
19321         echo "==== test 5: lease broken can't be regained by replay"
19322         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19323         PID=$!
19324         sleep 2
19325
19326         # open file to break lease and then recovery
19327         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19328         fail mds1
19329
19330         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19331
19332         rm -f $DIR/$tfile
19333 }
19334 run_test 208 "Exclusive open"
19335
19336 test_209() {
19337         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19338                 skip_env "must have disp_stripe"
19339
19340         touch $DIR/$tfile
19341         sync; sleep 5; sync;
19342
19343         echo 3 > /proc/sys/vm/drop_caches
19344         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19345                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19346         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19347
19348         # open/close 500 times
19349         for i in $(seq 500); do
19350                 cat $DIR/$tfile
19351         done
19352
19353         echo 3 > /proc/sys/vm/drop_caches
19354         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19355                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19356         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19357
19358         echo "before: $req_before, after: $req_after"
19359         [ $((req_after - req_before)) -ge 300 ] &&
19360                 error "open/close requests are not freed"
19361         return 0
19362 }
19363 run_test 209 "read-only open/close requests should be freed promptly"
19364
19365 test_210() {
19366         local pid
19367
19368         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19369         pid=$!
19370         sleep 1
19371
19372         $LFS getstripe $DIR/$tfile
19373         kill -USR1 $pid
19374         wait $pid || error "multiop failed"
19375
19376         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19377         pid=$!
19378         sleep 1
19379
19380         $LFS getstripe $DIR/$tfile
19381         kill -USR1 $pid
19382         wait $pid || error "multiop failed"
19383 }
19384 run_test 210 "lfs getstripe does not break leases"
19385
19386 test_212() {
19387         size=`date +%s`
19388         size=$((size % 8192 + 1))
19389         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19390         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19391         rm -f $DIR/f212 $DIR/f212.xyz
19392 }
19393 run_test 212 "Sendfile test ============================================"
19394
19395 test_213() {
19396         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19397         cancel_lru_locks osc
19398         lctl set_param fail_loc=0x8000040f
19399         # generate a read lock
19400         cat $DIR/$tfile > /dev/null
19401         # write to the file, it will try to cancel the above read lock.
19402         cat /etc/hosts >> $DIR/$tfile
19403 }
19404 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19405
19406 test_214() { # for bug 20133
19407         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19408         for (( i=0; i < 340; i++ )) ; do
19409                 touch $DIR/$tdir/d214c/a$i
19410         done
19411
19412         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19413         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19414         ls $DIR/d214c || error "ls $DIR/d214c failed"
19415         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19416         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19417 }
19418 run_test 214 "hash-indexed directory test - bug 20133"
19419
19420 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19421 create_lnet_proc_files() {
19422         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19423 }
19424
19425 # counterpart of create_lnet_proc_files
19426 remove_lnet_proc_files() {
19427         rm -f $TMP/lnet_$1.sys
19428 }
19429
19430 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19431 # 3rd arg as regexp for body
19432 check_lnet_proc_stats() {
19433         local l=$(cat "$TMP/lnet_$1" |wc -l)
19434         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19435
19436         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19437 }
19438
19439 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19440 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19441 # optional and can be regexp for 2nd line (lnet.routes case)
19442 check_lnet_proc_entry() {
19443         local blp=2          # blp stands for 'position of 1st line of body'
19444         [ -z "$5" ] || blp=3 # lnet.routes case
19445
19446         local l=$(cat "$TMP/lnet_$1" |wc -l)
19447         # subtracting one from $blp because the body can be empty
19448         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19449
19450         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19451                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19452
19453         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19454                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19455
19456         # bail out if any unexpected line happened
19457         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19458         [ "$?" != 0 ] || error "$2 misformatted"
19459 }
19460
19461 test_215() { # for bugs 18102, 21079, 21517
19462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19463
19464         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19465         local P='[1-9][0-9]*'           # positive numeric
19466         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19467         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19468         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19469         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19470
19471         local L1 # regexp for 1st line
19472         local L2 # regexp for 2nd line (optional)
19473         local BR # regexp for the rest (body)
19474
19475         # lnet.stats should look as 11 space-separated non-negative numerics
19476         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19477         create_lnet_proc_files "stats"
19478         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19479         remove_lnet_proc_files "stats"
19480
19481         # lnet.routes should look like this:
19482         # Routing disabled/enabled
19483         # net hops priority state router
19484         # where net is a string like tcp0, hops > 0, priority >= 0,
19485         # state is up/down,
19486         # router is a string like 192.168.1.1@tcp2
19487         L1="^Routing (disabled|enabled)$"
19488         L2="^net +hops +priority +state +router$"
19489         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19490         create_lnet_proc_files "routes"
19491         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19492         remove_lnet_proc_files "routes"
19493
19494         # lnet.routers should look like this:
19495         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19496         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19497         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19498         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19499         L1="^ref +rtr_ref +alive +router$"
19500         BR="^$P +$P +(up|down) +$NID$"
19501         create_lnet_proc_files "routers"
19502         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19503         remove_lnet_proc_files "routers"
19504
19505         # lnet.peers should look like this:
19506         # nid refs state last max rtr min tx min queue
19507         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19508         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19509         # numeric (0 or >0 or <0), queue >= 0.
19510         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19511         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19512         create_lnet_proc_files "peers"
19513         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19514         remove_lnet_proc_files "peers"
19515
19516         # lnet.buffers  should look like this:
19517         # pages count credits min
19518         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19519         L1="^pages +count +credits +min$"
19520         BR="^ +$N +$N +$I +$I$"
19521         create_lnet_proc_files "buffers"
19522         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19523         remove_lnet_proc_files "buffers"
19524
19525         # lnet.nis should look like this:
19526         # nid status alive refs peer rtr max tx min
19527         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19528         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19529         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19530         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19531         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19532         create_lnet_proc_files "nis"
19533         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19534         remove_lnet_proc_files "nis"
19535
19536         # can we successfully write to lnet.stats?
19537         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19538 }
19539 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19540
19541 test_216() { # bug 20317
19542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19543         remote_ost_nodsh && skip "remote OST with nodsh"
19544
19545         local node
19546         local facets=$(get_facets OST)
19547         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19548
19549         save_lustre_params client "osc.*.contention_seconds" > $p
19550         save_lustre_params $facets \
19551                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19552         save_lustre_params $facets \
19553                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19554         save_lustre_params $facets \
19555                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19556         clear_stats osc.*.osc_stats
19557
19558         # agressive lockless i/o settings
19559         do_nodes $(comma_list $(osts_nodes)) \
19560                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19561                         ldlm.namespaces.filter-*.contended_locks=0 \
19562                         ldlm.namespaces.filter-*.contention_seconds=60"
19563         lctl set_param -n osc.*.contention_seconds=60
19564
19565         $DIRECTIO write $DIR/$tfile 0 10 4096
19566         $CHECKSTAT -s 40960 $DIR/$tfile
19567
19568         # disable lockless i/o
19569         do_nodes $(comma_list $(osts_nodes)) \
19570                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19571                         ldlm.namespaces.filter-*.contended_locks=32 \
19572                         ldlm.namespaces.filter-*.contention_seconds=0"
19573         lctl set_param -n osc.*.contention_seconds=0
19574         clear_stats osc.*.osc_stats
19575
19576         dd if=/dev/zero of=$DIR/$tfile count=0
19577         $CHECKSTAT -s 0 $DIR/$tfile
19578
19579         restore_lustre_params <$p
19580         rm -f $p
19581         rm $DIR/$tfile
19582 }
19583 run_test 216 "check lockless direct write updates file size and kms correctly"
19584
19585 test_217() { # bug 22430
19586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19587
19588         local node
19589         local nid
19590
19591         for node in $(nodes_list); do
19592                 nid=$(host_nids_address $node $NETTYPE)
19593                 if [[ $nid = *-* ]] ; then
19594                         echo "lctl ping $(h2nettype $nid)"
19595                         lctl ping $(h2nettype $nid)
19596                 else
19597                         echo "skipping $node (no hyphen detected)"
19598                 fi
19599         done
19600 }
19601 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19602
19603 test_218() {
19604        # do directio so as not to populate the page cache
19605        log "creating a 10 Mb file"
19606        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19607        log "starting reads"
19608        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19609        log "truncating the file"
19610        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19611        log "killing dd"
19612        kill %+ || true # reads might have finished
19613        echo "wait until dd is finished"
19614        wait
19615        log "removing the temporary file"
19616        rm -rf $DIR/$tfile || error "tmp file removal failed"
19617 }
19618 run_test 218 "parallel read and truncate should not deadlock"
19619
19620 test_219() {
19621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19622
19623         # write one partial page
19624         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19625         # set no grant so vvp_io_commit_write will do sync write
19626         $LCTL set_param fail_loc=0x411
19627         # write a full page at the end of file
19628         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19629
19630         $LCTL set_param fail_loc=0
19631         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19632         $LCTL set_param fail_loc=0x411
19633         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19634
19635         # LU-4201
19636         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19637         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19638 }
19639 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19640
19641 test_220() { #LU-325
19642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19643         remote_ost_nodsh && skip "remote OST with nodsh"
19644         remote_mds_nodsh && skip "remote MDS with nodsh"
19645         remote_mgs_nodsh && skip "remote MGS with nodsh"
19646
19647         local OSTIDX=0
19648
19649         # create on MDT0000 so the last_id and next_id are correct
19650         mkdir_on_mdt0 $DIR/$tdir
19651         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19652         OST=${OST%_UUID}
19653
19654         # on the mdt's osc
19655         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19656         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19657                         osp.$mdtosc_proc1.prealloc_last_id)
19658         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19659                         osp.$mdtosc_proc1.prealloc_next_id)
19660
19661         $LFS df -i
19662
19663         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19664         #define OBD_FAIL_OST_ENOINO              0x229
19665         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19666         create_pool $FSNAME.$TESTNAME || return 1
19667         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19668
19669         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19670
19671         MDSOBJS=$((last_id - next_id))
19672         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19673
19674         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19675         echo "OST still has $count kbytes free"
19676
19677         echo "create $MDSOBJS files @next_id..."
19678         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19679
19680         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19681                         osp.$mdtosc_proc1.prealloc_last_id)
19682         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19683                         osp.$mdtosc_proc1.prealloc_next_id)
19684
19685         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19686         $LFS df -i
19687
19688         echo "cleanup..."
19689
19690         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19691         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19692
19693         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19694                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19695         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19696                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19697         echo "unlink $MDSOBJS files @$next_id..."
19698         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19699 }
19700 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19701
19702 test_221() {
19703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19704
19705         dd if=`which date` of=$MOUNT/date oflag=sync
19706         chmod +x $MOUNT/date
19707
19708         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19709         $LCTL set_param fail_loc=0x80001401
19710
19711         $MOUNT/date > /dev/null
19712         rm -f $MOUNT/date
19713 }
19714 run_test 221 "make sure fault and truncate race to not cause OOM"
19715
19716 test_222a () {
19717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19718
19719         rm -rf $DIR/$tdir
19720         test_mkdir $DIR/$tdir
19721         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19722         createmany -o $DIR/$tdir/$tfile 10
19723         cancel_lru_locks mdc
19724         cancel_lru_locks osc
19725         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19726         $LCTL set_param fail_loc=0x31a
19727         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19728         $LCTL set_param fail_loc=0
19729         rm -r $DIR/$tdir
19730 }
19731 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19732
19733 test_222b () {
19734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19735
19736         rm -rf $DIR/$tdir
19737         test_mkdir $DIR/$tdir
19738         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19739         createmany -o $DIR/$tdir/$tfile 10
19740         cancel_lru_locks mdc
19741         cancel_lru_locks osc
19742         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19743         $LCTL set_param fail_loc=0x31a
19744         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19745         $LCTL set_param fail_loc=0
19746 }
19747 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19748
19749 test_223 () {
19750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19751
19752         rm -rf $DIR/$tdir
19753         test_mkdir $DIR/$tdir
19754         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19755         createmany -o $DIR/$tdir/$tfile 10
19756         cancel_lru_locks mdc
19757         cancel_lru_locks osc
19758         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19759         $LCTL set_param fail_loc=0x31b
19760         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19761         $LCTL set_param fail_loc=0
19762         rm -r $DIR/$tdir
19763 }
19764 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19765
19766 test_224a() { # LU-1039, MRP-303
19767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19768         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19769         $LCTL set_param fail_loc=0x508
19770         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19771         $LCTL set_param fail_loc=0
19772         df $DIR
19773 }
19774 run_test 224a "Don't panic on bulk IO failure"
19775
19776 test_224bd_sub() { # LU-1039, MRP-303
19777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19778         local timeout=$1
19779
19780         shift
19781         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19782
19783         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19784
19785         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19786         cancel_lru_locks osc
19787         set_checksums 0
19788         stack_trap "set_checksums $ORIG_CSUM" EXIT
19789         local at_max_saved=0
19790
19791         # adaptive timeouts may prevent seeing the issue
19792         if at_is_enabled; then
19793                 at_max_saved=$(at_max_get mds)
19794                 at_max_set 0 mds client
19795                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19796         fi
19797
19798         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19799         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19800         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19801
19802         do_facet ost1 $LCTL set_param fail_loc=0
19803         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19804         df $DIR
19805 }
19806
19807 test_224b() {
19808         test_224bd_sub 3 error "dd failed"
19809 }
19810 run_test 224b "Don't panic on bulk IO failure"
19811
19812 test_224c() { # LU-6441
19813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19814         remote_mds_nodsh && skip "remote MDS with nodsh"
19815
19816         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19817         save_writethrough $p
19818         set_cache writethrough on
19819
19820         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19821         local at_max=$($LCTL get_param -n at_max)
19822         local timeout=$($LCTL get_param -n timeout)
19823         local test_at="at_max"
19824         local param_at="$FSNAME.sys.at_max"
19825         local test_timeout="timeout"
19826         local param_timeout="$FSNAME.sys.timeout"
19827
19828         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19829
19830         set_persistent_param_and_check client "$test_at" "$param_at" 0
19831         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19832
19833         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19834         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19835         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19836         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19837         sync
19838         do_facet ost1 "$LCTL set_param fail_loc=0"
19839
19840         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19841         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19842                 $timeout
19843
19844         $LCTL set_param -n $pages_per_rpc
19845         restore_lustre_params < $p
19846         rm -f $p
19847 }
19848 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19849
19850 test_224d() { # LU-11169
19851         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19852 }
19853 run_test 224d "Don't corrupt data on bulk IO timeout"
19854
19855 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19856 test_225a () {
19857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19858         if [ -z ${MDSSURVEY} ]; then
19859                 skip_env "mds-survey not found"
19860         fi
19861         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19862                 skip "Need MDS version at least 2.2.51"
19863
19864         local mds=$(facet_host $SINGLEMDS)
19865         local target=$(do_nodes $mds 'lctl dl' |
19866                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19867
19868         local cmd1="file_count=1000 thrhi=4"
19869         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19870         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19871         local cmd="$cmd1 $cmd2 $cmd3"
19872
19873         rm -f ${TMP}/mds_survey*
19874         echo + $cmd
19875         eval $cmd || error "mds-survey with zero-stripe failed"
19876         cat ${TMP}/mds_survey*
19877         rm -f ${TMP}/mds_survey*
19878 }
19879 run_test 225a "Metadata survey sanity with zero-stripe"
19880
19881 test_225b () {
19882         if [ -z ${MDSSURVEY} ]; then
19883                 skip_env "mds-survey not found"
19884         fi
19885         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19886                 skip "Need MDS version at least 2.2.51"
19887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19888         remote_mds_nodsh && skip "remote MDS with nodsh"
19889         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19890                 skip_env "Need to mount OST to test"
19891         fi
19892
19893         local mds=$(facet_host $SINGLEMDS)
19894         local target=$(do_nodes $mds 'lctl dl' |
19895                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19896
19897         local cmd1="file_count=1000 thrhi=4"
19898         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19899         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19900         local cmd="$cmd1 $cmd2 $cmd3"
19901
19902         rm -f ${TMP}/mds_survey*
19903         echo + $cmd
19904         eval $cmd || error "mds-survey with stripe_count failed"
19905         cat ${TMP}/mds_survey*
19906         rm -f ${TMP}/mds_survey*
19907 }
19908 run_test 225b "Metadata survey sanity with stripe_count = 1"
19909
19910 mcreate_path2fid () {
19911         local mode=$1
19912         local major=$2
19913         local minor=$3
19914         local name=$4
19915         local desc=$5
19916         local path=$DIR/$tdir/$name
19917         local fid
19918         local rc
19919         local fid_path
19920
19921         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19922                 error "cannot create $desc"
19923
19924         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19925         rc=$?
19926         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19927
19928         fid_path=$($LFS fid2path $MOUNT $fid)
19929         rc=$?
19930         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19931
19932         [ "$path" == "$fid_path" ] ||
19933                 error "fid2path returned $fid_path, expected $path"
19934
19935         echo "pass with $path and $fid"
19936 }
19937
19938 test_226a () {
19939         rm -rf $DIR/$tdir
19940         mkdir -p $DIR/$tdir
19941
19942         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19943         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19944         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19945         mcreate_path2fid 0040666 0 0 dir "directory"
19946         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19947         mcreate_path2fid 0100666 0 0 file "regular file"
19948         mcreate_path2fid 0120666 0 0 link "symbolic link"
19949         mcreate_path2fid 0140666 0 0 sock "socket"
19950 }
19951 run_test 226a "call path2fid and fid2path on files of all type"
19952
19953 test_226b () {
19954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19955
19956         local MDTIDX=1
19957
19958         rm -rf $DIR/$tdir
19959         mkdir -p $DIR/$tdir
19960         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19961                 error "create remote directory failed"
19962         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19963         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19964                                 "character special file (null)"
19965         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19966                                 "character special file (no device)"
19967         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19968         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19969                                 "block special file (loop)"
19970         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19971         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19972         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19973 }
19974 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19975
19976 test_226c () {
19977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19978         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19979                 skip "Need MDS version at least 2.13.55"
19980
19981         local submnt=/mnt/submnt
19982         local srcfile=/etc/passwd
19983         local dstfile=$submnt/passwd
19984         local path
19985         local fid
19986
19987         rm -rf $DIR/$tdir
19988         rm -rf $submnt
19989         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19990                 error "create remote directory failed"
19991         mkdir -p $submnt || error "create $submnt failed"
19992         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19993                 error "mount $submnt failed"
19994         stack_trap "umount $submnt" EXIT
19995
19996         cp $srcfile $dstfile
19997         fid=$($LFS path2fid $dstfile)
19998         path=$($LFS fid2path $submnt "$fid")
19999         [ "$path" = "$dstfile" ] ||
20000                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20001 }
20002 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20003
20004 # LU-1299 Executing or running ldd on a truncated executable does not
20005 # cause an out-of-memory condition.
20006 test_227() {
20007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20008         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20009
20010         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20011         chmod +x $MOUNT/date
20012
20013         $MOUNT/date > /dev/null
20014         ldd $MOUNT/date > /dev/null
20015         rm -f $MOUNT/date
20016 }
20017 run_test 227 "running truncated executable does not cause OOM"
20018
20019 # LU-1512 try to reuse idle OI blocks
20020 test_228a() {
20021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20022         remote_mds_nodsh && skip "remote MDS with nodsh"
20023         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20024
20025         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20026         local myDIR=$DIR/$tdir
20027
20028         mkdir -p $myDIR
20029         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20030         $LCTL set_param fail_loc=0x80001002
20031         createmany -o $myDIR/t- 10000
20032         $LCTL set_param fail_loc=0
20033         # The guard is current the largest FID holder
20034         touch $myDIR/guard
20035         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20036                     tr -d '[')
20037         local IDX=$(($SEQ % 64))
20038
20039         do_facet $SINGLEMDS sync
20040         # Make sure journal flushed.
20041         sleep 6
20042         local blk1=$(do_facet $SINGLEMDS \
20043                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20044                      grep Blockcount | awk '{print $4}')
20045
20046         # Remove old files, some OI blocks will become idle.
20047         unlinkmany $myDIR/t- 10000
20048         # Create new files, idle OI blocks should be reused.
20049         createmany -o $myDIR/t- 2000
20050         do_facet $SINGLEMDS sync
20051         # Make sure journal flushed.
20052         sleep 6
20053         local blk2=$(do_facet $SINGLEMDS \
20054                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20055                      grep Blockcount | awk '{print $4}')
20056
20057         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20058 }
20059 run_test 228a "try to reuse idle OI blocks"
20060
20061 test_228b() {
20062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20063         remote_mds_nodsh && skip "remote MDS with nodsh"
20064         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20065
20066         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20067         local myDIR=$DIR/$tdir
20068
20069         mkdir -p $myDIR
20070         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20071         $LCTL set_param fail_loc=0x80001002
20072         createmany -o $myDIR/t- 10000
20073         $LCTL set_param fail_loc=0
20074         # The guard is current the largest FID holder
20075         touch $myDIR/guard
20076         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20077                     tr -d '[')
20078         local IDX=$(($SEQ % 64))
20079
20080         do_facet $SINGLEMDS sync
20081         # Make sure journal flushed.
20082         sleep 6
20083         local blk1=$(do_facet $SINGLEMDS \
20084                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20085                      grep Blockcount | awk '{print $4}')
20086
20087         # Remove old files, some OI blocks will become idle.
20088         unlinkmany $myDIR/t- 10000
20089
20090         # stop the MDT
20091         stop $SINGLEMDS || error "Fail to stop MDT."
20092         # remount the MDT
20093         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20094                 error "Fail to start MDT."
20095
20096         client_up || error "Fail to df."
20097         # Create new files, idle OI blocks should be reused.
20098         createmany -o $myDIR/t- 2000
20099         do_facet $SINGLEMDS sync
20100         # Make sure journal flushed.
20101         sleep 6
20102         local blk2=$(do_facet $SINGLEMDS \
20103                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20104                      grep Blockcount | awk '{print $4}')
20105
20106         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20107 }
20108 run_test 228b "idle OI blocks can be reused after MDT restart"
20109
20110 #LU-1881
20111 test_228c() {
20112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20113         remote_mds_nodsh && skip "remote MDS with nodsh"
20114         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20115
20116         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20117         local myDIR=$DIR/$tdir
20118
20119         mkdir -p $myDIR
20120         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20121         $LCTL set_param fail_loc=0x80001002
20122         # 20000 files can guarantee there are index nodes in the OI file
20123         createmany -o $myDIR/t- 20000
20124         $LCTL set_param fail_loc=0
20125         # The guard is current the largest FID holder
20126         touch $myDIR/guard
20127         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20128                     tr -d '[')
20129         local IDX=$(($SEQ % 64))
20130
20131         do_facet $SINGLEMDS sync
20132         # Make sure journal flushed.
20133         sleep 6
20134         local blk1=$(do_facet $SINGLEMDS \
20135                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20136                      grep Blockcount | awk '{print $4}')
20137
20138         # Remove old files, some OI blocks will become idle.
20139         unlinkmany $myDIR/t- 20000
20140         rm -f $myDIR/guard
20141         # The OI file should become empty now
20142
20143         # Create new files, idle OI blocks should be reused.
20144         createmany -o $myDIR/t- 2000
20145         do_facet $SINGLEMDS sync
20146         # Make sure journal flushed.
20147         sleep 6
20148         local blk2=$(do_facet $SINGLEMDS \
20149                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20150                      grep Blockcount | awk '{print $4}')
20151
20152         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20153 }
20154 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20155
20156 test_229() { # LU-2482, LU-3448
20157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20158         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20159         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20160                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20161
20162         rm -f $DIR/$tfile
20163
20164         # Create a file with a released layout and stripe count 2.
20165         $MULTIOP $DIR/$tfile H2c ||
20166                 error "failed to create file with released layout"
20167
20168         $LFS getstripe -v $DIR/$tfile
20169
20170         local pattern=$($LFS getstripe -L $DIR/$tfile)
20171         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20172
20173         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20174                 error "getstripe"
20175         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20176         stat $DIR/$tfile || error "failed to stat released file"
20177
20178         chown $RUNAS_ID $DIR/$tfile ||
20179                 error "chown $RUNAS_ID $DIR/$tfile failed"
20180
20181         chgrp $RUNAS_ID $DIR/$tfile ||
20182                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20183
20184         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20185         rm $DIR/$tfile || error "failed to remove released file"
20186 }
20187 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20188
20189 test_230a() {
20190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20192         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20193                 skip "Need MDS version at least 2.11.52"
20194
20195         local MDTIDX=1
20196
20197         test_mkdir $DIR/$tdir
20198         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20199         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20200         [ $mdt_idx -ne 0 ] &&
20201                 error "create local directory on wrong MDT $mdt_idx"
20202
20203         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20204                         error "create remote directory failed"
20205         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20206         [ $mdt_idx -ne $MDTIDX ] &&
20207                 error "create remote directory on wrong MDT $mdt_idx"
20208
20209         createmany -o $DIR/$tdir/test_230/t- 10 ||
20210                 error "create files on remote directory failed"
20211         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20212         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20213         rm -r $DIR/$tdir || error "unlink remote directory failed"
20214 }
20215 run_test 230a "Create remote directory and files under the remote directory"
20216
20217 test_230b() {
20218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20220         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20221                 skip "Need MDS version at least 2.11.52"
20222
20223         local MDTIDX=1
20224         local mdt_index
20225         local i
20226         local file
20227         local pid
20228         local stripe_count
20229         local migrate_dir=$DIR/$tdir/migrate_dir
20230         local other_dir=$DIR/$tdir/other_dir
20231
20232         test_mkdir $DIR/$tdir
20233         test_mkdir -i0 -c1 $migrate_dir
20234         test_mkdir -i0 -c1 $other_dir
20235         for ((i=0; i<10; i++)); do
20236                 mkdir -p $migrate_dir/dir_${i}
20237                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20238                         error "create files under remote dir failed $i"
20239         done
20240
20241         cp /etc/passwd $migrate_dir/$tfile
20242         cp /etc/passwd $other_dir/$tfile
20243         chattr +SAD $migrate_dir
20244         chattr +SAD $migrate_dir/$tfile
20245
20246         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20247         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20248         local old_dir_mode=$(stat -c%f $migrate_dir)
20249         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20250
20251         mkdir -p $migrate_dir/dir_default_stripe2
20252         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20253         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20254
20255         mkdir -p $other_dir
20256         ln $migrate_dir/$tfile $other_dir/luna
20257         ln $migrate_dir/$tfile $migrate_dir/sofia
20258         ln $other_dir/$tfile $migrate_dir/david
20259         ln -s $migrate_dir/$tfile $other_dir/zachary
20260         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20261         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20262
20263         local len
20264         local lnktgt
20265
20266         # inline symlink
20267         for len in 58 59 60; do
20268                 lnktgt=$(str_repeat 'l' $len)
20269                 touch $migrate_dir/$lnktgt
20270                 ln -s $lnktgt $migrate_dir/${len}char_ln
20271         done
20272
20273         # PATH_MAX
20274         for len in 4094 4095; do
20275                 lnktgt=$(str_repeat 'l' $len)
20276                 ln -s $lnktgt $migrate_dir/${len}char_ln
20277         done
20278
20279         # NAME_MAX
20280         for len in 254 255; do
20281                 touch $migrate_dir/$(str_repeat 'l' $len)
20282         done
20283
20284         $LFS migrate -m $MDTIDX $migrate_dir ||
20285                 error "fails on migrating remote dir to MDT1"
20286
20287         echo "migratate to MDT1, then checking.."
20288         for ((i = 0; i < 10; i++)); do
20289                 for file in $(find $migrate_dir/dir_${i}); do
20290                         mdt_index=$($LFS getstripe -m $file)
20291                         # broken symlink getstripe will fail
20292                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20293                                 error "$file is not on MDT${MDTIDX}"
20294                 done
20295         done
20296
20297         # the multiple link file should still in MDT0
20298         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20299         [ $mdt_index == 0 ] ||
20300                 error "$file is not on MDT${MDTIDX}"
20301
20302         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20303         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20304                 error " expect $old_dir_flag get $new_dir_flag"
20305
20306         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20307         [ "$old_file_flag" = "$new_file_flag" ] ||
20308                 error " expect $old_file_flag get $new_file_flag"
20309
20310         local new_dir_mode=$(stat -c%f $migrate_dir)
20311         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20312                 error "expect mode $old_dir_mode get $new_dir_mode"
20313
20314         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20315         [ "$old_file_mode" = "$new_file_mode" ] ||
20316                 error "expect mode $old_file_mode get $new_file_mode"
20317
20318         diff /etc/passwd $migrate_dir/$tfile ||
20319                 error "$tfile different after migration"
20320
20321         diff /etc/passwd $other_dir/luna ||
20322                 error "luna different after migration"
20323
20324         diff /etc/passwd $migrate_dir/sofia ||
20325                 error "sofia different after migration"
20326
20327         diff /etc/passwd $migrate_dir/david ||
20328                 error "david different after migration"
20329
20330         diff /etc/passwd $other_dir/zachary ||
20331                 error "zachary different after migration"
20332
20333         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20334                 error "${tfile}_ln different after migration"
20335
20336         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20337                 error "${tfile}_ln_other different after migration"
20338
20339         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20340         [ $stripe_count = 2 ] ||
20341                 error "dir strpe_count $d != 2 after migration."
20342
20343         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20344         [ $stripe_count = 2 ] ||
20345                 error "file strpe_count $d != 2 after migration."
20346
20347         #migrate back to MDT0
20348         MDTIDX=0
20349
20350         $LFS migrate -m $MDTIDX $migrate_dir ||
20351                 error "fails on migrating remote dir to MDT0"
20352
20353         echo "migrate back to MDT0, checking.."
20354         for file in $(find $migrate_dir); do
20355                 mdt_index=$($LFS getstripe -m $file)
20356                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20357                         error "$file is not on MDT${MDTIDX}"
20358         done
20359
20360         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20361         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20362                 error " expect $old_dir_flag get $new_dir_flag"
20363
20364         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20365         [ "$old_file_flag" = "$new_file_flag" ] ||
20366                 error " expect $old_file_flag get $new_file_flag"
20367
20368         local new_dir_mode=$(stat -c%f $migrate_dir)
20369         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20370                 error "expect mode $old_dir_mode get $new_dir_mode"
20371
20372         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20373         [ "$old_file_mode" = "$new_file_mode" ] ||
20374                 error "expect mode $old_file_mode get $new_file_mode"
20375
20376         diff /etc/passwd ${migrate_dir}/$tfile ||
20377                 error "$tfile different after migration"
20378
20379         diff /etc/passwd ${other_dir}/luna ||
20380                 error "luna different after migration"
20381
20382         diff /etc/passwd ${migrate_dir}/sofia ||
20383                 error "sofia different after migration"
20384
20385         diff /etc/passwd ${other_dir}/zachary ||
20386                 error "zachary different after migration"
20387
20388         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20389                 error "${tfile}_ln different after migration"
20390
20391         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20392                 error "${tfile}_ln_other different after migration"
20393
20394         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20395         [ $stripe_count = 2 ] ||
20396                 error "dir strpe_count $d != 2 after migration."
20397
20398         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20399         [ $stripe_count = 2 ] ||
20400                 error "file strpe_count $d != 2 after migration."
20401
20402         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20403 }
20404 run_test 230b "migrate directory"
20405
20406 test_230c() {
20407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20408         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20409         remote_mds_nodsh && skip "remote MDS with nodsh"
20410         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20411                 skip "Need MDS version at least 2.11.52"
20412
20413         local MDTIDX=1
20414         local total=3
20415         local mdt_index
20416         local file
20417         local migrate_dir=$DIR/$tdir/migrate_dir
20418
20419         #If migrating directory fails in the middle, all entries of
20420         #the directory is still accessiable.
20421         test_mkdir $DIR/$tdir
20422         test_mkdir -i0 -c1 $migrate_dir
20423         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20424         stat $migrate_dir
20425         createmany -o $migrate_dir/f $total ||
20426                 error "create files under ${migrate_dir} failed"
20427
20428         # fail after migrating top dir, and this will fail only once, so the
20429         # first sub file migration will fail (currently f3), others succeed.
20430         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20431         do_facet mds1 lctl set_param fail_loc=0x1801
20432         local t=$(ls $migrate_dir | wc -l)
20433         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20434                 error "migrate should fail"
20435         local u=$(ls $migrate_dir | wc -l)
20436         [ "$u" == "$t" ] || error "$u != $t during migration"
20437
20438         # add new dir/file should succeed
20439         mkdir $migrate_dir/dir ||
20440                 error "mkdir failed under migrating directory"
20441         touch $migrate_dir/file ||
20442                 error "create file failed under migrating directory"
20443
20444         # add file with existing name should fail
20445         for file in $migrate_dir/f*; do
20446                 stat $file > /dev/null || error "stat $file failed"
20447                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20448                         error "open(O_CREAT|O_EXCL) $file should fail"
20449                 $MULTIOP $file m && error "create $file should fail"
20450                 touch $DIR/$tdir/remote_dir/$tfile ||
20451                         error "touch $tfile failed"
20452                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20453                         error "link $file should fail"
20454                 mdt_index=$($LFS getstripe -m $file)
20455                 if [ $mdt_index == 0 ]; then
20456                         # file failed to migrate is not allowed to rename to
20457                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20458                                 error "rename to $file should fail"
20459                 else
20460                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20461                                 error "rename to $file failed"
20462                 fi
20463                 echo hello >> $file || error "write $file failed"
20464         done
20465
20466         # resume migration with different options should fail
20467         $LFS migrate -m 0 $migrate_dir &&
20468                 error "migrate -m 0 $migrate_dir should fail"
20469
20470         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20471                 error "migrate -c 2 $migrate_dir should fail"
20472
20473         # resume migration should succeed
20474         $LFS migrate -m $MDTIDX $migrate_dir ||
20475                 error "migrate $migrate_dir failed"
20476
20477         echo "Finish migration, then checking.."
20478         for file in $(find $migrate_dir); do
20479                 mdt_index=$($LFS getstripe -m $file)
20480                 [ $mdt_index == $MDTIDX ] ||
20481                         error "$file is not on MDT${MDTIDX}"
20482         done
20483
20484         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20485 }
20486 run_test 230c "check directory accessiblity if migration failed"
20487
20488 test_230d() {
20489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20490         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20491         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20492                 skip "Need MDS version at least 2.11.52"
20493         # LU-11235
20494         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20495
20496         local migrate_dir=$DIR/$tdir/migrate_dir
20497         local old_index
20498         local new_index
20499         local old_count
20500         local new_count
20501         local new_hash
20502         local mdt_index
20503         local i
20504         local j
20505
20506         old_index=$((RANDOM % MDSCOUNT))
20507         old_count=$((MDSCOUNT - old_index))
20508         new_index=$((RANDOM % MDSCOUNT))
20509         new_count=$((MDSCOUNT - new_index))
20510         new_hash=1 # for all_char
20511
20512         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20513         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20514
20515         test_mkdir $DIR/$tdir
20516         test_mkdir -i $old_index -c $old_count $migrate_dir
20517
20518         for ((i=0; i<100; i++)); do
20519                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20520                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20521                         error "create files under remote dir failed $i"
20522         done
20523
20524         echo -n "Migrate from MDT$old_index "
20525         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20526         echo -n "to MDT$new_index"
20527         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20528         echo
20529
20530         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20531         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20532                 error "migrate remote dir error"
20533
20534         echo "Finish migration, then checking.."
20535         for file in $(find $migrate_dir -maxdepth 1); do
20536                 mdt_index=$($LFS getstripe -m $file)
20537                 if [ $mdt_index -lt $new_index ] ||
20538                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20539                         error "$file is on MDT$mdt_index"
20540                 fi
20541         done
20542
20543         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20544 }
20545 run_test 230d "check migrate big directory"
20546
20547 test_230e() {
20548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20550         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20551                 skip "Need MDS version at least 2.11.52"
20552
20553         local i
20554         local j
20555         local a_fid
20556         local b_fid
20557
20558         mkdir_on_mdt0 $DIR/$tdir
20559         mkdir $DIR/$tdir/migrate_dir
20560         mkdir $DIR/$tdir/other_dir
20561         touch $DIR/$tdir/migrate_dir/a
20562         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20563         ls $DIR/$tdir/other_dir
20564
20565         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20566                 error "migrate dir fails"
20567
20568         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20569         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20570
20571         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20572         [ $mdt_index == 0 ] || error "a is not on MDT0"
20573
20574         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20575                 error "migrate dir fails"
20576
20577         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20578         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20579
20580         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20581         [ $mdt_index == 1 ] || error "a is not on MDT1"
20582
20583         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20584         [ $mdt_index == 1 ] || error "b is not on MDT1"
20585
20586         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20587         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20588
20589         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20590
20591         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20592 }
20593 run_test 230e "migrate mulitple local link files"
20594
20595 test_230f() {
20596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20597         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20598         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20599                 skip "Need MDS version at least 2.11.52"
20600
20601         local a_fid
20602         local ln_fid
20603
20604         mkdir -p $DIR/$tdir
20605         mkdir $DIR/$tdir/migrate_dir
20606         $LFS mkdir -i1 $DIR/$tdir/other_dir
20607         touch $DIR/$tdir/migrate_dir/a
20608         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20609         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20610         ls $DIR/$tdir/other_dir
20611
20612         # a should be migrated to MDT1, since no other links on MDT0
20613         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20614                 error "#1 migrate dir fails"
20615         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20616         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20617         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20618         [ $mdt_index == 1 ] || error "a is not on MDT1"
20619
20620         # a should stay on MDT1, because it is a mulitple link file
20621         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20622                 error "#2 migrate dir fails"
20623         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20624         [ $mdt_index == 1 ] || error "a is not on MDT1"
20625
20626         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20627                 error "#3 migrate dir fails"
20628
20629         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20630         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20631         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20632
20633         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20634         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20635
20636         # a should be migrated to MDT0, since no other links on MDT1
20637         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20638                 error "#4 migrate dir fails"
20639         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20640         [ $mdt_index == 0 ] || error "a is not on MDT0"
20641
20642         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20643 }
20644 run_test 230f "migrate mulitple remote link files"
20645
20646 test_230g() {
20647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20649         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20650                 skip "Need MDS version at least 2.11.52"
20651
20652         mkdir -p $DIR/$tdir/migrate_dir
20653
20654         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20655                 error "migrating dir to non-exist MDT succeeds"
20656         true
20657 }
20658 run_test 230g "migrate dir to non-exist MDT"
20659
20660 test_230h() {
20661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20662         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20663         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20664                 skip "Need MDS version at least 2.11.52"
20665
20666         local mdt_index
20667
20668         mkdir -p $DIR/$tdir/migrate_dir
20669
20670         $LFS migrate -m1 $DIR &&
20671                 error "migrating mountpoint1 should fail"
20672
20673         $LFS migrate -m1 $DIR/$tdir/.. &&
20674                 error "migrating mountpoint2 should fail"
20675
20676         # same as mv
20677         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20678                 error "migrating $tdir/migrate_dir/.. should fail"
20679
20680         true
20681 }
20682 run_test 230h "migrate .. and root"
20683
20684 test_230i() {
20685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20686         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20687         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20688                 skip "Need MDS version at least 2.11.52"
20689
20690         mkdir -p $DIR/$tdir/migrate_dir
20691
20692         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20693                 error "migration fails with a tailing slash"
20694
20695         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20696                 error "migration fails with two tailing slashes"
20697 }
20698 run_test 230i "lfs migrate -m tolerates trailing slashes"
20699
20700 test_230j() {
20701         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20702         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20703                 skip "Need MDS version at least 2.11.52"
20704
20705         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20706         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20707                 error "create $tfile failed"
20708         cat /etc/passwd > $DIR/$tdir/$tfile
20709
20710         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20711
20712         cmp /etc/passwd $DIR/$tdir/$tfile ||
20713                 error "DoM file mismatch after migration"
20714 }
20715 run_test 230j "DoM file data not changed after dir migration"
20716
20717 test_230k() {
20718         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20719         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20720                 skip "Need MDS version at least 2.11.56"
20721
20722         local total=20
20723         local files_on_starting_mdt=0
20724
20725         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20726         $LFS getdirstripe $DIR/$tdir
20727         for i in $(seq $total); do
20728                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20729                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20730                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20731         done
20732
20733         echo "$files_on_starting_mdt files on MDT0"
20734
20735         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20736         $LFS getdirstripe $DIR/$tdir
20737
20738         files_on_starting_mdt=0
20739         for i in $(seq $total); do
20740                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20741                         error "file $tfile.$i mismatch after migration"
20742                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20743                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20744         done
20745
20746         echo "$files_on_starting_mdt files on MDT1 after migration"
20747         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20748
20749         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20750         $LFS getdirstripe $DIR/$tdir
20751
20752         files_on_starting_mdt=0
20753         for i in $(seq $total); do
20754                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20755                         error "file $tfile.$i mismatch after 2nd migration"
20756                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20757                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20758         done
20759
20760         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20761         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20762
20763         true
20764 }
20765 run_test 230k "file data not changed after dir migration"
20766
20767 test_230l() {
20768         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20769         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20770                 skip "Need MDS version at least 2.11.56"
20771
20772         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20773         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20774                 error "create files under remote dir failed $i"
20775         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20776 }
20777 run_test 230l "readdir between MDTs won't crash"
20778
20779 test_230m() {
20780         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20781         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20782                 skip "Need MDS version at least 2.11.56"
20783
20784         local MDTIDX=1
20785         local mig_dir=$DIR/$tdir/migrate_dir
20786         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20787         local shortstr="b"
20788         local val
20789
20790         echo "Creating files and dirs with xattrs"
20791         test_mkdir $DIR/$tdir
20792         test_mkdir -i0 -c1 $mig_dir
20793         mkdir $mig_dir/dir
20794         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20795                 error "cannot set xattr attr1 on dir"
20796         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20797                 error "cannot set xattr attr2 on dir"
20798         touch $mig_dir/dir/f0
20799         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20800                 error "cannot set xattr attr1 on file"
20801         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20802                 error "cannot set xattr attr2 on file"
20803         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20804         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20805         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20806         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20807         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20808         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20809         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20810         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20811         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20812
20813         echo "Migrating to MDT1"
20814         $LFS migrate -m $MDTIDX $mig_dir ||
20815                 error "fails on migrating dir to MDT1"
20816
20817         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20818         echo "Checking xattrs"
20819         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20820         [ "$val" = $longstr ] ||
20821                 error "expecting xattr1 $longstr on dir, found $val"
20822         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20823         [ "$val" = $shortstr ] ||
20824                 error "expecting xattr2 $shortstr on dir, found $val"
20825         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20826         [ "$val" = $longstr ] ||
20827                 error "expecting xattr1 $longstr on file, found $val"
20828         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20829         [ "$val" = $shortstr ] ||
20830                 error "expecting xattr2 $shortstr on file, found $val"
20831 }
20832 run_test 230m "xattrs not changed after dir migration"
20833
20834 test_230n() {
20835         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20836         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20837                 skip "Need MDS version at least 2.13.53"
20838
20839         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20840         cat /etc/hosts > $DIR/$tdir/$tfile
20841         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20842         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20843
20844         cmp /etc/hosts $DIR/$tdir/$tfile ||
20845                 error "File data mismatch after migration"
20846 }
20847 run_test 230n "Dir migration with mirrored file"
20848
20849 test_230o() {
20850         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20851         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20852                 skip "Need MDS version at least 2.13.52"
20853
20854         local mdts=$(comma_list $(mdts_nodes))
20855         local timeout=100
20856         local restripe_status
20857         local delta
20858         local i
20859
20860         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20861
20862         # in case "crush" hash type is not set
20863         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20864
20865         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20866                            mdt.*MDT0000.enable_dir_restripe)
20867         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20868         stack_trap "do_nodes $mdts $LCTL set_param \
20869                     mdt.*.enable_dir_restripe=$restripe_status"
20870
20871         mkdir $DIR/$tdir
20872         createmany -m $DIR/$tdir/f 100 ||
20873                 error "create files under remote dir failed $i"
20874         createmany -d $DIR/$tdir/d 100 ||
20875                 error "create dirs under remote dir failed $i"
20876
20877         for i in $(seq 2 $MDSCOUNT); do
20878                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20879                 $LFS setdirstripe -c $i $DIR/$tdir ||
20880                         error "split -c $i $tdir failed"
20881                 wait_update $HOSTNAME \
20882                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20883                         error "dir split not finished"
20884                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20885                         awk '/migrate/ {sum += $2} END { print sum }')
20886                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20887                 # delta is around total_files/stripe_count
20888                 (( $delta < 200 / (i - 1) + 4 )) ||
20889                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20890         done
20891 }
20892 run_test 230o "dir split"
20893
20894 test_230p() {
20895         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20896         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20897                 skip "Need MDS version at least 2.13.52"
20898
20899         local mdts=$(comma_list $(mdts_nodes))
20900         local timeout=100
20901         local restripe_status
20902         local delta
20903         local c
20904
20905         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20906
20907         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20908
20909         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20910                            mdt.*MDT0000.enable_dir_restripe)
20911         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20912         stack_trap "do_nodes $mdts $LCTL set_param \
20913                     mdt.*.enable_dir_restripe=$restripe_status"
20914
20915         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20916         createmany -m $DIR/$tdir/f 100 ||
20917                 error "create files under remote dir failed"
20918         createmany -d $DIR/$tdir/d 100 ||
20919                 error "create dirs under remote dir failed"
20920
20921         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20922                 local mdt_hash="crush"
20923
20924                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20925                 $LFS setdirstripe -c $c $DIR/$tdir ||
20926                         error "split -c $c $tdir failed"
20927                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20928                         mdt_hash="$mdt_hash,fixed"
20929                 elif [ $c -eq 1 ]; then
20930                         mdt_hash="none"
20931                 fi
20932                 wait_update $HOSTNAME \
20933                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20934                         error "dir merge not finished"
20935                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20936                         awk '/migrate/ {sum += $2} END { print sum }')
20937                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20938                 # delta is around total_files/stripe_count
20939                 (( delta < 200 / c + 4 )) ||
20940                         error "$delta files migrated >= $((200 / c + 4))"
20941         done
20942 }
20943 run_test 230p "dir merge"
20944
20945 test_230q() {
20946         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20947         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20948                 skip "Need MDS version at least 2.13.52"
20949
20950         local mdts=$(comma_list $(mdts_nodes))
20951         local saved_threshold=$(do_facet mds1 \
20952                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20953         local saved_delta=$(do_facet mds1 \
20954                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20955         local threshold=100
20956         local delta=2
20957         local total=0
20958         local stripe_count=0
20959         local stripe_index
20960         local nr_files
20961         local create
20962
20963         # test with fewer files on ZFS
20964         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20965
20966         stack_trap "do_nodes $mdts $LCTL set_param \
20967                     mdt.*.dir_split_count=$saved_threshold"
20968         stack_trap "do_nodes $mdts $LCTL set_param \
20969                     mdt.*.dir_split_delta=$saved_delta"
20970         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20971         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20972         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20973         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20974         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20975         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20976
20977         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20978         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20979
20980         create=$((threshold * 3 / 2))
20981         while [ $stripe_count -lt $MDSCOUNT ]; do
20982                 createmany -m $DIR/$tdir/f $total $create ||
20983                         error "create sub files failed"
20984                 stat $DIR/$tdir > /dev/null
20985                 total=$((total + create))
20986                 stripe_count=$((stripe_count + delta))
20987                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20988
20989                 wait_update $HOSTNAME \
20990                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20991                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20992
20993                 wait_update $HOSTNAME \
20994                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20995                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20996
20997                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20998                 echo "$nr_files/$total files on MDT$stripe_index after split"
20999                 # allow 10% margin of imbalance with crush hash
21000                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21001                         error "$nr_files files on MDT$stripe_index after split"
21002
21003                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21004                 [ $nr_files -eq $total ] ||
21005                         error "total sub files $nr_files != $total"
21006         done
21007
21008         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21009
21010         echo "fixed layout directory won't auto split"
21011         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21012         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21013                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21014         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21015                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21016 }
21017 run_test 230q "dir auto split"
21018
21019 test_230r() {
21020         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21021         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21022         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21023                 skip "Need MDS version at least 2.13.54"
21024
21025         # maximum amount of local locks:
21026         # parent striped dir - 2 locks
21027         # new stripe in parent to migrate to - 1 lock
21028         # source and target - 2 locks
21029         # Total 5 locks for regular file
21030         mkdir -p $DIR/$tdir
21031         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21032         touch $DIR/$tdir/dir1/eee
21033
21034         # create 4 hardlink for 4 more locks
21035         # Total: 9 locks > RS_MAX_LOCKS (8)
21036         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21037         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21038         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21039         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21040         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21041         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21042         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21043         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21044
21045         cancel_lru_locks mdc
21046
21047         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21048                 error "migrate dir fails"
21049
21050         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21051 }
21052 run_test 230r "migrate with too many local locks"
21053
21054 test_230s() {
21055         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21056                 skip "Need MDS version at least 2.14.52"
21057
21058         local mdts=$(comma_list $(mdts_nodes))
21059         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21060                                 mdt.*MDT0000.enable_dir_restripe)
21061
21062         stack_trap "do_nodes $mdts $LCTL set_param \
21063                     mdt.*.enable_dir_restripe=$restripe_status"
21064
21065         local st
21066         for st in 0 1; do
21067                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21068                 test_mkdir $DIR/$tdir
21069                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21070                         error "$LFS mkdir should return EEXIST if target exists"
21071                 rmdir $DIR/$tdir
21072         done
21073 }
21074 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21075
21076 test_230t()
21077 {
21078         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21079         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21080                 skip "Need MDS version at least 2.14.50"
21081
21082         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21083         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21084         $LFS project -p 1 -s $DIR/$tdir ||
21085                 error "set $tdir project id failed"
21086         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21087                 error "set subdir project id failed"
21088         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21089 }
21090 run_test 230t "migrate directory with project ID set"
21091
21092 test_230u()
21093 {
21094         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21095         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21096                 skip "Need MDS version at least 2.14.53"
21097
21098         local count
21099
21100         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21101         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21102         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21103         for i in $(seq 0 $((MDSCOUNT - 1))); do
21104                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21105                 echo "$count dirs migrated to MDT$i"
21106         done
21107         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21108         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21109 }
21110 run_test 230u "migrate directory by QOS"
21111
21112 test_230v()
21113 {
21114         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21115         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21116                 skip "Need MDS version at least 2.14.53"
21117
21118         local count
21119
21120         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21121         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21122         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21123         for i in $(seq 0 $((MDSCOUNT - 1))); do
21124                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21125                 echo "$count subdirs migrated to MDT$i"
21126                 (( i == 3 )) && (( count > 0 )) &&
21127                         error "subdir shouldn't be migrated to MDT3"
21128         done
21129         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21130         (( count == 3 )) || error "dirs migrated to $count MDTs"
21131 }
21132 run_test 230v "subdir migrated to the MDT where its parent is located"
21133
21134 test_230w() {
21135         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21136         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21137                 skip "Need MDS version at least 2.15.0"
21138
21139         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21140         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21141         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21142
21143         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21144                 error "migrate failed"
21145
21146         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21147                 error "$tdir stripe count mismatch"
21148
21149         for i in $(seq 0 9); do
21150                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21151                         error "d$i is striped"
21152         done
21153 }
21154 run_test 230w "non-recursive mode dir migration"
21155
21156 test_230x() {
21157         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21158         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21159                 skip "Need MDS version at least 2.15.0"
21160
21161         mkdir -p $DIR/$tdir || error "mkdir failed"
21162         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21163
21164         local mdt_name=$(mdtname_from_index 0)
21165         local low=$(do_facet mds2 $LCTL get_param -n \
21166                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21167         local high=$(do_facet mds2 $LCTL get_param -n \
21168                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21169         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21170         local maxage=$(do_facet mds2 $LCTL get_param -n \
21171                 osp.*$mdt_name-osp-MDT0001.maxage)
21172
21173         stack_trap "do_facet mds2 $LCTL set_param -n \
21174                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21175                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21176         stack_trap "do_facet mds2 $LCTL set_param -n \
21177                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21178
21179         do_facet mds2 $LCTL set_param -n \
21180                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21181         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21182         sleep 4
21183         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21184                 error "migrate $tdir should fail"
21185
21186         do_facet mds2 $LCTL set_param -n \
21187                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21188         do_facet mds2 $LCTL set_param -n \
21189                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21190         sleep 4
21191         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21192                 error "migrate failed"
21193         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21194                 error "$tdir stripe count mismatch"
21195 }
21196 run_test 230x "dir migration check space"
21197
21198 test_231a()
21199 {
21200         # For simplicity this test assumes that max_pages_per_rpc
21201         # is the same across all OSCs
21202         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21203         local bulk_size=$((max_pages * PAGE_SIZE))
21204         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21205                                        head -n 1)
21206
21207         mkdir -p $DIR/$tdir
21208         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21209                 error "failed to set stripe with -S ${brw_size}M option"
21210
21211         # clear the OSC stats
21212         $LCTL set_param osc.*.stats=0 &>/dev/null
21213         stop_writeback
21214
21215         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21216         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21217                 oflag=direct &>/dev/null || error "dd failed"
21218
21219         sync; sleep 1; sync # just to be safe
21220         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21221         if [ x$nrpcs != "x1" ]; then
21222                 $LCTL get_param osc.*.stats
21223                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21224         fi
21225
21226         start_writeback
21227         # Drop the OSC cache, otherwise we will read from it
21228         cancel_lru_locks osc
21229
21230         # clear the OSC stats
21231         $LCTL set_param osc.*.stats=0 &>/dev/null
21232
21233         # Client reads $bulk_size.
21234         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21235                 iflag=direct &>/dev/null || error "dd failed"
21236
21237         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21238         if [ x$nrpcs != "x1" ]; then
21239                 $LCTL get_param osc.*.stats
21240                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21241         fi
21242 }
21243 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21244
21245 test_231b() {
21246         mkdir -p $DIR/$tdir
21247         local i
21248         for i in {0..1023}; do
21249                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21250                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21251                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21252         done
21253         sync
21254 }
21255 run_test 231b "must not assert on fully utilized OST request buffer"
21256
21257 test_232a() {
21258         mkdir -p $DIR/$tdir
21259         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21260
21261         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21262         do_facet ost1 $LCTL set_param fail_loc=0x31c
21263
21264         # ignore dd failure
21265         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21266
21267         do_facet ost1 $LCTL set_param fail_loc=0
21268         umount_client $MOUNT || error "umount failed"
21269         mount_client $MOUNT || error "mount failed"
21270         stop ost1 || error "cannot stop ost1"
21271         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21272 }
21273 run_test 232a "failed lock should not block umount"
21274
21275 test_232b() {
21276         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21277                 skip "Need MDS version at least 2.10.58"
21278
21279         mkdir -p $DIR/$tdir
21280         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21281         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21282         sync
21283         cancel_lru_locks osc
21284
21285         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21286         do_facet ost1 $LCTL set_param fail_loc=0x31c
21287
21288         # ignore failure
21289         $LFS data_version $DIR/$tdir/$tfile || true
21290
21291         do_facet ost1 $LCTL set_param fail_loc=0
21292         umount_client $MOUNT || error "umount failed"
21293         mount_client $MOUNT || error "mount failed"
21294         stop ost1 || error "cannot stop ost1"
21295         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21296 }
21297 run_test 232b "failed data version lock should not block umount"
21298
21299 test_233a() {
21300         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21301                 skip "Need MDS version at least 2.3.64"
21302         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21303
21304         local fid=$($LFS path2fid $MOUNT)
21305
21306         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21307                 error "cannot access $MOUNT using its FID '$fid'"
21308 }
21309 run_test 233a "checking that OBF of the FS root succeeds"
21310
21311 test_233b() {
21312         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21313                 skip "Need MDS version at least 2.5.90"
21314         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21315
21316         local fid=$($LFS path2fid $MOUNT/.lustre)
21317
21318         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21319                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21320
21321         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21322         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21323                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21324 }
21325 run_test 233b "checking that OBF of the FS .lustre succeeds"
21326
21327 test_234() {
21328         local p="$TMP/sanityN-$TESTNAME.parameters"
21329         save_lustre_params client "llite.*.xattr_cache" > $p
21330         lctl set_param llite.*.xattr_cache 1 ||
21331                 skip_env "xattr cache is not supported"
21332
21333         mkdir -p $DIR/$tdir || error "mkdir failed"
21334         touch $DIR/$tdir/$tfile || error "touch failed"
21335         # OBD_FAIL_LLITE_XATTR_ENOMEM
21336         $LCTL set_param fail_loc=0x1405
21337         getfattr -n user.attr $DIR/$tdir/$tfile &&
21338                 error "getfattr should have failed with ENOMEM"
21339         $LCTL set_param fail_loc=0x0
21340         rm -rf $DIR/$tdir
21341
21342         restore_lustre_params < $p
21343         rm -f $p
21344 }
21345 run_test 234 "xattr cache should not crash on ENOMEM"
21346
21347 test_235() {
21348         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21349                 skip "Need MDS version at least 2.4.52"
21350
21351         flock_deadlock $DIR/$tfile
21352         local RC=$?
21353         case $RC in
21354                 0)
21355                 ;;
21356                 124) error "process hangs on a deadlock"
21357                 ;;
21358                 *) error "error executing flock_deadlock $DIR/$tfile"
21359                 ;;
21360         esac
21361 }
21362 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21363
21364 #LU-2935
21365 test_236() {
21366         check_swap_layouts_support
21367
21368         local ref1=/etc/passwd
21369         local ref2=/etc/group
21370         local file1=$DIR/$tdir/f1
21371         local file2=$DIR/$tdir/f2
21372
21373         test_mkdir -c1 $DIR/$tdir
21374         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21375         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21376         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21377         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21378         local fd=$(free_fd)
21379         local cmd="exec $fd<>$file2"
21380         eval $cmd
21381         rm $file2
21382         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21383                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21384         cmd="exec $fd>&-"
21385         eval $cmd
21386         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21387
21388         #cleanup
21389         rm -rf $DIR/$tdir
21390 }
21391 run_test 236 "Layout swap on open unlinked file"
21392
21393 # LU-4659 linkea consistency
21394 test_238() {
21395         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21396                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21397                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21398                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21399
21400         touch $DIR/$tfile
21401         ln $DIR/$tfile $DIR/$tfile.lnk
21402         touch $DIR/$tfile.new
21403         mv $DIR/$tfile.new $DIR/$tfile
21404         local fid1=$($LFS path2fid $DIR/$tfile)
21405         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21406         local path1=$($LFS fid2path $FSNAME "$fid1")
21407         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21408         local path2=$($LFS fid2path $FSNAME "$fid2")
21409         [ $tfile.lnk == $path2 ] ||
21410                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21411         rm -f $DIR/$tfile*
21412 }
21413 run_test 238 "Verify linkea consistency"
21414
21415 test_239A() { # was test_239
21416         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21417                 skip "Need MDS version at least 2.5.60"
21418
21419         local list=$(comma_list $(mdts_nodes))
21420
21421         mkdir -p $DIR/$tdir
21422         createmany -o $DIR/$tdir/f- 5000
21423         unlinkmany $DIR/$tdir/f- 5000
21424         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21425                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21426         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21427                         osp.*MDT*.sync_in_flight" | calc_sum)
21428         [ "$changes" -eq 0 ] || error "$changes not synced"
21429 }
21430 run_test 239A "osp_sync test"
21431
21432 test_239a() { #LU-5297
21433         remote_mds_nodsh && skip "remote MDS with nodsh"
21434
21435         touch $DIR/$tfile
21436         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21438         chgrp $RUNAS_GID $DIR/$tfile
21439         wait_delete_completed
21440 }
21441 run_test 239a "process invalid osp sync record correctly"
21442
21443 test_239b() { #LU-5297
21444         remote_mds_nodsh && skip "remote MDS with nodsh"
21445
21446         touch $DIR/$tfile1
21447         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21448         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21449         chgrp $RUNAS_GID $DIR/$tfile1
21450         wait_delete_completed
21451         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21452         touch $DIR/$tfile2
21453         chgrp $RUNAS_GID $DIR/$tfile2
21454         wait_delete_completed
21455 }
21456 run_test 239b "process osp sync record with ENOMEM error correctly"
21457
21458 test_240() {
21459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21460         remote_mds_nodsh && skip "remote MDS with nodsh"
21461
21462         mkdir -p $DIR/$tdir
21463
21464         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21465                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21466         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21467                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21468
21469         umount_client $MOUNT || error "umount failed"
21470         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21471         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21472         mount_client $MOUNT || error "failed to mount client"
21473
21474         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21475         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21476 }
21477 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21478
21479 test_241_bio() {
21480         local count=$1
21481         local bsize=$2
21482
21483         for LOOP in $(seq $count); do
21484                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21485                 cancel_lru_locks $OSC || true
21486         done
21487 }
21488
21489 test_241_dio() {
21490         local count=$1
21491         local bsize=$2
21492
21493         for LOOP in $(seq $1); do
21494                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21495                         2>/dev/null
21496         done
21497 }
21498
21499 test_241a() { # was test_241
21500         local bsize=$PAGE_SIZE
21501
21502         (( bsize < 40960 )) && bsize=40960
21503         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21504         ls -la $DIR/$tfile
21505         cancel_lru_locks $OSC
21506         test_241_bio 1000 $bsize &
21507         PID=$!
21508         test_241_dio 1000 $bsize
21509         wait $PID
21510 }
21511 run_test 241a "bio vs dio"
21512
21513 test_241b() {
21514         local bsize=$PAGE_SIZE
21515
21516         (( bsize < 40960 )) && bsize=40960
21517         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21518         ls -la $DIR/$tfile
21519         test_241_dio 1000 $bsize &
21520         PID=$!
21521         test_241_dio 1000 $bsize
21522         wait $PID
21523 }
21524 run_test 241b "dio vs dio"
21525
21526 test_242() {
21527         remote_mds_nodsh && skip "remote MDS with nodsh"
21528
21529         mkdir_on_mdt0 $DIR/$tdir
21530         touch $DIR/$tdir/$tfile
21531
21532         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21533         do_facet mds1 lctl set_param fail_loc=0x105
21534         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21535
21536         do_facet mds1 lctl set_param fail_loc=0
21537         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21538 }
21539 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21540
21541 test_243()
21542 {
21543         test_mkdir $DIR/$tdir
21544         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21545 }
21546 run_test 243 "various group lock tests"
21547
21548 test_244a()
21549 {
21550         test_mkdir $DIR/$tdir
21551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21552         sendfile_grouplock $DIR/$tdir/$tfile || \
21553                 error "sendfile+grouplock failed"
21554         rm -rf $DIR/$tdir
21555 }
21556 run_test 244a "sendfile with group lock tests"
21557
21558 test_244b()
21559 {
21560         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21561
21562         local threads=50
21563         local size=$((1024*1024))
21564
21565         test_mkdir $DIR/$tdir
21566         for i in $(seq 1 $threads); do
21567                 local file=$DIR/$tdir/file_$((i / 10))
21568                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21569                 local pids[$i]=$!
21570         done
21571         for i in $(seq 1 $threads); do
21572                 wait ${pids[$i]}
21573         done
21574 }
21575 run_test 244b "multi-threaded write with group lock"
21576
21577 test_245a() {
21578         local flagname="multi_mod_rpcs"
21579         local connect_data_name="max_mod_rpcs"
21580         local out
21581
21582         # check if multiple modify RPCs flag is set
21583         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21584                 grep "connect_flags:")
21585         echo "$out"
21586
21587         echo "$out" | grep -qw $flagname
21588         if [ $? -ne 0 ]; then
21589                 echo "connect flag $flagname is not set"
21590                 return
21591         fi
21592
21593         # check if multiple modify RPCs data is set
21594         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21595         echo "$out"
21596
21597         echo "$out" | grep -qw $connect_data_name ||
21598                 error "import should have connect data $connect_data_name"
21599 }
21600 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21601
21602 test_245b() {
21603         local flagname="multi_mod_rpcs"
21604         local connect_data_name="max_mod_rpcs"
21605         local out
21606
21607         remote_mds_nodsh && skip "remote MDS with nodsh"
21608         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21609
21610         # check if multiple modify RPCs flag is set
21611         out=$(do_facet mds1 \
21612               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21613               grep "connect_flags:")
21614         echo "$out"
21615
21616         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21617
21618         # check if multiple modify RPCs data is set
21619         out=$(do_facet mds1 \
21620               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21621
21622         [[ "$out" =~ $connect_data_name ]] ||
21623                 {
21624                         echo "$out"
21625                         error "missing connect data $connect_data_name"
21626                 }
21627 }
21628 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21629
21630 cleanup_247() {
21631         local submount=$1
21632
21633         trap 0
21634         umount_client $submount
21635         rmdir $submount
21636 }
21637
21638 test_247a() {
21639         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21640                 grep -q subtree ||
21641                 skip_env "Fileset feature is not supported"
21642
21643         local submount=${MOUNT}_$tdir
21644
21645         mkdir $MOUNT/$tdir
21646         mkdir -p $submount || error "mkdir $submount failed"
21647         FILESET="$FILESET/$tdir" mount_client $submount ||
21648                 error "mount $submount failed"
21649         trap "cleanup_247 $submount" EXIT
21650         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21651         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21652                 error "read $MOUNT/$tdir/$tfile failed"
21653         cleanup_247 $submount
21654 }
21655 run_test 247a "mount subdir as fileset"
21656
21657 test_247b() {
21658         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21659                 skip_env "Fileset feature is not supported"
21660
21661         local submount=${MOUNT}_$tdir
21662
21663         rm -rf $MOUNT/$tdir
21664         mkdir -p $submount || error "mkdir $submount failed"
21665         SKIP_FILESET=1
21666         FILESET="$FILESET/$tdir" mount_client $submount &&
21667                 error "mount $submount should fail"
21668         rmdir $submount
21669 }
21670 run_test 247b "mount subdir that dose not exist"
21671
21672 test_247c() {
21673         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21674                 skip_env "Fileset feature is not supported"
21675
21676         local submount=${MOUNT}_$tdir
21677
21678         mkdir -p $MOUNT/$tdir/dir1
21679         mkdir -p $submount || error "mkdir $submount failed"
21680         trap "cleanup_247 $submount" EXIT
21681         FILESET="$FILESET/$tdir" mount_client $submount ||
21682                 error "mount $submount failed"
21683         local fid=$($LFS path2fid $MOUNT/)
21684         $LFS fid2path $submount $fid && error "fid2path should fail"
21685         cleanup_247 $submount
21686 }
21687 run_test 247c "running fid2path outside subdirectory root"
21688
21689 test_247d() {
21690         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21691                 skip "Fileset feature is not supported"
21692
21693         local submount=${MOUNT}_$tdir
21694
21695         mkdir -p $MOUNT/$tdir/dir1
21696         mkdir -p $submount || error "mkdir $submount failed"
21697         FILESET="$FILESET/$tdir" mount_client $submount ||
21698                 error "mount $submount failed"
21699         trap "cleanup_247 $submount" EXIT
21700
21701         local td=$submount/dir1
21702         local fid=$($LFS path2fid $td)
21703         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21704
21705         # check that we get the same pathname back
21706         local rootpath
21707         local found
21708         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21709                 echo "$rootpath $fid"
21710                 found=$($LFS fid2path $rootpath "$fid")
21711                 [ -n "$found" ] || error "fid2path should succeed"
21712                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21713         done
21714         # check wrong root path format
21715         rootpath=$submount"_wrong"
21716         found=$($LFS fid2path $rootpath "$fid")
21717         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21718
21719         cleanup_247 $submount
21720 }
21721 run_test 247d "running fid2path inside subdirectory root"
21722
21723 # LU-8037
21724 test_247e() {
21725         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21726                 grep -q subtree ||
21727                 skip "Fileset feature is not supported"
21728
21729         local submount=${MOUNT}_$tdir
21730
21731         mkdir $MOUNT/$tdir
21732         mkdir -p $submount || error "mkdir $submount failed"
21733         FILESET="$FILESET/.." mount_client $submount &&
21734                 error "mount $submount should fail"
21735         rmdir $submount
21736 }
21737 run_test 247e "mount .. as fileset"
21738
21739 test_247f() {
21740         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21741         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21742                 skip "Need at least version 2.14.50.162"
21743         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21744                 skip "Fileset feature is not supported"
21745
21746         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21747         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21748                 error "mkdir remote failed"
21749         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21750                 error "mkdir remote/subdir failed"
21751         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21752                 error "mkdir striped failed"
21753         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21754
21755         local submount=${MOUNT}_$tdir
21756
21757         mkdir -p $submount || error "mkdir $submount failed"
21758         stack_trap "rmdir $submount"
21759
21760         local dir
21761         local fileset=$FILESET
21762         local mdts=$(comma_list $(mdts_nodes))
21763
21764         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21765         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
21766                 $tdir/striped/subdir $tdir/striped/.; do
21767                 FILESET="$fileset/$dir" mount_client $submount ||
21768                         error "mount $dir failed"
21769                 umount_client $submount
21770         done
21771 }
21772 run_test 247f "mount striped or remote directory as fileset"
21773
21774 test_subdir_mount_lock()
21775 {
21776         local testdir=$1
21777         local submount=${MOUNT}_$(basename $testdir)
21778
21779         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
21780
21781         mkdir -p $submount || error "mkdir $submount failed"
21782         stack_trap "rmdir $submount"
21783
21784         FILESET="$fileset/$testdir" mount_client $submount ||
21785                 error "mount $FILESET failed"
21786         stack_trap "umount $submount"
21787
21788         local mdts=$(comma_list $(mdts_nodes))
21789
21790         local nrpcs
21791
21792         stat $submount > /dev/null || error "stat $submount failed"
21793         cancel_lru_locks $MDC
21794         stat $submount > /dev/null || error "stat $submount failed"
21795         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21796         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21797         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21798         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21799                 awk '/getattr/ {sum += $2} END {print sum}')
21800
21801         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21802 }
21803
21804 test_247g() {
21805         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21806
21807         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21808                 error "mkdir $tdir failed"
21809         test_subdir_mount_lock $tdir
21810 }
21811 run_test 247g "striped directory submount revalidate ROOT from cache"
21812
21813 test_247h() {
21814         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21815         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
21816                 skip "Need MDS version at least 2.15.51"
21817
21818         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21819         test_subdir_mount_lock $tdir
21820         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
21821         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
21822                 error "mkdir $tdir.1 failed"
21823         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
21824 }
21825 run_test 247h "remote directory submount revalidate ROOT from cache"
21826
21827 test_248a() {
21828         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21829         [ -z "$fast_read_sav" ] && skip "no fast read support"
21830
21831         # create a large file for fast read verification
21832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21833
21834         # make sure the file is created correctly
21835         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21836                 { rm -f $DIR/$tfile; skip "file creation error"; }
21837
21838         echo "Test 1: verify that fast read is 4 times faster on cache read"
21839
21840         # small read with fast read enabled
21841         $LCTL set_param -n llite.*.fast_read=1
21842         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21843                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21844                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21845         # small read with fast read disabled
21846         $LCTL set_param -n llite.*.fast_read=0
21847         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21848                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21849                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21850
21851         # verify that fast read is 4 times faster for cache read
21852         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21853                 error_not_in_vm "fast read was not 4 times faster: " \
21854                            "$t_fast vs $t_slow"
21855
21856         echo "Test 2: verify the performance between big and small read"
21857         $LCTL set_param -n llite.*.fast_read=1
21858
21859         # 1k non-cache read
21860         cancel_lru_locks osc
21861         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21862                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21863                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21864
21865         # 1M non-cache read
21866         cancel_lru_locks osc
21867         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21868                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21869                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21870
21871         # verify that big IO is not 4 times faster than small IO
21872         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21873                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21874
21875         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21876         rm -f $DIR/$tfile
21877 }
21878 run_test 248a "fast read verification"
21879
21880 test_248b() {
21881         # Default short_io_bytes=16384, try both smaller and larger sizes.
21882         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21883         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21884         echo "bs=53248 count=113 normal buffered write"
21885         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21886                 error "dd of initial data file failed"
21887         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21888
21889         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21890         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21891                 error "dd with sync normal writes failed"
21892         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21893
21894         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21895         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21896                 error "dd with sync small writes failed"
21897         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21898
21899         cancel_lru_locks osc
21900
21901         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21902         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21903         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21904         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21905                 iflag=direct || error "dd with O_DIRECT small read failed"
21906         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21907         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21908                 error "compare $TMP/$tfile.1 failed"
21909
21910         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21911         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21912
21913         # just to see what the maximum tunable value is, and test parsing
21914         echo "test invalid parameter 2MB"
21915         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21916                 error "too-large short_io_bytes allowed"
21917         echo "test maximum parameter 512KB"
21918         # if we can set a larger short_io_bytes, run test regardless of version
21919         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21920                 # older clients may not allow setting it this large, that's OK
21921                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21922                         skip "Need at least client version 2.13.50"
21923                 error "medium short_io_bytes failed"
21924         fi
21925         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21926         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21927
21928         echo "test large parameter 64KB"
21929         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21930         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21931
21932         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21933         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21934                 error "dd with sync large writes failed"
21935         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21936
21937         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21938         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21939         num=$((113 * 4096 / PAGE_SIZE))
21940         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21941         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21942                 error "dd with O_DIRECT large writes failed"
21943         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21944                 error "compare $DIR/$tfile.3 failed"
21945
21946         cancel_lru_locks osc
21947
21948         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21949         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21950                 error "dd with O_DIRECT large read failed"
21951         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21952                 error "compare $TMP/$tfile.2 failed"
21953
21954         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21955         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21956                 error "dd with O_DIRECT large read failed"
21957         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21958                 error "compare $TMP/$tfile.3 failed"
21959 }
21960 run_test 248b "test short_io read and write for both small and large sizes"
21961
21962 test_249() { # LU-7890
21963         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21964                 skip "Need at least version 2.8.54"
21965
21966         rm -f $DIR/$tfile
21967         $LFS setstripe -c 1 $DIR/$tfile
21968         # Offset 2T == 4k * 512M
21969         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21970                 error "dd to 2T offset failed"
21971 }
21972 run_test 249 "Write above 2T file size"
21973
21974 test_250() {
21975         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21976          && skip "no 16TB file size limit on ZFS"
21977
21978         $LFS setstripe -c 1 $DIR/$tfile
21979         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21980         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21981         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21982         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21983                 conv=notrunc,fsync && error "append succeeded"
21984         return 0
21985 }
21986 run_test 250 "Write above 16T limit"
21987
21988 test_251() {
21989         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21990
21991         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21992         #Skip once - writing the first stripe will succeed
21993         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21994         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21995                 error "short write happened"
21996
21997         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21998         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21999                 error "short read happened"
22000
22001         rm -f $DIR/$tfile
22002 }
22003 run_test 251 "Handling short read and write correctly"
22004
22005 test_252() {
22006         remote_mds_nodsh && skip "remote MDS with nodsh"
22007         remote_ost_nodsh && skip "remote OST with nodsh"
22008         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22009                 skip_env "ldiskfs only test"
22010         fi
22011
22012         local tgt
22013         local dev
22014         local out
22015         local uuid
22016         local num
22017         local gen
22018
22019         # check lr_reader on OST0000
22020         tgt=ost1
22021         dev=$(facet_device $tgt)
22022         out=$(do_facet $tgt $LR_READER $dev)
22023         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22024         echo "$out"
22025         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22026         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22027                 error "Invalid uuid returned by $LR_READER on target $tgt"
22028         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22029
22030         # check lr_reader -c on MDT0000
22031         tgt=mds1
22032         dev=$(facet_device $tgt)
22033         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22034                 skip "$LR_READER does not support additional options"
22035         fi
22036         out=$(do_facet $tgt $LR_READER -c $dev)
22037         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22038         echo "$out"
22039         num=$(echo "$out" | grep -c "mdtlov")
22040         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22041                 error "Invalid number of mdtlov clients returned by $LR_READER"
22042         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22043
22044         # check lr_reader -cr on MDT0000
22045         out=$(do_facet $tgt $LR_READER -cr $dev)
22046         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22047         echo "$out"
22048         echo "$out" | grep -q "^reply_data:$" ||
22049                 error "$LR_READER should have returned 'reply_data' section"
22050         num=$(echo "$out" | grep -c "client_generation")
22051         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22052 }
22053 run_test 252 "check lr_reader tool"
22054
22055 test_253() {
22056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22057         remote_mds_nodsh && skip "remote MDS with nodsh"
22058         remote_mgs_nodsh && skip "remote MGS with nodsh"
22059
22060         local ostidx=0
22061         local rc=0
22062         local ost_name=$(ostname_from_index $ostidx)
22063
22064         # on the mdt's osc
22065         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22066         do_facet $SINGLEMDS $LCTL get_param -n \
22067                 osp.$mdtosc_proc1.reserved_mb_high ||
22068                 skip  "remote MDS does not support reserved_mb_high"
22069
22070         rm -rf $DIR/$tdir
22071         wait_mds_ost_sync
22072         wait_delete_completed
22073         mkdir $DIR/$tdir
22074
22075         pool_add $TESTNAME || error "Pool creation failed"
22076         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22077
22078         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22079                 error "Setstripe failed"
22080
22081         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22082
22083         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22084                     grep "watermarks")
22085         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22086
22087         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22088                         osp.$mdtosc_proc1.prealloc_status)
22089         echo "prealloc_status $oa_status"
22090
22091         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22092                 error "File creation should fail"
22093
22094         #object allocation was stopped, but we still able to append files
22095         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22096                 oflag=append || error "Append failed"
22097
22098         rm -f $DIR/$tdir/$tfile.0
22099
22100         # For this test, we want to delete the files we created to go out of
22101         # space but leave the watermark, so we remain nearly out of space
22102         ost_watermarks_enospc_delete_files $tfile $ostidx
22103
22104         wait_delete_completed
22105
22106         sleep_maxage
22107
22108         for i in $(seq 10 12); do
22109                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22110                         2>/dev/null || error "File creation failed after rm"
22111         done
22112
22113         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22114                         osp.$mdtosc_proc1.prealloc_status)
22115         echo "prealloc_status $oa_status"
22116
22117         if (( oa_status != 0 )); then
22118                 error "Object allocation still disable after rm"
22119         fi
22120 }
22121 run_test 253 "Check object allocation limit"
22122
22123 test_254() {
22124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22125         remote_mds_nodsh && skip "remote MDS with nodsh"
22126
22127         local mdt=$(facet_svc $SINGLEMDS)
22128
22129         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22130                 skip "MDS does not support changelog_size"
22131
22132         local cl_user
22133
22134         changelog_register || error "changelog_register failed"
22135
22136         changelog_clear 0 || error "changelog_clear failed"
22137
22138         local size1=$(do_facet $SINGLEMDS \
22139                       $LCTL get_param -n mdd.$mdt.changelog_size)
22140         echo "Changelog size $size1"
22141
22142         rm -rf $DIR/$tdir
22143         $LFS mkdir -i 0 $DIR/$tdir
22144         # change something
22145         mkdir -p $DIR/$tdir/pics/2008/zachy
22146         touch $DIR/$tdir/pics/2008/zachy/timestamp
22147         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22148         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22149         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22150         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22151         rm $DIR/$tdir/pics/desktop.jpg
22152
22153         local size2=$(do_facet $SINGLEMDS \
22154                       $LCTL get_param -n mdd.$mdt.changelog_size)
22155         echo "Changelog size after work $size2"
22156
22157         (( $size2 > $size1 )) ||
22158                 error "new Changelog size=$size2 less than old size=$size1"
22159 }
22160 run_test 254 "Check changelog size"
22161
22162 ladvise_no_type()
22163 {
22164         local type=$1
22165         local file=$2
22166
22167         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22168                 awk -F: '{print $2}' | grep $type > /dev/null
22169         if [ $? -ne 0 ]; then
22170                 return 0
22171         fi
22172         return 1
22173 }
22174
22175 ladvise_no_ioctl()
22176 {
22177         local file=$1
22178
22179         lfs ladvise -a willread $file > /dev/null 2>&1
22180         if [ $? -eq 0 ]; then
22181                 return 1
22182         fi
22183
22184         lfs ladvise -a willread $file 2>&1 |
22185                 grep "Inappropriate ioctl for device" > /dev/null
22186         if [ $? -eq 0 ]; then
22187                 return 0
22188         fi
22189         return 1
22190 }
22191
22192 percent() {
22193         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22194 }
22195
22196 # run a random read IO workload
22197 # usage: random_read_iops <filename> <filesize> <iosize>
22198 random_read_iops() {
22199         local file=$1
22200         local fsize=$2
22201         local iosize=${3:-4096}
22202
22203         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22204                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22205 }
22206
22207 drop_file_oss_cache() {
22208         local file="$1"
22209         local nodes="$2"
22210
22211         $LFS ladvise -a dontneed $file 2>/dev/null ||
22212                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22213 }
22214
22215 ladvise_willread_performance()
22216 {
22217         local repeat=10
22218         local average_origin=0
22219         local average_cache=0
22220         local average_ladvise=0
22221
22222         for ((i = 1; i <= $repeat; i++)); do
22223                 echo "Iter $i/$repeat: reading without willread hint"
22224                 cancel_lru_locks osc
22225                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22226                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22227                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22228                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22229
22230                 cancel_lru_locks osc
22231                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22232                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22233                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22234
22235                 cancel_lru_locks osc
22236                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22237                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22238                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22239                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22240                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22241         done
22242         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22243         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22244         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22245
22246         speedup_cache=$(percent $average_cache $average_origin)
22247         speedup_ladvise=$(percent $average_ladvise $average_origin)
22248
22249         echo "Average uncached read: $average_origin"
22250         echo "Average speedup with OSS cached read: " \
22251                 "$average_cache = +$speedup_cache%"
22252         echo "Average speedup with ladvise willread: " \
22253                 "$average_ladvise = +$speedup_ladvise%"
22254
22255         local lowest_speedup=20
22256         if (( ${average_cache%.*} < $lowest_speedup )); then
22257                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22258                      " got $average_cache%. Skipping ladvise willread check."
22259                 return 0
22260         fi
22261
22262         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22263         # it is still good to run until then to exercise 'ladvise willread'
22264         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22265                 [ "$ost1_FSTYPE" = "zfs" ] &&
22266                 echo "osd-zfs does not support dontneed or drop_caches" &&
22267                 return 0
22268
22269         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22270         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22271                 error_not_in_vm "Speedup with willread is less than " \
22272                         "$lowest_speedup%, got $average_ladvise%"
22273 }
22274
22275 test_255a() {
22276         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22277                 skip "lustre < 2.8.54 does not support ladvise "
22278         remote_ost_nodsh && skip "remote OST with nodsh"
22279
22280         stack_trap "rm -f $DIR/$tfile"
22281         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22282
22283         ladvise_no_type willread $DIR/$tfile &&
22284                 skip "willread ladvise is not supported"
22285
22286         ladvise_no_ioctl $DIR/$tfile &&
22287                 skip "ladvise ioctl is not supported"
22288
22289         local size_mb=100
22290         local size=$((size_mb * 1048576))
22291         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22292                 error "dd to $DIR/$tfile failed"
22293
22294         lfs ladvise -a willread $DIR/$tfile ||
22295                 error "Ladvise failed with no range argument"
22296
22297         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22298                 error "Ladvise failed with no -l or -e argument"
22299
22300         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22301                 error "Ladvise failed with only -e argument"
22302
22303         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22304                 error "Ladvise failed with only -l argument"
22305
22306         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22307                 error "End offset should not be smaller than start offset"
22308
22309         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22310                 error "End offset should not be equal to start offset"
22311
22312         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22313                 error "Ladvise failed with overflowing -s argument"
22314
22315         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22316                 error "Ladvise failed with overflowing -e argument"
22317
22318         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22319                 error "Ladvise failed with overflowing -l argument"
22320
22321         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22322                 error "Ladvise succeeded with conflicting -l and -e arguments"
22323
22324         echo "Synchronous ladvise should wait"
22325         local delay=4
22326 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22327         do_nodes $(comma_list $(osts_nodes)) \
22328                 $LCTL set_param fail_val=$delay fail_loc=0x237
22329
22330         local start_ts=$SECONDS
22331         lfs ladvise -a willread $DIR/$tfile ||
22332                 error "Ladvise failed with no range argument"
22333         local end_ts=$SECONDS
22334         local inteval_ts=$((end_ts - start_ts))
22335
22336         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22337                 error "Synchronous advice didn't wait reply"
22338         fi
22339
22340         echo "Asynchronous ladvise shouldn't wait"
22341         local start_ts=$SECONDS
22342         lfs ladvise -a willread -b $DIR/$tfile ||
22343                 error "Ladvise failed with no range argument"
22344         local end_ts=$SECONDS
22345         local inteval_ts=$((end_ts - start_ts))
22346
22347         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22348                 error "Asynchronous advice blocked"
22349         fi
22350
22351         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22352         ladvise_willread_performance
22353 }
22354 run_test 255a "check 'lfs ladvise -a willread'"
22355
22356 facet_meminfo() {
22357         local facet=$1
22358         local info=$2
22359
22360         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22361 }
22362
22363 test_255b() {
22364         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22365                 skip "lustre < 2.8.54 does not support ladvise "
22366         remote_ost_nodsh && skip "remote OST with nodsh"
22367
22368         stack_trap "rm -f $DIR/$tfile"
22369         lfs setstripe -c 1 -i 0 $DIR/$tfile
22370
22371         ladvise_no_type dontneed $DIR/$tfile &&
22372                 skip "dontneed ladvise is not supported"
22373
22374         ladvise_no_ioctl $DIR/$tfile &&
22375                 skip "ladvise ioctl is not supported"
22376
22377         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22378                 [ "$ost1_FSTYPE" = "zfs" ] &&
22379                 skip "zfs-osd does not support 'ladvise dontneed'"
22380
22381         local size_mb=100
22382         local size=$((size_mb * 1048576))
22383         # In order to prevent disturbance of other processes, only check 3/4
22384         # of the memory usage
22385         local kibibytes=$((size_mb * 1024 * 3 / 4))
22386
22387         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22388                 error "dd to $DIR/$tfile failed"
22389
22390         #force write to complete before dropping OST cache & checking memory
22391         sync
22392
22393         local total=$(facet_meminfo ost1 MemTotal)
22394         echo "Total memory: $total KiB"
22395
22396         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22397         local before_read=$(facet_meminfo ost1 Cached)
22398         echo "Cache used before read: $before_read KiB"
22399
22400         lfs ladvise -a willread $DIR/$tfile ||
22401                 error "Ladvise willread failed"
22402         local after_read=$(facet_meminfo ost1 Cached)
22403         echo "Cache used after read: $after_read KiB"
22404
22405         lfs ladvise -a dontneed $DIR/$tfile ||
22406                 error "Ladvise dontneed again failed"
22407         local no_read=$(facet_meminfo ost1 Cached)
22408         echo "Cache used after dontneed ladvise: $no_read KiB"
22409
22410         if [ $total -lt $((before_read + kibibytes)) ]; then
22411                 echo "Memory is too small, abort checking"
22412                 return 0
22413         fi
22414
22415         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22416                 error "Ladvise willread should use more memory" \
22417                         "than $kibibytes KiB"
22418         fi
22419
22420         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22421                 error "Ladvise dontneed should release more memory" \
22422                         "than $kibibytes KiB"
22423         fi
22424 }
22425 run_test 255b "check 'lfs ladvise -a dontneed'"
22426
22427 test_255c() {
22428         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22429                 skip "lustre < 2.10.50 does not support lockahead"
22430
22431         local ost1_imp=$(get_osc_import_name client ost1)
22432         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22433                          cut -d'.' -f2)
22434         local count
22435         local new_count
22436         local difference
22437         local i
22438         local rc
22439
22440         test_mkdir -p $DIR/$tdir
22441         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22442
22443         #test 10 returns only success/failure
22444         i=10
22445         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22446         rc=$?
22447         if [ $rc -eq 255 ]; then
22448                 error "Ladvise test${i} failed, ${rc}"
22449         fi
22450
22451         #test 11 counts lock enqueue requests, all others count new locks
22452         i=11
22453         count=$(do_facet ost1 \
22454                 $LCTL get_param -n ost.OSS.ost.stats)
22455         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22456
22457         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22458         rc=$?
22459         if [ $rc -eq 255 ]; then
22460                 error "Ladvise test${i} failed, ${rc}"
22461         fi
22462
22463         new_count=$(do_facet ost1 \
22464                 $LCTL get_param -n ost.OSS.ost.stats)
22465         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22466                    awk '{ print $2 }')
22467
22468         difference="$((new_count - count))"
22469         if [ $difference -ne $rc ]; then
22470                 error "Ladvise test${i}, bad enqueue count, returned " \
22471                       "${rc}, actual ${difference}"
22472         fi
22473
22474         for i in $(seq 12 21); do
22475                 # If we do not do this, we run the risk of having too many
22476                 # locks and starting lock cancellation while we are checking
22477                 # lock counts.
22478                 cancel_lru_locks osc
22479
22480                 count=$($LCTL get_param -n \
22481                        ldlm.namespaces.$imp_name.lock_unused_count)
22482
22483                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22484                 rc=$?
22485                 if [ $rc -eq 255 ]; then
22486                         error "Ladvise test ${i} failed, ${rc}"
22487                 fi
22488
22489                 new_count=$($LCTL get_param -n \
22490                        ldlm.namespaces.$imp_name.lock_unused_count)
22491                 difference="$((new_count - count))"
22492
22493                 # Test 15 output is divided by 100 to map down to valid return
22494                 if [ $i -eq 15 ]; then
22495                         rc="$((rc * 100))"
22496                 fi
22497
22498                 if [ $difference -ne $rc ]; then
22499                         error "Ladvise test ${i}, bad lock count, returned " \
22500                               "${rc}, actual ${difference}"
22501                 fi
22502         done
22503
22504         #test 22 returns only success/failure
22505         i=22
22506         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22507         rc=$?
22508         if [ $rc -eq 255 ]; then
22509                 error "Ladvise test${i} failed, ${rc}"
22510         fi
22511 }
22512 run_test 255c "suite of ladvise lockahead tests"
22513
22514 test_256() {
22515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22516         remote_mds_nodsh && skip "remote MDS with nodsh"
22517         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22518         changelog_users $SINGLEMDS | grep "^cl" &&
22519                 skip "active changelog user"
22520
22521         local cl_user
22522         local cat_sl
22523         local mdt_dev
22524
22525         mdt_dev=$(facet_device $SINGLEMDS)
22526         echo $mdt_dev
22527
22528         changelog_register || error "changelog_register failed"
22529
22530         rm -rf $DIR/$tdir
22531         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22532
22533         changelog_clear 0 || error "changelog_clear failed"
22534
22535         # change something
22536         touch $DIR/$tdir/{1..10}
22537
22538         # stop the MDT
22539         stop $SINGLEMDS || error "Fail to stop MDT"
22540
22541         # remount the MDT
22542         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22543                 error "Fail to start MDT"
22544
22545         #after mount new plainllog is used
22546         touch $DIR/$tdir/{11..19}
22547         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22548         stack_trap "rm -f $tmpfile"
22549         cat_sl=$(do_facet $SINGLEMDS "sync; \
22550                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22551                  llog_reader $tmpfile | grep -c type=1064553b")
22552         do_facet $SINGLEMDS llog_reader $tmpfile
22553
22554         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22555
22556         changelog_clear 0 || error "changelog_clear failed"
22557
22558         cat_sl=$(do_facet $SINGLEMDS "sync; \
22559                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22560                  llog_reader $tmpfile | grep -c type=1064553b")
22561
22562         if (( cat_sl == 2 )); then
22563                 error "Empty plain llog was not deleted from changelog catalog"
22564         elif (( cat_sl != 1 )); then
22565                 error "Active plain llog shouldn't be deleted from catalog"
22566         fi
22567 }
22568 run_test 256 "Check llog delete for empty and not full state"
22569
22570 test_257() {
22571         remote_mds_nodsh && skip "remote MDS with nodsh"
22572         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22573                 skip "Need MDS version at least 2.8.55"
22574
22575         test_mkdir $DIR/$tdir
22576
22577         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22578                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22579         stat $DIR/$tdir
22580
22581 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22582         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22583         local facet=mds$((mdtidx + 1))
22584         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22585         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22586
22587         stop $facet || error "stop MDS failed"
22588         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22589                 error "start MDS fail"
22590         wait_recovery_complete $facet
22591 }
22592 run_test 257 "xattr locks are not lost"
22593
22594 # Verify we take the i_mutex when security requires it
22595 test_258a() {
22596 #define OBD_FAIL_IMUTEX_SEC 0x141c
22597         $LCTL set_param fail_loc=0x141c
22598         touch $DIR/$tfile
22599         chmod u+s $DIR/$tfile
22600         chmod a+rwx $DIR/$tfile
22601         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22602         RC=$?
22603         if [ $RC -ne 0 ]; then
22604                 error "error, failed to take i_mutex, rc=$?"
22605         fi
22606         rm -f $DIR/$tfile
22607 }
22608 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22609
22610 # Verify we do NOT take the i_mutex in the normal case
22611 test_258b() {
22612 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22613         $LCTL set_param fail_loc=0x141d
22614         touch $DIR/$tfile
22615         chmod a+rwx $DIR
22616         chmod a+rw $DIR/$tfile
22617         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22618         RC=$?
22619         if [ $RC -ne 0 ]; then
22620                 error "error, took i_mutex unnecessarily, rc=$?"
22621         fi
22622         rm -f $DIR/$tfile
22623
22624 }
22625 run_test 258b "verify i_mutex security behavior"
22626
22627 test_259() {
22628         local file=$DIR/$tfile
22629         local before
22630         local after
22631
22632         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22633
22634         stack_trap "rm -f $file" EXIT
22635
22636         wait_delete_completed
22637         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22638         echo "before: $before"
22639
22640         $LFS setstripe -i 0 -c 1 $file
22641         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22642         sync_all_data
22643         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22644         echo "after write: $after"
22645
22646 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22647         do_facet ost1 $LCTL set_param fail_loc=0x2301
22648         $TRUNCATE $file 0
22649         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22650         echo "after truncate: $after"
22651
22652         stop ost1
22653         do_facet ost1 $LCTL set_param fail_loc=0
22654         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22655         sleep 2
22656         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22657         echo "after restart: $after"
22658         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22659                 error "missing truncate?"
22660
22661         return 0
22662 }
22663 run_test 259 "crash at delayed truncate"
22664
22665 test_260() {
22666 #define OBD_FAIL_MDC_CLOSE               0x806
22667         $LCTL set_param fail_loc=0x80000806
22668         touch $DIR/$tfile
22669
22670 }
22671 run_test 260 "Check mdc_close fail"
22672
22673 ### Data-on-MDT sanity tests ###
22674 test_270a() {
22675         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22676                 skip "Need MDS version at least 2.10.55 for DoM"
22677
22678         # create DoM file
22679         local dom=$DIR/$tdir/dom_file
22680         local tmp=$DIR/$tdir/tmp_file
22681
22682         mkdir_on_mdt0 $DIR/$tdir
22683
22684         # basic checks for DoM component creation
22685         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22686                 error "Can set MDT layout to non-first entry"
22687
22688         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22689                 error "Can define multiple entries as MDT layout"
22690
22691         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22692
22693         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22694         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22695         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22696
22697         local mdtidx=$($LFS getstripe -m $dom)
22698         local mdtname=MDT$(printf %04x $mdtidx)
22699         local facet=mds$((mdtidx + 1))
22700         local space_check=1
22701
22702         # Skip free space checks with ZFS
22703         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22704
22705         # write
22706         sync
22707         local size_tmp=$((65536 * 3))
22708         local mdtfree1=$(do_facet $facet \
22709                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22710
22711         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22712         # check also direct IO along write
22713         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22714         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22715         sync
22716         cmp $tmp $dom || error "file data is different"
22717         [ $(stat -c%s $dom) == $size_tmp ] ||
22718                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22719         if [ $space_check == 1 ]; then
22720                 local mdtfree2=$(do_facet $facet \
22721                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22722
22723                 # increase in usage from by $size_tmp
22724                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22725                         error "MDT free space wrong after write: " \
22726                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22727         fi
22728
22729         # truncate
22730         local size_dom=10000
22731
22732         $TRUNCATE $dom $size_dom
22733         [ $(stat -c%s $dom) == $size_dom ] ||
22734                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22735         if [ $space_check == 1 ]; then
22736                 mdtfree1=$(do_facet $facet \
22737                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22738                 # decrease in usage from $size_tmp to new $size_dom
22739                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22740                   $(((size_tmp - size_dom) / 1024)) ] ||
22741                         error "MDT free space is wrong after truncate: " \
22742                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22743         fi
22744
22745         # append
22746         cat $tmp >> $dom
22747         sync
22748         size_dom=$((size_dom + size_tmp))
22749         [ $(stat -c%s $dom) == $size_dom ] ||
22750                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22751         if [ $space_check == 1 ]; then
22752                 mdtfree2=$(do_facet $facet \
22753                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22754                 # increase in usage by $size_tmp from previous
22755                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22756                         error "MDT free space is wrong after append: " \
22757                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22758         fi
22759
22760         # delete
22761         rm $dom
22762         if [ $space_check == 1 ]; then
22763                 mdtfree1=$(do_facet $facet \
22764                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22765                 # decrease in usage by $size_dom from previous
22766                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22767                         error "MDT free space is wrong after removal: " \
22768                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22769         fi
22770
22771         # combined striping
22772         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22773                 error "Can't create DoM + OST striping"
22774
22775         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22776         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22777         # check also direct IO along write
22778         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22779         sync
22780         cmp $tmp $dom || error "file data is different"
22781         [ $(stat -c%s $dom) == $size_tmp ] ||
22782                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22783         rm $dom $tmp
22784
22785         return 0
22786 }
22787 run_test 270a "DoM: basic functionality tests"
22788
22789 test_270b() {
22790         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22791                 skip "Need MDS version at least 2.10.55"
22792
22793         local dom=$DIR/$tdir/dom_file
22794         local max_size=1048576
22795
22796         mkdir -p $DIR/$tdir
22797         $LFS setstripe -E $max_size -L mdt $dom
22798
22799         # truncate over the limit
22800         $TRUNCATE $dom $(($max_size + 1)) &&
22801                 error "successful truncate over the maximum size"
22802         # write over the limit
22803         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22804                 error "successful write over the maximum size"
22805         # append over the limit
22806         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22807         echo "12345" >> $dom && error "successful append over the maximum size"
22808         rm $dom
22809
22810         return 0
22811 }
22812 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22813
22814 test_270c() {
22815         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22816                 skip "Need MDS version at least 2.10.55"
22817
22818         mkdir -p $DIR/$tdir
22819         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22820
22821         # check files inherit DoM EA
22822         touch $DIR/$tdir/first
22823         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22824                 error "bad pattern"
22825         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22826                 error "bad stripe count"
22827         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22828                 error "bad stripe size"
22829
22830         # check directory inherits DoM EA and uses it as default
22831         mkdir $DIR/$tdir/subdir
22832         touch $DIR/$tdir/subdir/second
22833         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22834                 error "bad pattern in sub-directory"
22835         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22836                 error "bad stripe count in sub-directory"
22837         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22838                 error "bad stripe size in sub-directory"
22839         return 0
22840 }
22841 run_test 270c "DoM: DoM EA inheritance tests"
22842
22843 test_270d() {
22844         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22845                 skip "Need MDS version at least 2.10.55"
22846
22847         mkdir -p $DIR/$tdir
22848         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22849
22850         # inherit default DoM striping
22851         mkdir $DIR/$tdir/subdir
22852         touch $DIR/$tdir/subdir/f1
22853
22854         # change default directory striping
22855         $LFS setstripe -c 1 $DIR/$tdir/subdir
22856         touch $DIR/$tdir/subdir/f2
22857         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22858                 error "wrong default striping in file 2"
22859         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22860                 error "bad pattern in file 2"
22861         return 0
22862 }
22863 run_test 270d "DoM: change striping from DoM to RAID0"
22864
22865 test_270e() {
22866         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22867                 skip "Need MDS version at least 2.10.55"
22868
22869         mkdir -p $DIR/$tdir/dom
22870         mkdir -p $DIR/$tdir/norm
22871         DOMFILES=20
22872         NORMFILES=10
22873         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22874         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22875
22876         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22877         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22878
22879         # find DoM files by layout
22880         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22881         [ $NUM -eq  $DOMFILES ] ||
22882                 error "lfs find -L: found $NUM, expected $DOMFILES"
22883         echo "Test 1: lfs find 20 DOM files by layout: OK"
22884
22885         # there should be 1 dir with default DOM striping
22886         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22887         [ $NUM -eq  1 ] ||
22888                 error "lfs find -L: found $NUM, expected 1 dir"
22889         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22890
22891         # find DoM files by stripe size
22892         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22893         [ $NUM -eq  $DOMFILES ] ||
22894                 error "lfs find -S: found $NUM, expected $DOMFILES"
22895         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22896
22897         # find files by stripe offset except DoM files
22898         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22899         [ $NUM -eq  $NORMFILES ] ||
22900                 error "lfs find -i: found $NUM, expected $NORMFILES"
22901         echo "Test 5: lfs find no DOM files by stripe index: OK"
22902         return 0
22903 }
22904 run_test 270e "DoM: lfs find with DoM files test"
22905
22906 test_270f() {
22907         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22908                 skip "Need MDS version at least 2.10.55"
22909
22910         local mdtname=${FSNAME}-MDT0000-mdtlov
22911         local dom=$DIR/$tdir/dom_file
22912         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22913                                                 lod.$mdtname.dom_stripesize)
22914         local dom_limit=131072
22915
22916         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22917         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22918                                                 lod.$mdtname.dom_stripesize)
22919         [ ${dom_limit} -eq ${dom_current} ] ||
22920                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22921
22922         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22923         $LFS setstripe -d $DIR/$tdir
22924         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22925                 error "Can't set directory default striping"
22926
22927         # exceed maximum stripe size
22928         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22929                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22930         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22931                 error "Able to create DoM component size more than LOD limit"
22932
22933         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22934         dom_current=$(do_facet mds1 $LCTL get_param -n \
22935                                                 lod.$mdtname.dom_stripesize)
22936         [ 0 -eq ${dom_current} ] ||
22937                 error "Can't set zero DoM stripe limit"
22938         rm $dom
22939
22940         # attempt to create DoM file on server with disabled DoM should
22941         # remove DoM entry from layout and be succeed
22942         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22943                 error "Can't create DoM file (DoM is disabled)"
22944         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22945                 error "File has DoM component while DoM is disabled"
22946         rm $dom
22947
22948         # attempt to create DoM file with only DoM stripe should return error
22949         $LFS setstripe -E $dom_limit -L mdt $dom &&
22950                 error "Able to create DoM-only file while DoM is disabled"
22951
22952         # too low values to be aligned with smallest stripe size 64K
22953         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22954         dom_current=$(do_facet mds1 $LCTL get_param -n \
22955                                                 lod.$mdtname.dom_stripesize)
22956         [ 30000 -eq ${dom_current} ] &&
22957                 error "Can set too small DoM stripe limit"
22958
22959         # 64K is a minimal stripe size in Lustre, expect limit of that size
22960         [ 65536 -eq ${dom_current} ] ||
22961                 error "Limit is not set to 64K but ${dom_current}"
22962
22963         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22964         dom_current=$(do_facet mds1 $LCTL get_param -n \
22965                                                 lod.$mdtname.dom_stripesize)
22966         echo $dom_current
22967         [ 2147483648 -eq ${dom_current} ] &&
22968                 error "Can set too large DoM stripe limit"
22969
22970         do_facet mds1 $LCTL set_param -n \
22971                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22972         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22973                 error "Can't create DoM component size after limit change"
22974         do_facet mds1 $LCTL set_param -n \
22975                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22976         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22977                 error "Can't create DoM file after limit decrease"
22978         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22979                 error "Can create big DoM component after limit decrease"
22980         touch ${dom}_def ||
22981                 error "Can't create file with old default layout"
22982
22983         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22984         return 0
22985 }
22986 run_test 270f "DoM: maximum DoM stripe size checks"
22987
22988 test_270g() {
22989         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22990                 skip "Need MDS version at least 2.13.52"
22991         local dom=$DIR/$tdir/$tfile
22992
22993         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22994         local lodname=${FSNAME}-MDT0000-mdtlov
22995
22996         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22997         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22998         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22999         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23000
23001         local dom_limit=1024
23002         local dom_threshold="50%"
23003
23004         $LFS setstripe -d $DIR/$tdir
23005         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23006                 error "Can't set directory default striping"
23007
23008         do_facet mds1 $LCTL set_param -n \
23009                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23010         # set 0 threshold and create DOM file to change tunable stripesize
23011         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23012         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23013                 error "Failed to create $dom file"
23014         # now tunable dom_cur_stripesize should reach maximum
23015         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23016                                         lod.${lodname}.dom_stripesize_cur_kb)
23017         [[ $dom_current == $dom_limit ]] ||
23018                 error "Current DOM stripesize is not maximum"
23019         rm $dom
23020
23021         # set threshold for further tests
23022         do_facet mds1 $LCTL set_param -n \
23023                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23024         echo "DOM threshold is $dom_threshold free space"
23025         local dom_def
23026         local dom_set
23027         # Spoof bfree to exceed threshold
23028         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23029         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23030         for spfree in 40 20 0 15 30 55; do
23031                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23032                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23033                         error "Failed to create $dom file"
23034                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23035                                         lod.${lodname}.dom_stripesize_cur_kb)
23036                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23037                 [[ $dom_def != $dom_current ]] ||
23038                         error "Default stripe size was not changed"
23039                 if (( spfree > 0 )) ; then
23040                         dom_set=$($LFS getstripe -S $dom)
23041                         (( dom_set == dom_def * 1024 )) ||
23042                                 error "DOM component size is still old"
23043                 else
23044                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23045                                 error "DoM component is set with no free space"
23046                 fi
23047                 rm $dom
23048                 dom_current=$dom_def
23049         done
23050 }
23051 run_test 270g "DoM: default DoM stripe size depends on free space"
23052
23053 test_270h() {
23054         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23055                 skip "Need MDS version at least 2.13.53"
23056
23057         local mdtname=${FSNAME}-MDT0000-mdtlov
23058         local dom=$DIR/$tdir/$tfile
23059         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23060
23061         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23062         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23063
23064         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23065         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23066                 error "can't create OST file"
23067         # mirrored file with DOM entry in the second mirror
23068         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23069                 error "can't create mirror with DoM component"
23070
23071         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23072
23073         # DOM component in the middle and has other enries in the same mirror,
23074         # should succeed but lost DoM component
23075         $LFS setstripe --copy=${dom}_1 $dom ||
23076                 error "Can't create file from OST|DOM mirror layout"
23077         # check new file has no DoM layout after all
23078         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23079                 error "File has DoM component while DoM is disabled"
23080 }
23081 run_test 270h "DoM: DoM stripe removal when disabled on server"
23082
23083 test_270i() {
23084         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23085                 skip "Need MDS version at least 2.14.54"
23086
23087         mkdir $DIR/$tdir
23088         # DoM with plain layout
23089         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23090                 error "default plain layout with DoM must fail"
23091         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23092                 error "setstripe plain file layout with DoM must fail"
23093         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23094                 error "default DoM layout with bad striping must fail"
23095         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23096                 error "setstripe to DoM layout with bad striping must fail"
23097         return 0
23098 }
23099 run_test 270i "DoM: setting invalid DoM striping should fail"
23100
23101 test_271a() {
23102         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23103                 skip "Need MDS version at least 2.10.55"
23104
23105         local dom=$DIR/$tdir/dom
23106
23107         mkdir -p $DIR/$tdir
23108
23109         $LFS setstripe -E 1024K -L mdt $dom
23110
23111         lctl set_param -n mdc.*.stats=clear
23112         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23113         cat $dom > /dev/null
23114         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23115         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23116         ls $dom
23117         rm -f $dom
23118 }
23119 run_test 271a "DoM: data is cached for read after write"
23120
23121 test_271b() {
23122         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23123                 skip "Need MDS version at least 2.10.55"
23124
23125         local dom=$DIR/$tdir/dom
23126
23127         mkdir -p $DIR/$tdir
23128
23129         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23130
23131         lctl set_param -n mdc.*.stats=clear
23132         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23133         cancel_lru_locks mdc
23134         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23135         # second stat to check size is cached on client
23136         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23137         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23138         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23139         rm -f $dom
23140 }
23141 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23142
23143 test_271ba() {
23144         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23145                 skip "Need MDS version at least 2.10.55"
23146
23147         local dom=$DIR/$tdir/dom
23148
23149         mkdir -p $DIR/$tdir
23150
23151         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23152
23153         lctl set_param -n mdc.*.stats=clear
23154         lctl set_param -n osc.*.stats=clear
23155         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23156         cancel_lru_locks mdc
23157         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23158         # second stat to check size is cached on client
23159         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23160         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23161         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23162         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23163         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23164         rm -f $dom
23165 }
23166 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23167
23168
23169 get_mdc_stats() {
23170         local mdtidx=$1
23171         local param=$2
23172         local mdt=MDT$(printf %04x $mdtidx)
23173
23174         if [ -z $param ]; then
23175                 lctl get_param -n mdc.*$mdt*.stats
23176         else
23177                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23178         fi
23179 }
23180
23181 test_271c() {
23182         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23183                 skip "Need MDS version at least 2.10.55"
23184
23185         local dom=$DIR/$tdir/dom
23186
23187         mkdir -p $DIR/$tdir
23188
23189         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23190
23191         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23192         local facet=mds$((mdtidx + 1))
23193
23194         cancel_lru_locks mdc
23195         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23196         createmany -o $dom 1000
23197         lctl set_param -n mdc.*.stats=clear
23198         smalliomany -w $dom 1000 200
23199         get_mdc_stats $mdtidx
23200         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23201         # Each file has 1 open, 1 IO enqueues, total 2000
23202         # but now we have also +1 getxattr for security.capability, total 3000
23203         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23204         unlinkmany $dom 1000
23205
23206         cancel_lru_locks mdc
23207         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23208         createmany -o $dom 1000
23209         lctl set_param -n mdc.*.stats=clear
23210         smalliomany -w $dom 1000 200
23211         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23212         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23213         # for OPEN and IO lock.
23214         [ $((enq - enq_2)) -ge 1000 ] ||
23215                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23216         unlinkmany $dom 1000
23217         return 0
23218 }
23219 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23220
23221 cleanup_271def_tests() {
23222         trap 0
23223         rm -f $1
23224 }
23225
23226 test_271d() {
23227         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23228                 skip "Need MDS version at least 2.10.57"
23229
23230         local dom=$DIR/$tdir/dom
23231         local tmp=$TMP/$tfile
23232         trap "cleanup_271def_tests $tmp" EXIT
23233
23234         mkdir -p $DIR/$tdir
23235
23236         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23237
23238         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23239
23240         cancel_lru_locks mdc
23241         dd if=/dev/urandom of=$tmp bs=1000 count=1
23242         dd if=$tmp of=$dom bs=1000 count=1
23243         cancel_lru_locks mdc
23244
23245         cat /etc/hosts >> $tmp
23246         lctl set_param -n mdc.*.stats=clear
23247
23248         # append data to the same file it should update local page
23249         echo "Append to the same page"
23250         cat /etc/hosts >> $dom
23251         local num=$(get_mdc_stats $mdtidx ost_read)
23252         local ra=$(get_mdc_stats $mdtidx req_active)
23253         local rw=$(get_mdc_stats $mdtidx req_waittime)
23254
23255         [ -z $num ] || error "$num READ RPC occured"
23256         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23257         echo "... DONE"
23258
23259         # compare content
23260         cmp $tmp $dom || error "file miscompare"
23261
23262         cancel_lru_locks mdc
23263         lctl set_param -n mdc.*.stats=clear
23264
23265         echo "Open and read file"
23266         cat $dom > /dev/null
23267         local num=$(get_mdc_stats $mdtidx ost_read)
23268         local ra=$(get_mdc_stats $mdtidx req_active)
23269         local rw=$(get_mdc_stats $mdtidx req_waittime)
23270
23271         [ -z $num ] || error "$num READ RPC occured"
23272         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23273         echo "... DONE"
23274
23275         # compare content
23276         cmp $tmp $dom || error "file miscompare"
23277
23278         return 0
23279 }
23280 run_test 271d "DoM: read on open (1K file in reply buffer)"
23281
23282 test_271f() {
23283         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23284                 skip "Need MDS version at least 2.10.57"
23285
23286         local dom=$DIR/$tdir/dom
23287         local tmp=$TMP/$tfile
23288         trap "cleanup_271def_tests $tmp" EXIT
23289
23290         mkdir -p $DIR/$tdir
23291
23292         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23293
23294         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23295
23296         cancel_lru_locks mdc
23297         dd if=/dev/urandom of=$tmp bs=265000 count=1
23298         dd if=$tmp of=$dom bs=265000 count=1
23299         cancel_lru_locks mdc
23300         cat /etc/hosts >> $tmp
23301         lctl set_param -n mdc.*.stats=clear
23302
23303         echo "Append to the same page"
23304         cat /etc/hosts >> $dom
23305         local num=$(get_mdc_stats $mdtidx ost_read)
23306         local ra=$(get_mdc_stats $mdtidx req_active)
23307         local rw=$(get_mdc_stats $mdtidx req_waittime)
23308
23309         [ -z $num ] || error "$num READ RPC occured"
23310         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23311         echo "... DONE"
23312
23313         # compare content
23314         cmp $tmp $dom || error "file miscompare"
23315
23316         cancel_lru_locks mdc
23317         lctl set_param -n mdc.*.stats=clear
23318
23319         echo "Open and read file"
23320         cat $dom > /dev/null
23321         local num=$(get_mdc_stats $mdtidx ost_read)
23322         local ra=$(get_mdc_stats $mdtidx req_active)
23323         local rw=$(get_mdc_stats $mdtidx req_waittime)
23324
23325         [ -z $num ] && num=0
23326         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23327         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23328         echo "... DONE"
23329
23330         # compare content
23331         cmp $tmp $dom || error "file miscompare"
23332
23333         return 0
23334 }
23335 run_test 271f "DoM: read on open (200K file and read tail)"
23336
23337 test_271g() {
23338         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23339                 skip "Skipping due to old client or server version"
23340
23341         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23342         # to get layout
23343         $CHECKSTAT -t file $DIR1/$tfile
23344
23345         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23346         MULTIOP_PID=$!
23347         sleep 1
23348         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23349         $LCTL set_param fail_loc=0x80000314
23350         rm $DIR1/$tfile || error "Unlink fails"
23351         RC=$?
23352         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23353         [ $RC -eq 0 ] || error "Failed write to stale object"
23354 }
23355 run_test 271g "Discard DoM data vs client flush race"
23356
23357 test_272a() {
23358         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23359                 skip "Need MDS version at least 2.11.50"
23360
23361         local dom=$DIR/$tdir/dom
23362         mkdir -p $DIR/$tdir
23363
23364         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23365         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23366                 error "failed to write data into $dom"
23367         local old_md5=$(md5sum $dom)
23368
23369         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23370                 error "failed to migrate to the same DoM component"
23371
23372         local new_md5=$(md5sum $dom)
23373
23374         [ "$old_md5" == "$new_md5" ] ||
23375                 error "md5sum differ: $old_md5, $new_md5"
23376
23377         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23378                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23379 }
23380 run_test 272a "DoM migration: new layout with the same DOM component"
23381
23382 test_272b() {
23383         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23384                 skip "Need MDS version at least 2.11.50"
23385
23386         local dom=$DIR/$tdir/dom
23387         mkdir -p $DIR/$tdir
23388         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23389
23390         local mdtidx=$($LFS getstripe -m $dom)
23391         local mdtname=MDT$(printf %04x $mdtidx)
23392         local facet=mds$((mdtidx + 1))
23393
23394         local mdtfree1=$(do_facet $facet \
23395                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23396         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23397                 error "failed to write data into $dom"
23398         local old_md5=$(md5sum $dom)
23399         cancel_lru_locks mdc
23400         local mdtfree1=$(do_facet $facet \
23401                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23402
23403         $LFS migrate -c2 $dom ||
23404                 error "failed to migrate to the new composite layout"
23405         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23406                 error "MDT stripe was not removed"
23407
23408         cancel_lru_locks mdc
23409         local new_md5=$(md5sum $dom)
23410         [ "$old_md5" == "$new_md5" ] ||
23411                 error "$old_md5 != $new_md5"
23412
23413         # Skip free space checks with ZFS
23414         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23415                 local mdtfree2=$(do_facet $facet \
23416                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23417                 [ $mdtfree2 -gt $mdtfree1 ] ||
23418                         error "MDT space is not freed after migration"
23419         fi
23420         return 0
23421 }
23422 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23423
23424 test_272c() {
23425         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23426                 skip "Need MDS version at least 2.11.50"
23427
23428         local dom=$DIR/$tdir/$tfile
23429         mkdir -p $DIR/$tdir
23430         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23431
23432         local mdtidx=$($LFS getstripe -m $dom)
23433         local mdtname=MDT$(printf %04x $mdtidx)
23434         local facet=mds$((mdtidx + 1))
23435
23436         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23437                 error "failed to write data into $dom"
23438         local old_md5=$(md5sum $dom)
23439         cancel_lru_locks mdc
23440         local mdtfree1=$(do_facet $facet \
23441                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23442
23443         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23444                 error "failed to migrate to the new composite layout"
23445         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23446                 error "MDT stripe was not removed"
23447
23448         cancel_lru_locks mdc
23449         local new_md5=$(md5sum $dom)
23450         [ "$old_md5" == "$new_md5" ] ||
23451                 error "$old_md5 != $new_md5"
23452
23453         # Skip free space checks with ZFS
23454         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23455                 local mdtfree2=$(do_facet $facet \
23456                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23457                 [ $mdtfree2 -gt $mdtfree1 ] ||
23458                         error "MDS space is not freed after migration"
23459         fi
23460         return 0
23461 }
23462 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23463
23464 test_272d() {
23465         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23466                 skip "Need MDS version at least 2.12.55"
23467
23468         local dom=$DIR/$tdir/$tfile
23469         mkdir -p $DIR/$tdir
23470         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23471
23472         local mdtidx=$($LFS getstripe -m $dom)
23473         local mdtname=MDT$(printf %04x $mdtidx)
23474         local facet=mds$((mdtidx + 1))
23475
23476         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23477                 error "failed to write data into $dom"
23478         local old_md5=$(md5sum $dom)
23479         cancel_lru_locks mdc
23480         local mdtfree1=$(do_facet $facet \
23481                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23482
23483         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23484                 error "failed mirroring to the new composite layout"
23485         $LFS mirror resync $dom ||
23486                 error "failed mirror resync"
23487         $LFS mirror split --mirror-id 1 -d $dom ||
23488                 error "failed mirror split"
23489
23490         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23491                 error "MDT stripe was not removed"
23492
23493         cancel_lru_locks mdc
23494         local new_md5=$(md5sum $dom)
23495         [ "$old_md5" == "$new_md5" ] ||
23496                 error "$old_md5 != $new_md5"
23497
23498         # Skip free space checks with ZFS
23499         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23500                 local mdtfree2=$(do_facet $facet \
23501                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23502                 [ $mdtfree2 -gt $mdtfree1 ] ||
23503                         error "MDS space is not freed after DOM mirror deletion"
23504         fi
23505         return 0
23506 }
23507 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23508
23509 test_272e() {
23510         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23511                 skip "Need MDS version at least 2.12.55"
23512
23513         local dom=$DIR/$tdir/$tfile
23514         mkdir -p $DIR/$tdir
23515         $LFS setstripe -c 2 $dom
23516
23517         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23518                 error "failed to write data into $dom"
23519         local old_md5=$(md5sum $dom)
23520         cancel_lru_locks
23521
23522         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23523                 error "failed mirroring to the DOM layout"
23524         $LFS mirror resync $dom ||
23525                 error "failed mirror resync"
23526         $LFS mirror split --mirror-id 1 -d $dom ||
23527                 error "failed mirror split"
23528
23529         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23530                 error "MDT stripe wasn't set"
23531
23532         cancel_lru_locks
23533         local new_md5=$(md5sum $dom)
23534         [ "$old_md5" == "$new_md5" ] ||
23535                 error "$old_md5 != $new_md5"
23536
23537         return 0
23538 }
23539 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23540
23541 test_272f() {
23542         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23543                 skip "Need MDS version at least 2.12.55"
23544
23545         local dom=$DIR/$tdir/$tfile
23546         mkdir -p $DIR/$tdir
23547         $LFS setstripe -c 2 $dom
23548
23549         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23550                 error "failed to write data into $dom"
23551         local old_md5=$(md5sum $dom)
23552         cancel_lru_locks
23553
23554         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23555                 error "failed migrating to the DOM file"
23556
23557         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23558                 error "MDT stripe wasn't set"
23559
23560         cancel_lru_locks
23561         local new_md5=$(md5sum $dom)
23562         [ "$old_md5" != "$new_md5" ] &&
23563                 error "$old_md5 != $new_md5"
23564
23565         return 0
23566 }
23567 run_test 272f "DoM migration: OST-striped file to DOM file"
23568
23569 test_273a() {
23570         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23571                 skip "Need MDS version at least 2.11.50"
23572
23573         # Layout swap cannot be done if either file has DOM component,
23574         # this will never be supported, migration should be used instead
23575
23576         local dom=$DIR/$tdir/$tfile
23577         mkdir -p $DIR/$tdir
23578
23579         $LFS setstripe -c2 ${dom}_plain
23580         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23581         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23582                 error "can swap layout with DoM component"
23583         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23584                 error "can swap layout with DoM component"
23585
23586         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23587         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23588                 error "can swap layout with DoM component"
23589         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23590                 error "can swap layout with DoM component"
23591         return 0
23592 }
23593 run_test 273a "DoM: layout swapping should fail with DOM"
23594
23595 test_273b() {
23596         mkdir -p $DIR/$tdir
23597         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23598
23599 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23600         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23601
23602         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23603 }
23604 run_test 273b "DoM: race writeback and object destroy"
23605
23606 test_275() {
23607         remote_ost_nodsh && skip "remote OST with nodsh"
23608         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23609                 skip "Need OST version >= 2.10.57"
23610
23611         local file=$DIR/$tfile
23612         local oss
23613
23614         oss=$(comma_list $(osts_nodes))
23615
23616         dd if=/dev/urandom of=$file bs=1M count=2 ||
23617                 error "failed to create a file"
23618         cancel_lru_locks osc
23619
23620         #lock 1
23621         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23622                 error "failed to read a file"
23623
23624 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23625         $LCTL set_param fail_loc=0x8000031f
23626
23627         cancel_lru_locks osc &
23628         sleep 1
23629
23630 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23631         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23632         #IO takes another lock, but matches the PENDING one
23633         #and places it to the IO RPC
23634         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23635                 error "failed to read a file with PENDING lock"
23636 }
23637 run_test 275 "Read on a canceled duplicate lock"
23638
23639 test_276() {
23640         remote_ost_nodsh && skip "remote OST with nodsh"
23641         local pid
23642
23643         do_facet ost1 "(while true; do \
23644                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23645                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23646         pid=$!
23647
23648         for LOOP in $(seq 20); do
23649                 stop ost1
23650                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23651         done
23652         kill -9 $pid
23653         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23654                 rm $TMP/sanity_276_pid"
23655 }
23656 run_test 276 "Race between mount and obd_statfs"
23657
23658 test_277() {
23659         $LCTL set_param ldlm.namespaces.*.lru_size=0
23660         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23661         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23662                         grep ^used_mb | awk '{print $2}')
23663         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23664         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23665                 oflag=direct conv=notrunc
23666         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23667                         grep ^used_mb | awk '{print $2}')
23668         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23669 }
23670 run_test 277 "Direct IO shall drop page cache"
23671
23672 test_278() {
23673         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23674         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23675         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23676                 skip "needs the same host for mdt1 mdt2" && return
23677
23678         local pid1
23679         local pid2
23680
23681 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23682         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23683         stop mds2 &
23684         pid2=$!
23685
23686         stop mds1
23687
23688         echo "Starting MDTs"
23689         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23690         wait $pid2
23691 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23692 #will return NULL
23693         do_facet mds2 $LCTL set_param fail_loc=0
23694
23695         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23696         wait_recovery_complete mds2
23697 }
23698 run_test 278 "Race starting MDS between MDTs stop/start"
23699
23700 test_280() {
23701         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23702                 skip "Need MGS version at least 2.13.52"
23703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23704         combined_mgs_mds || skip "needs combined MGS/MDT"
23705
23706         umount_client $MOUNT
23707 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23708         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23709
23710         mount_client $MOUNT &
23711         sleep 1
23712         stop mgs || error "stop mgs failed"
23713         #for a race mgs would crash
23714         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23715         # make sure we unmount client before remounting
23716         wait
23717         umount_client $MOUNT
23718         mount_client $MOUNT || error "mount client failed"
23719 }
23720 run_test 280 "Race between MGS umount and client llog processing"
23721
23722 cleanup_test_300() {
23723         trap 0
23724         umask $SAVE_UMASK
23725 }
23726 test_striped_dir() {
23727         local mdt_index=$1
23728         local stripe_count
23729         local stripe_index
23730
23731         mkdir -p $DIR/$tdir
23732
23733         SAVE_UMASK=$(umask)
23734         trap cleanup_test_300 RETURN EXIT
23735
23736         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23737                                                 $DIR/$tdir/striped_dir ||
23738                 error "set striped dir error"
23739
23740         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23741         [ "$mode" = "755" ] || error "expect 755 got $mode"
23742
23743         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23744                 error "getdirstripe failed"
23745         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23746         if [ "$stripe_count" != "2" ]; then
23747                 error "1:stripe_count is $stripe_count, expect 2"
23748         fi
23749         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23750         if [ "$stripe_count" != "2" ]; then
23751                 error "2:stripe_count is $stripe_count, expect 2"
23752         fi
23753
23754         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23755         if [ "$stripe_index" != "$mdt_index" ]; then
23756                 error "stripe_index is $stripe_index, expect $mdt_index"
23757         fi
23758
23759         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23760                 error "nlink error after create striped dir"
23761
23762         mkdir $DIR/$tdir/striped_dir/a
23763         mkdir $DIR/$tdir/striped_dir/b
23764
23765         stat $DIR/$tdir/striped_dir/a ||
23766                 error "create dir under striped dir failed"
23767         stat $DIR/$tdir/striped_dir/b ||
23768                 error "create dir under striped dir failed"
23769
23770         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23771                 error "nlink error after mkdir"
23772
23773         rmdir $DIR/$tdir/striped_dir/a
23774         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23775                 error "nlink error after rmdir"
23776
23777         rmdir $DIR/$tdir/striped_dir/b
23778         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23779                 error "nlink error after rmdir"
23780
23781         chattr +i $DIR/$tdir/striped_dir
23782         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23783                 error "immutable flags not working under striped dir!"
23784         chattr -i $DIR/$tdir/striped_dir
23785
23786         rmdir $DIR/$tdir/striped_dir ||
23787                 error "rmdir striped dir error"
23788
23789         cleanup_test_300
23790
23791         true
23792 }
23793
23794 test_300a() {
23795         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23796                 skip "skipped for lustre < 2.7.0"
23797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23799
23800         test_striped_dir 0 || error "failed on striped dir on MDT0"
23801         test_striped_dir 1 || error "failed on striped dir on MDT0"
23802 }
23803 run_test 300a "basic striped dir sanity test"
23804
23805 test_300b() {
23806         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23807                 skip "skipped for lustre < 2.7.0"
23808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23810
23811         local i
23812         local mtime1
23813         local mtime2
23814         local mtime3
23815
23816         test_mkdir $DIR/$tdir || error "mkdir fail"
23817         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23818                 error "set striped dir error"
23819         for i in {0..9}; do
23820                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23821                 sleep 1
23822                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23823                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23824                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23825                 sleep 1
23826                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23827                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23828                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23829         done
23830         true
23831 }
23832 run_test 300b "check ctime/mtime for striped dir"
23833
23834 test_300c() {
23835         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23836                 skip "skipped for lustre < 2.7.0"
23837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23838         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23839
23840         local file_count
23841
23842         mkdir_on_mdt0 $DIR/$tdir
23843         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23844                 error "set striped dir error"
23845
23846         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23847                 error "chown striped dir failed"
23848
23849         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23850                 error "create 5k files failed"
23851
23852         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23853
23854         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23855
23856         rm -rf $DIR/$tdir
23857 }
23858 run_test 300c "chown && check ls under striped directory"
23859
23860 test_300d() {
23861         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23862                 skip "skipped for lustre < 2.7.0"
23863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23864         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23865
23866         local stripe_count
23867         local file
23868
23869         mkdir -p $DIR/$tdir
23870         $LFS setstripe -c 2 $DIR/$tdir
23871
23872         #local striped directory
23873         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23874                 error "set striped dir error"
23875         #look at the directories for debug purposes
23876         ls -l $DIR/$tdir
23877         $LFS getdirstripe $DIR/$tdir
23878         ls -l $DIR/$tdir/striped_dir
23879         $LFS getdirstripe $DIR/$tdir/striped_dir
23880         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23881                 error "create 10 files failed"
23882
23883         #remote striped directory
23884         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23885                 error "set striped dir error"
23886         #look at the directories for debug purposes
23887         ls -l $DIR/$tdir
23888         $LFS getdirstripe $DIR/$tdir
23889         ls -l $DIR/$tdir/remote_striped_dir
23890         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23891         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23892                 error "create 10 files failed"
23893
23894         for file in $(find $DIR/$tdir); do
23895                 stripe_count=$($LFS getstripe -c $file)
23896                 [ $stripe_count -eq 2 ] ||
23897                         error "wrong stripe $stripe_count for $file"
23898         done
23899
23900         rm -rf $DIR/$tdir
23901 }
23902 run_test 300d "check default stripe under striped directory"
23903
23904 test_300e() {
23905         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23906                 skip "Need MDS version at least 2.7.55"
23907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23909
23910         local stripe_count
23911         local file
23912
23913         mkdir -p $DIR/$tdir
23914
23915         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23916                 error "set striped dir error"
23917
23918         touch $DIR/$tdir/striped_dir/a
23919         touch $DIR/$tdir/striped_dir/b
23920         touch $DIR/$tdir/striped_dir/c
23921
23922         mkdir $DIR/$tdir/striped_dir/dir_a
23923         mkdir $DIR/$tdir/striped_dir/dir_b
23924         mkdir $DIR/$tdir/striped_dir/dir_c
23925
23926         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23927                 error "set striped adir under striped dir error"
23928
23929         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23930                 error "set striped bdir under striped dir error"
23931
23932         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23933                 error "set striped cdir under striped dir error"
23934
23935         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23936                 error "rename dir under striped dir fails"
23937
23938         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23939                 error "rename dir under different stripes fails"
23940
23941         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23942                 error "rename file under striped dir should succeed"
23943
23944         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23945                 error "rename dir under striped dir should succeed"
23946
23947         rm -rf $DIR/$tdir
23948 }
23949 run_test 300e "check rename under striped directory"
23950
23951 test_300f() {
23952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23954         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23955                 skip "Need MDS version at least 2.7.55"
23956
23957         local stripe_count
23958         local file
23959
23960         rm -rf $DIR/$tdir
23961         mkdir -p $DIR/$tdir
23962
23963         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23964                 error "set striped dir error"
23965
23966         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23967                 error "set striped dir error"
23968
23969         touch $DIR/$tdir/striped_dir/a
23970         mkdir $DIR/$tdir/striped_dir/dir_a
23971         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23972                 error "create striped dir under striped dir fails"
23973
23974         touch $DIR/$tdir/striped_dir1/b
23975         mkdir $DIR/$tdir/striped_dir1/dir_b
23976         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23977                 error "create striped dir under striped dir fails"
23978
23979         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23980                 error "rename dir under different striped dir should fail"
23981
23982         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23983                 error "rename striped dir under diff striped dir should fail"
23984
23985         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23986                 error "rename file under diff striped dirs fails"
23987
23988         rm -rf $DIR/$tdir
23989 }
23990 run_test 300f "check rename cross striped directory"
23991
23992 test_300_check_default_striped_dir()
23993 {
23994         local dirname=$1
23995         local default_count=$2
23996         local default_index=$3
23997         local stripe_count
23998         local stripe_index
23999         local dir_stripe_index
24000         local dir
24001
24002         echo "checking $dirname $default_count $default_index"
24003         $LFS setdirstripe -D -c $default_count -i $default_index \
24004                                 -H all_char $DIR/$tdir/$dirname ||
24005                 error "set default stripe on striped dir error"
24006         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24007         [ $stripe_count -eq $default_count ] ||
24008                 error "expect $default_count get $stripe_count for $dirname"
24009
24010         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24011         [ $stripe_index -eq $default_index ] ||
24012                 error "expect $default_index get $stripe_index for $dirname"
24013
24014         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24015                                                 error "create dirs failed"
24016
24017         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24018         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24019         for dir in $(find $DIR/$tdir/$dirname/*); do
24020                 stripe_count=$($LFS getdirstripe -c $dir)
24021                 (( $stripe_count == $default_count )) ||
24022                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24023                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24024                 error "stripe count $default_count != $stripe_count for $dir"
24025
24026                 stripe_index=$($LFS getdirstripe -i $dir)
24027                 [ $default_index -eq -1 ] ||
24028                         [ $stripe_index -eq $default_index ] ||
24029                         error "$stripe_index != $default_index for $dir"
24030
24031                 #check default stripe
24032                 stripe_count=$($LFS getdirstripe -D -c $dir)
24033                 [ $stripe_count -eq $default_count ] ||
24034                 error "default count $default_count != $stripe_count for $dir"
24035
24036                 stripe_index=$($LFS getdirstripe -D -i $dir)
24037                 [ $stripe_index -eq $default_index ] ||
24038                 error "default index $default_index != $stripe_index for $dir"
24039         done
24040         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24041 }
24042
24043 test_300g() {
24044         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24045         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24046                 skip "Need MDS version at least 2.7.55"
24047
24048         local dir
24049         local stripe_count
24050         local stripe_index
24051
24052         mkdir_on_mdt0 $DIR/$tdir
24053         mkdir $DIR/$tdir/normal_dir
24054
24055         #Checking when client cache stripe index
24056         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24057         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24058                 error "create striped_dir failed"
24059
24060         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24061                 error "create dir0 fails"
24062         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24063         [ $stripe_index -eq 0 ] ||
24064                 error "dir0 expect index 0 got $stripe_index"
24065
24066         mkdir $DIR/$tdir/striped_dir/dir1 ||
24067                 error "create dir1 fails"
24068         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24069         [ $stripe_index -eq 1 ] ||
24070                 error "dir1 expect index 1 got $stripe_index"
24071
24072         #check default stripe count/stripe index
24073         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24074         test_300_check_default_striped_dir normal_dir 1 0
24075         test_300_check_default_striped_dir normal_dir -1 1
24076         test_300_check_default_striped_dir normal_dir 2 -1
24077
24078         #delete default stripe information
24079         echo "delete default stripeEA"
24080         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24081                 error "set default stripe on striped dir error"
24082
24083         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24084         for dir in $(find $DIR/$tdir/normal_dir/*); do
24085                 stripe_count=$($LFS getdirstripe -c $dir)
24086                 [ $stripe_count -eq 0 ] ||
24087                         error "expect 1 get $stripe_count for $dir"
24088         done
24089 }
24090 run_test 300g "check default striped directory for normal directory"
24091
24092 test_300h() {
24093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24094         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24095                 skip "Need MDS version at least 2.7.55"
24096
24097         local dir
24098         local stripe_count
24099
24100         mkdir $DIR/$tdir
24101         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24102                 error "set striped dir error"
24103
24104         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24105         test_300_check_default_striped_dir striped_dir 1 0
24106         test_300_check_default_striped_dir striped_dir -1 1
24107         test_300_check_default_striped_dir striped_dir 2 -1
24108
24109         #delete default stripe information
24110         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24111                 error "set default stripe on striped dir error"
24112
24113         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24114         for dir in $(find $DIR/$tdir/striped_dir/*); do
24115                 stripe_count=$($LFS getdirstripe -c $dir)
24116                 [ $stripe_count -eq 0 ] ||
24117                         error "expect 1 get $stripe_count for $dir"
24118         done
24119 }
24120 run_test 300h "check default striped directory for striped directory"
24121
24122 test_300i() {
24123         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24124         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24125         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24126                 skip "Need MDS version at least 2.7.55"
24127
24128         local stripe_count
24129         local file
24130
24131         mkdir $DIR/$tdir
24132
24133         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24134                 error "set striped dir error"
24135
24136         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24137                 error "create files under striped dir failed"
24138
24139         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24140                 error "set striped hashdir error"
24141
24142         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24143                 error "create dir0 under hash dir failed"
24144         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24145                 error "create dir1 under hash dir failed"
24146         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24147                 error "create dir2 under hash dir failed"
24148
24149         # unfortunately, we need to umount to clear dir layout cache for now
24150         # once we fully implement dir layout, we can drop this
24151         umount_client $MOUNT || error "umount failed"
24152         mount_client $MOUNT || error "mount failed"
24153
24154         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24155         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24156         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24157
24158         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24159                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24160                         error "create crush2 dir $tdir/hashdir/d3 failed"
24161                 $LFS find -H crush2 $DIR/$tdir/hashdir
24162                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24163                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24164
24165                 # mkdir with an invalid hash type (hash=fail_val) from client
24166                 # should be replaced on MDS with a valid (default) hash type
24167                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24168                 $LCTL set_param fail_loc=0x1901 fail_val=99
24169                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24170
24171                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24172                 local expect=$(do_facet mds1 \
24173                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24174                 [[ $hash == $expect ]] ||
24175                         error "d99 hash '$hash' != expected hash '$expect'"
24176         fi
24177
24178         #set the stripe to be unknown hash type on read
24179         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24180         $LCTL set_param fail_loc=0x1901 fail_val=99
24181         for ((i = 0; i < 10; i++)); do
24182                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24183                         error "stat f-$i failed"
24184                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24185         done
24186
24187         touch $DIR/$tdir/striped_dir/f0 &&
24188                 error "create under striped dir with unknown hash should fail"
24189
24190         $LCTL set_param fail_loc=0
24191
24192         umount_client $MOUNT || error "umount failed"
24193         mount_client $MOUNT || error "mount failed"
24194
24195         return 0
24196 }
24197 run_test 300i "client handle unknown hash type striped directory"
24198
24199 test_300j() {
24200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24202         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24203                 skip "Need MDS version at least 2.7.55"
24204
24205         local stripe_count
24206         local file
24207
24208         mkdir $DIR/$tdir
24209
24210         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24211         $LCTL set_param fail_loc=0x1702
24212         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24213                 error "set striped dir error"
24214
24215         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24216                 error "create files under striped dir failed"
24217
24218         $LCTL set_param fail_loc=0
24219
24220         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24221
24222         return 0
24223 }
24224 run_test 300j "test large update record"
24225
24226 test_300k() {
24227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24229         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24230                 skip "Need MDS version at least 2.7.55"
24231
24232         # this test needs a huge transaction
24233         local kb
24234         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24235              osd*.$FSNAME-MDT0000.kbytestotal")
24236         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24237
24238         local stripe_count
24239         local file
24240
24241         mkdir $DIR/$tdir
24242
24243         #define OBD_FAIL_LARGE_STRIPE   0x1703
24244         $LCTL set_param fail_loc=0x1703
24245         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24246                 error "set striped dir error"
24247         $LCTL set_param fail_loc=0
24248
24249         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24250                 error "getstripeddir fails"
24251         rm -rf $DIR/$tdir/striped_dir ||
24252                 error "unlink striped dir fails"
24253
24254         return 0
24255 }
24256 run_test 300k "test large striped directory"
24257
24258 test_300l() {
24259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24261         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24262                 skip "Need MDS version at least 2.7.55"
24263
24264         local stripe_index
24265
24266         test_mkdir -p $DIR/$tdir/striped_dir
24267         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24268                         error "chown $RUNAS_ID failed"
24269         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24270                 error "set default striped dir failed"
24271
24272         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24273         $LCTL set_param fail_loc=0x80000158
24274         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24275
24276         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24277         [ $stripe_index -eq 1 ] ||
24278                 error "expect 1 get $stripe_index for $dir"
24279 }
24280 run_test 300l "non-root user to create dir under striped dir with stale layout"
24281
24282 test_300m() {
24283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24284         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24285         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24286                 skip "Need MDS version at least 2.7.55"
24287
24288         mkdir -p $DIR/$tdir/striped_dir
24289         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24290                 error "set default stripes dir error"
24291
24292         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24293
24294         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24295         [ $stripe_count -eq 0 ] ||
24296                         error "expect 0 get $stripe_count for a"
24297
24298         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24299                 error "set default stripes dir error"
24300
24301         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24302
24303         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24304         [ $stripe_count -eq 0 ] ||
24305                         error "expect 0 get $stripe_count for b"
24306
24307         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24308                 error "set default stripes dir error"
24309
24310         mkdir $DIR/$tdir/striped_dir/c &&
24311                 error "default stripe_index is invalid, mkdir c should fails"
24312
24313         rm -rf $DIR/$tdir || error "rmdir fails"
24314 }
24315 run_test 300m "setstriped directory on single MDT FS"
24316
24317 cleanup_300n() {
24318         local list=$(comma_list $(mdts_nodes))
24319
24320         trap 0
24321         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24322 }
24323
24324 test_300n() {
24325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24327         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24328                 skip "Need MDS version at least 2.7.55"
24329         remote_mds_nodsh && skip "remote MDS with nodsh"
24330
24331         local stripe_index
24332         local list=$(comma_list $(mdts_nodes))
24333
24334         trap cleanup_300n RETURN EXIT
24335         mkdir -p $DIR/$tdir
24336         chmod 777 $DIR/$tdir
24337         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24338                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24339                 error "create striped dir succeeds with gid=0"
24340
24341         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24342         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24343                 error "create striped dir fails with gid=-1"
24344
24345         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24346         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24347                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24348                 error "set default striped dir succeeds with gid=0"
24349
24350
24351         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24352         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24353                 error "set default striped dir fails with gid=-1"
24354
24355
24356         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24357         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24358                                         error "create test_dir fails"
24359         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24360                                         error "create test_dir1 fails"
24361         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24362                                         error "create test_dir2 fails"
24363         cleanup_300n
24364 }
24365 run_test 300n "non-root user to create dir under striped dir with default EA"
24366
24367 test_300o() {
24368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24370         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24371                 skip "Need MDS version at least 2.7.55"
24372
24373         local numfree1
24374         local numfree2
24375
24376         mkdir -p $DIR/$tdir
24377
24378         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24379         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24380         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24381                 skip "not enough free inodes $numfree1 $numfree2"
24382         fi
24383
24384         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24385         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24386         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24387                 skip "not enough free space $numfree1 $numfree2"
24388         fi
24389
24390         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24391                 error "setdirstripe fails"
24392
24393         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24394                 error "create dirs fails"
24395
24396         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24397         ls $DIR/$tdir/striped_dir > /dev/null ||
24398                 error "ls striped dir fails"
24399         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24400                 error "unlink big striped dir fails"
24401 }
24402 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24403
24404 test_300p() {
24405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24407         remote_mds_nodsh && skip "remote MDS with nodsh"
24408
24409         mkdir_on_mdt0 $DIR/$tdir
24410
24411         #define OBD_FAIL_OUT_ENOSPC     0x1704
24412         do_facet mds2 lctl set_param fail_loc=0x80001704
24413         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24414                  && error "create striped directory should fail"
24415
24416         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24417
24418         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24419         true
24420 }
24421 run_test 300p "create striped directory without space"
24422
24423 test_300q() {
24424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24425         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24426
24427         local fd=$(free_fd)
24428         local cmd="exec $fd<$tdir"
24429         cd $DIR
24430         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24431         eval $cmd
24432         cmd="exec $fd<&-"
24433         trap "eval $cmd" EXIT
24434         cd $tdir || error "cd $tdir fails"
24435         rmdir  ../$tdir || error "rmdir $tdir fails"
24436         mkdir local_dir && error "create dir succeeds"
24437         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24438         eval $cmd
24439         return 0
24440 }
24441 run_test 300q "create remote directory under orphan directory"
24442
24443 test_300r() {
24444         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24445                 skip "Need MDS version at least 2.7.55" && return
24446         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24447
24448         mkdir $DIR/$tdir
24449
24450         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24451                 error "set striped dir error"
24452
24453         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24454                 error "getstripeddir fails"
24455
24456         local stripe_count
24457         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24458                       awk '/lmv_stripe_count:/ { print $2 }')
24459
24460         [ $MDSCOUNT -ne $stripe_count ] &&
24461                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24462
24463         rm -rf $DIR/$tdir/striped_dir ||
24464                 error "unlink striped dir fails"
24465 }
24466 run_test 300r "test -1 striped directory"
24467
24468 test_300s_helper() {
24469         local count=$1
24470
24471         local stripe_dir=$DIR/$tdir/striped_dir.$count
24472
24473         $LFS mkdir -c $count $stripe_dir ||
24474                 error "lfs mkdir -c error"
24475
24476         $LFS getdirstripe $stripe_dir ||
24477                 error "lfs getdirstripe fails"
24478
24479         local stripe_count
24480         stripe_count=$($LFS getdirstripe $stripe_dir |
24481                       awk '/lmv_stripe_count:/ { print $2 }')
24482
24483         [ $count -ne $stripe_count ] &&
24484                 error_noexit "bad stripe count $stripe_count expected $count"
24485
24486         local dupe_stripes
24487         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24488                 awk '/0x/ {count[$1] += 1}; END {
24489                         for (idx in count) {
24490                                 if (count[idx]>1) {
24491                                         print "index " idx " count " count[idx]
24492                                 }
24493                         }
24494                 }')
24495
24496         if [[ -n "$dupe_stripes" ]] ; then
24497                 lfs getdirstripe $stripe_dir
24498                 error_noexit "Dupe MDT above: $dupe_stripes "
24499         fi
24500
24501         rm -rf $stripe_dir ||
24502                 error_noexit "unlink $stripe_dir fails"
24503 }
24504
24505 test_300s() {
24506         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24507                 skip "Need MDS version at least 2.7.55" && return
24508         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24509
24510         mkdir $DIR/$tdir
24511         for count in $(seq 2 $MDSCOUNT); do
24512                 test_300s_helper $count
24513         done
24514 }
24515 run_test 300s "test lfs mkdir -c without -i"
24516
24517 test_300t() {
24518         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24519                 skip "need MDS 2.14.55 or later"
24520         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24521
24522         local testdir="$DIR/$tdir/striped_dir"
24523         local dir1=$testdir/dir1
24524         local dir2=$testdir/dir2
24525
24526         mkdir -p $testdir
24527
24528         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24529                 error "failed to set default stripe count for $testdir"
24530
24531         mkdir $dir1
24532         local stripe_count=$($LFS getdirstripe -c $dir1)
24533
24534         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24535
24536         local max_count=$((MDSCOUNT - 1))
24537         local mdts=$(comma_list $(mdts_nodes))
24538
24539         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24540         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24541
24542         mkdir $dir2
24543         stripe_count=$($LFS getdirstripe -c $dir2)
24544
24545         (( $stripe_count == $max_count )) || error "wrong stripe count"
24546 }
24547 run_test 300t "test max_mdt_stripecount"
24548
24549 prepare_remote_file() {
24550         mkdir $DIR/$tdir/src_dir ||
24551                 error "create remote source failed"
24552
24553         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24554                  error "cp to remote source failed"
24555         touch $DIR/$tdir/src_dir/a
24556
24557         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24558                 error "create remote target dir failed"
24559
24560         touch $DIR/$tdir/tgt_dir/b
24561
24562         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24563                 error "rename dir cross MDT failed!"
24564
24565         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24566                 error "src_child still exists after rename"
24567
24568         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24569                 error "missing file(a) after rename"
24570
24571         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24572                 error "diff after rename"
24573 }
24574
24575 test_310a() {
24576         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24578
24579         local remote_file=$DIR/$tdir/tgt_dir/b
24580
24581         mkdir -p $DIR/$tdir
24582
24583         prepare_remote_file || error "prepare remote file failed"
24584
24585         #open-unlink file
24586         $OPENUNLINK $remote_file $remote_file ||
24587                 error "openunlink $remote_file failed"
24588         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24589 }
24590 run_test 310a "open unlink remote file"
24591
24592 test_310b() {
24593         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24595
24596         local remote_file=$DIR/$tdir/tgt_dir/b
24597
24598         mkdir -p $DIR/$tdir
24599
24600         prepare_remote_file || error "prepare remote file failed"
24601
24602         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24603         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24604         $CHECKSTAT -t file $remote_file || error "check file failed"
24605 }
24606 run_test 310b "unlink remote file with multiple links while open"
24607
24608 test_310c() {
24609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24610         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24611
24612         local remote_file=$DIR/$tdir/tgt_dir/b
24613
24614         mkdir -p $DIR/$tdir
24615
24616         prepare_remote_file || error "prepare remote file failed"
24617
24618         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24619         multiop_bg_pause $remote_file O_uc ||
24620                         error "mulitop failed for remote file"
24621         MULTIPID=$!
24622         $MULTIOP $DIR/$tfile Ouc
24623         kill -USR1 $MULTIPID
24624         wait $MULTIPID
24625 }
24626 run_test 310c "open-unlink remote file with multiple links"
24627
24628 #LU-4825
24629 test_311() {
24630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24631         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24632         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24633                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24634         remote_mds_nodsh && skip "remote MDS with nodsh"
24635
24636         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24637         local mdts=$(comma_list $(mdts_nodes))
24638
24639         mkdir -p $DIR/$tdir
24640         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24641         createmany -o $DIR/$tdir/$tfile. 1000
24642
24643         # statfs data is not real time, let's just calculate it
24644         old_iused=$((old_iused + 1000))
24645
24646         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24647                         osp.*OST0000*MDT0000.create_count")
24648         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24649                                 osp.*OST0000*MDT0000.max_create_count")
24650         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24651
24652         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24653         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24654         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24655
24656         unlinkmany $DIR/$tdir/$tfile. 1000
24657
24658         do_nodes $mdts "$LCTL set_param -n \
24659                         osp.*OST0000*.max_create_count=$max_count"
24660         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24661                 do_nodes $mdts "$LCTL set_param -n \
24662                                 osp.*OST0000*.create_count=$count"
24663         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24664                         grep "=0" && error "create_count is zero"
24665
24666         local new_iused
24667         for i in $(seq 120); do
24668                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24669                 # system may be too busy to destroy all objs in time, use
24670                 # a somewhat small value to not fail autotest
24671                 [ $((old_iused - new_iused)) -gt 400 ] && break
24672                 sleep 1
24673         done
24674
24675         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24676         [ $((old_iused - new_iused)) -gt 400 ] ||
24677                 error "objs not destroyed after unlink"
24678 }
24679 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24680
24681 zfs_oid_to_objid()
24682 {
24683         local ost=$1
24684         local objid=$2
24685
24686         local vdevdir=$(dirname $(facet_vdevice $ost))
24687         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24688         local zfs_zapid=$(do_facet $ost $cmd |
24689                           grep -w "/O/0/d$((objid%32))" -C 5 |
24690                           awk '/Object/{getline; print $1}')
24691         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24692                           awk "/$objid = /"'{printf $3}')
24693
24694         echo $zfs_objid
24695 }
24696
24697 zfs_object_blksz() {
24698         local ost=$1
24699         local objid=$2
24700
24701         local vdevdir=$(dirname $(facet_vdevice $ost))
24702         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24703         local blksz=$(do_facet $ost $cmd $objid |
24704                       awk '/dblk/{getline; printf $4}')
24705
24706         case "${blksz: -1}" in
24707                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24708                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24709                 *) ;;
24710         esac
24711
24712         echo $blksz
24713 }
24714
24715 test_312() { # LU-4856
24716         remote_ost_nodsh && skip "remote OST with nodsh"
24717         [ "$ost1_FSTYPE" = "zfs" ] ||
24718                 skip_env "the test only applies to zfs"
24719
24720         local max_blksz=$(do_facet ost1 \
24721                           $ZFS get -p recordsize $(facet_device ost1) |
24722                           awk '!/VALUE/{print $3}')
24723
24724         # to make life a little bit easier
24725         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24726         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24727
24728         local tf=$DIR/$tdir/$tfile
24729         touch $tf
24730         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24731
24732         # Get ZFS object id
24733         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24734         # block size change by sequential overwrite
24735         local bs
24736
24737         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24738                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24739
24740                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24741                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24742         done
24743         rm -f $tf
24744
24745         # block size change by sequential append write
24746         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24747         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24748         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24749         local count
24750
24751         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24752                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24753                         oflag=sync conv=notrunc
24754
24755                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24756                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24757                         error "blksz error, actual $blksz, " \
24758                                 "expected: 2 * $count * $PAGE_SIZE"
24759         done
24760         rm -f $tf
24761
24762         # random write
24763         touch $tf
24764         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24765         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24766
24767         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24768         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24769         [ $blksz -eq $PAGE_SIZE ] ||
24770                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24771
24772         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24773         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24774         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24775
24776         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24777         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24778         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24779 }
24780 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24781
24782 test_313() {
24783         remote_ost_nodsh && skip "remote OST with nodsh"
24784
24785         local file=$DIR/$tfile
24786
24787         rm -f $file
24788         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24789
24790         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24791         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24792         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24793                 error "write should failed"
24794         do_facet ost1 "$LCTL set_param fail_loc=0"
24795         rm -f $file
24796 }
24797 run_test 313 "io should fail after last_rcvd update fail"
24798
24799 test_314() {
24800         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24801
24802         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24803         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24804         rm -f $DIR/$tfile
24805         wait_delete_completed
24806         do_facet ost1 "$LCTL set_param fail_loc=0"
24807 }
24808 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24809
24810 test_315() { # LU-618
24811         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24812
24813         local file=$DIR/$tfile
24814         rm -f $file
24815
24816         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24817                 error "multiop file write failed"
24818         $MULTIOP $file oO_RDONLY:r4063232_c &
24819         PID=$!
24820
24821         sleep 2
24822
24823         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24824         kill -USR1 $PID
24825
24826         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24827         rm -f $file
24828 }
24829 run_test 315 "read should be accounted"
24830
24831 test_316() {
24832         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24833         large_xattr_enabled || skip "ea_inode feature disabled"
24834
24835         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24836         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24837         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24838         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24839
24840         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24841 }
24842 run_test 316 "lfs migrate of file with large_xattr enabled"
24843
24844 test_317() {
24845         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24846                 skip "Need MDS version at least 2.11.53"
24847         if [ "$ost1_FSTYPE" == "zfs" ]; then
24848                 skip "LU-10370: no implementation for ZFS"
24849         fi
24850
24851         local trunc_sz
24852         local grant_blk_size
24853
24854         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24855                         awk '/grant_block_size:/ { print $2; exit; }')
24856         #
24857         # Create File of size 5M. Truncate it to below size's and verify
24858         # blocks count.
24859         #
24860         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24861                 error "Create file $DIR/$tfile failed"
24862         stack_trap "rm -f $DIR/$tfile" EXIT
24863
24864         for trunc_sz in 2097152 4097 4000 509 0; do
24865                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24866                         error "truncate $tfile to $trunc_sz failed"
24867                 local sz=$(stat --format=%s $DIR/$tfile)
24868                 local blk=$(stat --format=%b $DIR/$tfile)
24869                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24870                                      grant_blk_size) * 8))
24871
24872                 if [[ $blk -ne $trunc_blk ]]; then
24873                         $(which stat) $DIR/$tfile
24874                         error "Expected Block $trunc_blk got $blk for $tfile"
24875                 fi
24876
24877                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24878                         error "Expected Size $trunc_sz got $sz for $tfile"
24879         done
24880
24881         #
24882         # sparse file test
24883         # Create file with a hole and write actual 65536 bytes which aligned
24884         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24885         #
24886         local bs=65536
24887         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24888                 error "Create file : $DIR/$tfile"
24889
24890         #
24891         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24892         # blocks. The block count must drop to 8.
24893         #
24894         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24895                 ((bs - grant_blk_size) + 1)))
24896         $TRUNCATE $DIR/$tfile $trunc_sz ||
24897                 error "truncate $tfile to $trunc_sz failed"
24898
24899         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24900         sz=$(stat --format=%s $DIR/$tfile)
24901         blk=$(stat --format=%b $DIR/$tfile)
24902
24903         if [[ $blk -ne $trunc_bsz ]]; then
24904                 $(which stat) $DIR/$tfile
24905                 error "Expected Block $trunc_bsz got $blk for $tfile"
24906         fi
24907
24908         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24909                 error "Expected Size $trunc_sz got $sz for $tfile"
24910 }
24911 run_test 317 "Verify blocks get correctly update after truncate"
24912
24913 test_318() {
24914         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24915         local old_max_active=$($LCTL get_param -n \
24916                             ${llite_name}.max_read_ahead_async_active \
24917                             2>/dev/null)
24918
24919         $LCTL set_param llite.*.max_read_ahead_async_active=256
24920         local max_active=$($LCTL get_param -n \
24921                            ${llite_name}.max_read_ahead_async_active \
24922                            2>/dev/null)
24923         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24924
24925         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24926                 error "set max_read_ahead_async_active should succeed"
24927
24928         $LCTL set_param llite.*.max_read_ahead_async_active=512
24929         max_active=$($LCTL get_param -n \
24930                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24931         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24932
24933         # restore @max_active
24934         [ $old_max_active -ne 0 ] && $LCTL set_param \
24935                 llite.*.max_read_ahead_async_active=$old_max_active
24936
24937         local old_threshold=$($LCTL get_param -n \
24938                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24939         local max_per_file_mb=$($LCTL get_param -n \
24940                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24941
24942         local invalid=$(($max_per_file_mb + 1))
24943         $LCTL set_param \
24944                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24945                         && error "set $invalid should fail"
24946
24947         local valid=$(($invalid - 1))
24948         $LCTL set_param \
24949                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24950                         error "set $valid should succeed"
24951         local threshold=$($LCTL get_param -n \
24952                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24953         [ $threshold -eq $valid ] || error \
24954                 "expect threshold $valid got $threshold"
24955         $LCTL set_param \
24956                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24957 }
24958 run_test 318 "Verify async readahead tunables"
24959
24960 test_319() {
24961         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24962
24963         local before=$(date +%s)
24964         local evict
24965         local mdir=$DIR/$tdir
24966         local file=$mdir/xxx
24967
24968         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24969         touch $file
24970
24971 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24972         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24973         $LFS migrate -m1 $mdir &
24974
24975         sleep 1
24976         dd if=$file of=/dev/null
24977         wait
24978         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24979           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24980
24981         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24982 }
24983 run_test 319 "lost lease lock on migrate error"
24984
24985 test_398a() { # LU-4198
24986         local ost1_imp=$(get_osc_import_name client ost1)
24987         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24988                          cut -d'.' -f2)
24989
24990         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24991         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24992
24993         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24994         # request a new lock on client
24995         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24996
24997         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24998         #local lock_count=$($LCTL get_param -n \
24999         #                  ldlm.namespaces.$imp_name.lru_size)
25000         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25001
25002         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25003
25004         # no lock cached, should use lockless DIO and not enqueue new lock
25005         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25006                 conv=notrunc ||
25007                 error "dio write failed"
25008         lock_count=$($LCTL get_param -n \
25009                      ldlm.namespaces.$imp_name.lru_size)
25010         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25011
25012         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25013
25014         # no lock cached, should use locked DIO append
25015         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25016                 conv=notrunc || error "DIO append failed"
25017         lock_count=$($LCTL get_param -n \
25018                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25019         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25020 }
25021 run_test 398a "direct IO should cancel lock otherwise lockless"
25022
25023 test_398b() { # LU-4198
25024         which fio || skip_env "no fio installed"
25025         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25026
25027         local size=48
25028         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25029
25030         local njobs=4
25031         # Single page, multiple pages, stripe size, 4*stripe size
25032         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25033                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25034                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25035                         --numjobs=$njobs --fallocate=none \
25036                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25037                         --filename=$DIR/$tfile &
25038                 bg_pid=$!
25039
25040                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25041                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25042                         --numjobs=$njobs --fallocate=none \
25043                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25044                         --filename=$DIR/$tfile || true
25045                 wait $bg_pid
25046         done
25047
25048         evict=$(do_facet client $LCTL get_param \
25049                 osc.$FSNAME-OST*-osc-*/state |
25050             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25051
25052         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25053                 (do_facet client $LCTL get_param \
25054                         osc.$FSNAME-OST*-osc-*/state;
25055                     error "eviction happened: $evict before:$before")
25056
25057         rm -f $DIR/$tfile
25058 }
25059 run_test 398b "DIO and buffer IO race"
25060
25061 test_398c() { # LU-4198
25062         local ost1_imp=$(get_osc_import_name client ost1)
25063         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25064                          cut -d'.' -f2)
25065
25066         which fio || skip_env "no fio installed"
25067
25068         saved_debug=$($LCTL get_param -n debug)
25069         $LCTL set_param debug=0
25070
25071         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25072         ((size /= 1024)) # by megabytes
25073         ((size /= 2)) # write half of the OST at most
25074         [ $size -gt 40 ] && size=40 #reduce test time anyway
25075
25076         $LFS setstripe -c 1 $DIR/$tfile
25077
25078         # it seems like ldiskfs reserves more space than necessary if the
25079         # writing blocks are not mapped, so it extends the file firstly
25080         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25081         cancel_lru_locks osc
25082
25083         # clear and verify rpc_stats later
25084         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25085
25086         local njobs=4
25087         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25088         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25089                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25090                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25091                 --filename=$DIR/$tfile
25092         [ $? -eq 0 ] || error "fio write error"
25093
25094         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25095                 error "Locks were requested while doing AIO"
25096
25097         # get the percentage of 1-page I/O
25098         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25099                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25100                 awk '{print $7}')
25101         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25102
25103         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25104         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25105                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25106                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25107                 --filename=$DIR/$tfile
25108         [ $? -eq 0 ] || error "fio mixed read write error"
25109
25110         echo "AIO with large block size ${size}M"
25111         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25112                 --numjobs=1 --fallocate=none --ioengine=libaio \
25113                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25114                 --filename=$DIR/$tfile
25115         [ $? -eq 0 ] || error "fio large block size failed"
25116
25117         rm -f $DIR/$tfile
25118         $LCTL set_param debug="$saved_debug"
25119 }
25120 run_test 398c "run fio to test AIO"
25121
25122 test_398d() { #  LU-13846
25123         which aiocp || skip_env "no aiocp installed"
25124         local aio_file=$DIR/$tfile.aio
25125
25126         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25127
25128         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25129         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25130         stack_trap "rm -f $DIR/$tfile $aio_file"
25131
25132         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25133
25134         # make sure we don't crash and fail properly
25135         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25136                 error "aio not aligned with PAGE SIZE should fail"
25137
25138         rm -f $DIR/$tfile $aio_file
25139 }
25140 run_test 398d "run aiocp to verify block size > stripe size"
25141
25142 test_398e() {
25143         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25144         touch $DIR/$tfile.new
25145         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25146 }
25147 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25148
25149 test_398f() { #  LU-14687
25150         which aiocp || skip_env "no aiocp installed"
25151         local aio_file=$DIR/$tfile.aio
25152
25153         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25154
25155         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25156         stack_trap "rm -f $DIR/$tfile $aio_file"
25157
25158         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25159         $LCTL set_param fail_loc=0x1418
25160         # make sure we don't crash and fail properly
25161         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25162                 error "aio with page allocation failure succeeded"
25163         $LCTL set_param fail_loc=0
25164         diff $DIR/$tfile $aio_file
25165         [[ $? != 0 ]] || error "no diff after failed aiocp"
25166 }
25167 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25168
25169 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25170 # stripe and i/o size must be > stripe size
25171 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25172 # single RPC in flight.  This test shows async DIO submission is working by
25173 # showing multiple RPCs in flight.
25174 test_398g() { #  LU-13798
25175         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25176
25177         # We need to do some i/o first to acquire enough grant to put our RPCs
25178         # in flight; otherwise a new connection may not have enough grant
25179         # available
25180         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25181                 error "parallel dio failed"
25182         stack_trap "rm -f $DIR/$tfile"
25183
25184         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25185         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25186         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25187         stack_trap "$LCTL set_param -n $pages_per_rpc"
25188
25189         # Recreate file so it's empty
25190         rm -f $DIR/$tfile
25191         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25192         #Pause rpc completion to guarantee we see multiple rpcs in flight
25193         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25194         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25195         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25196
25197         # Clear rpc stats
25198         $LCTL set_param osc.*.rpc_stats=c
25199
25200         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25201                 error "parallel dio failed"
25202         stack_trap "rm -f $DIR/$tfile"
25203
25204         $LCTL get_param osc.*-OST0000-*.rpc_stats
25205         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25206                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25207                 grep "8:" | awk '{print $8}')
25208         # We look at the "8 rpcs in flight" field, and verify A) it is present
25209         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25210         # as expected for an 8M DIO to a file with 1M stripes.
25211         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25212
25213         # Verify turning off parallel dio works as expected
25214         # Clear rpc stats
25215         $LCTL set_param osc.*.rpc_stats=c
25216         $LCTL set_param llite.*.parallel_dio=0
25217         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25218
25219         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25220                 error "dio with parallel dio disabled failed"
25221
25222         # Ideally, we would see only one RPC in flight here, but there is an
25223         # unavoidable race between i/o completion and RPC in flight counting,
25224         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25225         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25226         # So instead we just verify it's always < 8.
25227         $LCTL get_param osc.*-OST0000-*.rpc_stats
25228         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25229                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25230                 grep '^$' -B1 | grep . | awk '{print $1}')
25231         [ $ret != "8:" ] ||
25232                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25233 }
25234 run_test 398g "verify parallel dio async RPC submission"
25235
25236 test_398h() { #  LU-13798
25237         local dio_file=$DIR/$tfile.dio
25238
25239         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25240
25241         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25242         stack_trap "rm -f $DIR/$tfile $dio_file"
25243
25244         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25245                 error "parallel dio failed"
25246         diff $DIR/$tfile $dio_file
25247         [[ $? == 0 ]] || error "file diff after aiocp"
25248 }
25249 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25250
25251 test_398i() { #  LU-13798
25252         local dio_file=$DIR/$tfile.dio
25253
25254         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25255
25256         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25257         stack_trap "rm -f $DIR/$tfile $dio_file"
25258
25259         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25260         $LCTL set_param fail_loc=0x1418
25261         # make sure we don't crash and fail properly
25262         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25263                 error "parallel dio page allocation failure succeeded"
25264         diff $DIR/$tfile $dio_file
25265         [[ $? != 0 ]] || error "no diff after failed aiocp"
25266 }
25267 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25268
25269 test_398j() { #  LU-13798
25270         # Stripe size > RPC size but less than i/o size tests split across
25271         # stripes and RPCs for individual i/o op
25272         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25273
25274         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25275         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25276         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25277         stack_trap "$LCTL set_param -n $pages_per_rpc"
25278
25279         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25280                 error "parallel dio write failed"
25281         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25282
25283         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25284                 error "parallel dio read failed"
25285         diff $DIR/$tfile $DIR/$tfile.2
25286         [[ $? == 0 ]] || error "file diff after parallel dio read"
25287 }
25288 run_test 398j "test parallel dio where stripe size > rpc_size"
25289
25290 test_398k() { #  LU-13798
25291         wait_delete_completed
25292         wait_mds_ost_sync
25293
25294         # 4 stripe file; we will cause out of space on OST0
25295         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25296
25297         # Fill OST0 (if it's not too large)
25298         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25299                    head -n1)
25300         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25301                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25302         fi
25303         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25304         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25305                 error "dd should fill OST0"
25306         stack_trap "rm -f $DIR/$tfile.1"
25307
25308         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25309         err=$?
25310
25311         ls -la $DIR/$tfile
25312         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25313                 error "file is not 0 bytes in size"
25314
25315         # dd above should not succeed, but don't error until here so we can
25316         # get debug info above
25317         [[ $err != 0 ]] ||
25318                 error "parallel dio write with enospc succeeded"
25319         stack_trap "rm -f $DIR/$tfile"
25320 }
25321 run_test 398k "test enospc on first stripe"
25322
25323 test_398l() { #  LU-13798
25324         wait_delete_completed
25325         wait_mds_ost_sync
25326
25327         # 4 stripe file; we will cause out of space on OST0
25328         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25329         # happens on the second i/o chunk we issue
25330         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25331
25332         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25333         stack_trap "rm -f $DIR/$tfile"
25334
25335         # Fill OST0 (if it's not too large)
25336         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25337                    head -n1)
25338         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25339                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25340         fi
25341         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25342         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25343                 error "dd should fill OST0"
25344         stack_trap "rm -f $DIR/$tfile.1"
25345
25346         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25347         err=$?
25348         stack_trap "rm -f $DIR/$tfile.2"
25349
25350         # Check that short write completed as expected
25351         ls -la $DIR/$tfile.2
25352         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25353                 error "file is not 1M in size"
25354
25355         # dd above should not succeed, but don't error until here so we can
25356         # get debug info above
25357         [[ $err != 0 ]] ||
25358                 error "parallel dio write with enospc succeeded"
25359
25360         # Truncate source file to same length as output file and diff them
25361         $TRUNCATE $DIR/$tfile 1048576
25362         diff $DIR/$tfile $DIR/$tfile.2
25363         [[ $? == 0 ]] || error "data incorrect after short write"
25364 }
25365 run_test 398l "test enospc on intermediate stripe/RPC"
25366
25367 test_398m() { #  LU-13798
25368         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25369
25370         # Set up failure on OST0, the first stripe:
25371         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25372         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25373         # OST0 is on ost1, OST1 is on ost2.
25374         # So this fail_val specifies OST0
25375         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25376         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25377
25378         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25379                 error "parallel dio write with failure on first stripe succeeded"
25380         stack_trap "rm -f $DIR/$tfile"
25381         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25382
25383         # Place data in file for read
25384         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25385                 error "parallel dio write failed"
25386
25387         # Fail read on OST0, first stripe
25388         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25389         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25390         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25391                 error "parallel dio read with error on first stripe succeeded"
25392         rm -f $DIR/$tfile.2
25393         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25394
25395         # Switch to testing on OST1, second stripe
25396         # Clear file contents, maintain striping
25397         echo > $DIR/$tfile
25398         # Set up failure on OST1, second stripe:
25399         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25400         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25401
25402         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25403                 error "parallel dio write with failure on second stripe succeeded"
25404         stack_trap "rm -f $DIR/$tfile"
25405         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25406
25407         # Place data in file for read
25408         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25409                 error "parallel dio write failed"
25410
25411         # Fail read on OST1, second stripe
25412         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25413         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25414         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25415                 error "parallel dio read with error on second stripe succeeded"
25416         rm -f $DIR/$tfile.2
25417         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25418 }
25419 run_test 398m "test RPC failures with parallel dio"
25420
25421 # Parallel submission of DIO should not cause problems for append, but it's
25422 # important to verify.
25423 test_398n() { #  LU-13798
25424         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25425
25426         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25427                 error "dd to create source file failed"
25428         stack_trap "rm -f $DIR/$tfile"
25429
25430         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25431                 error "parallel dio write with failure on second stripe succeeded"
25432         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25433         diff $DIR/$tfile $DIR/$tfile.1
25434         [[ $? == 0 ]] || error "data incorrect after append"
25435
25436 }
25437 run_test 398n "test append with parallel DIO"
25438
25439 test_398o() {
25440         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25441 }
25442 run_test 398o "right kms with DIO"
25443
25444 test_fake_rw() {
25445         local read_write=$1
25446         if [ "$read_write" = "write" ]; then
25447                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25448         elif [ "$read_write" = "read" ]; then
25449                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25450         else
25451                 error "argument error"
25452         fi
25453
25454         # turn off debug for performance testing
25455         local saved_debug=$($LCTL get_param -n debug)
25456         $LCTL set_param debug=0
25457
25458         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25459
25460         # get ost1 size - $FSNAME-OST0000
25461         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25462         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25463         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25464
25465         if [ "$read_write" = "read" ]; then
25466                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25467         fi
25468
25469         local start_time=$(date +%s.%N)
25470         $dd_cmd bs=1M count=$blocks oflag=sync ||
25471                 error "real dd $read_write error"
25472         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25473
25474         if [ "$read_write" = "write" ]; then
25475                 rm -f $DIR/$tfile
25476         fi
25477
25478         # define OBD_FAIL_OST_FAKE_RW           0x238
25479         do_facet ost1 $LCTL set_param fail_loc=0x238
25480
25481         local start_time=$(date +%s.%N)
25482         $dd_cmd bs=1M count=$blocks oflag=sync ||
25483                 error "fake dd $read_write error"
25484         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25485
25486         if [ "$read_write" = "write" ]; then
25487                 # verify file size
25488                 cancel_lru_locks osc
25489                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25490                         error "$tfile size not $blocks MB"
25491         fi
25492         do_facet ost1 $LCTL set_param fail_loc=0
25493
25494         echo "fake $read_write $duration_fake vs. normal $read_write" \
25495                 "$duration in seconds"
25496         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25497                 error_not_in_vm "fake write is slower"
25498
25499         $LCTL set_param -n debug="$saved_debug"
25500         rm -f $DIR/$tfile
25501 }
25502 test_399a() { # LU-7655 for OST fake write
25503         remote_ost_nodsh && skip "remote OST with nodsh"
25504
25505         test_fake_rw write
25506 }
25507 run_test 399a "fake write should not be slower than normal write"
25508
25509 test_399b() { # LU-8726 for OST fake read
25510         remote_ost_nodsh && skip "remote OST with nodsh"
25511         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25512                 skip_env "ldiskfs only test"
25513         fi
25514
25515         test_fake_rw read
25516 }
25517 run_test 399b "fake read should not be slower than normal read"
25518
25519 test_400a() { # LU-1606, was conf-sanity test_74
25520         if ! which $CC > /dev/null 2>&1; then
25521                 skip_env "$CC is not installed"
25522         fi
25523
25524         local extra_flags=''
25525         local out=$TMP/$tfile
25526         local prefix=/usr/include/lustre
25527         local prog
25528
25529         # Oleg removes .c files in his test rig so test if any c files exist
25530         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25531                 skip_env "Needed .c test files are missing"
25532
25533         if ! [[ -d $prefix ]]; then
25534                 # Assume we're running in tree and fixup the include path.
25535                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25536                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25537                 extra_flags+=" -L$LUSTRE/utils/.libs"
25538         fi
25539
25540         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25541                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25542                         error "client api broken"
25543         done
25544         rm -f $out
25545 }
25546 run_test 400a "Lustre client api program can compile and link"
25547
25548 test_400b() { # LU-1606, LU-5011
25549         local header
25550         local out=$TMP/$tfile
25551         local prefix=/usr/include/linux/lustre
25552
25553         # We use a hard coded prefix so that this test will not fail
25554         # when run in tree. There are headers in lustre/include/lustre/
25555         # that are not packaged (like lustre_idl.h) and have more
25556         # complicated include dependencies (like config.h and lnet/types.h).
25557         # Since this test about correct packaging we just skip them when
25558         # they don't exist (see below) rather than try to fixup cppflags.
25559
25560         if ! which $CC > /dev/null 2>&1; then
25561                 skip_env "$CC is not installed"
25562         fi
25563
25564         for header in $prefix/*.h; do
25565                 if ! [[ -f "$header" ]]; then
25566                         continue
25567                 fi
25568
25569                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25570                         continue # lustre_ioctl.h is internal header
25571                 fi
25572
25573                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25574                         error "cannot compile '$header'"
25575         done
25576         rm -f $out
25577 }
25578 run_test 400b "packaged headers can be compiled"
25579
25580 test_401a() { #LU-7437
25581         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25582         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25583
25584         #count the number of parameters by "list_param -R"
25585         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25586         #count the number of parameters by listing proc files
25587         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25588         echo "proc_dirs='$proc_dirs'"
25589         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25590         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25591                       sort -u | wc -l)
25592
25593         [ $params -eq $procs ] ||
25594                 error "found $params parameters vs. $procs proc files"
25595
25596         # test the list_param -D option only returns directories
25597         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25598         #count the number of parameters by listing proc directories
25599         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25600                 sort -u | wc -l)
25601
25602         [ $params -eq $procs ] ||
25603                 error "found $params parameters vs. $procs proc files"
25604 }
25605 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25606
25607 test_401b() {
25608         # jobid_var may not allow arbitrary values, so use jobid_name
25609         # if available
25610         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25611                 local testname=jobid_name tmp='testing%p'
25612         else
25613                 local testname=jobid_var tmp=testing
25614         fi
25615
25616         local save=$($LCTL get_param -n $testname)
25617
25618         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25619                 error "no error returned when setting bad parameters"
25620
25621         local jobid_new=$($LCTL get_param -n foe $testname baz)
25622         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25623
25624         $LCTL set_param -n fog=bam $testname=$save bat=fog
25625         local jobid_old=$($LCTL get_param -n foe $testname bag)
25626         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25627 }
25628 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25629
25630 test_401c() {
25631         # jobid_var may not allow arbitrary values, so use jobid_name
25632         # if available
25633         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25634                 local testname=jobid_name
25635         else
25636                 local testname=jobid_var
25637         fi
25638
25639         local jobid_var_old=$($LCTL get_param -n $testname)
25640         local jobid_var_new
25641
25642         $LCTL set_param $testname= &&
25643                 error "no error returned for 'set_param a='"
25644
25645         jobid_var_new=$($LCTL get_param -n $testname)
25646         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25647                 error "$testname was changed by setting without value"
25648
25649         $LCTL set_param $testname &&
25650                 error "no error returned for 'set_param a'"
25651
25652         jobid_var_new=$($LCTL get_param -n $testname)
25653         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25654                 error "$testname was changed by setting without value"
25655 }
25656 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25657
25658 test_401d() {
25659         # jobid_var may not allow arbitrary values, so use jobid_name
25660         # if available
25661         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25662                 local testname=jobid_name new_value='foo=bar%p'
25663         else
25664                 local testname=jobid_var new_valuie=foo=bar
25665         fi
25666
25667         local jobid_var_old=$($LCTL get_param -n $testname)
25668         local jobid_var_new
25669
25670         $LCTL set_param $testname=$new_value ||
25671                 error "'set_param a=b' did not accept a value containing '='"
25672
25673         jobid_var_new=$($LCTL get_param -n $testname)
25674         [[ "$jobid_var_new" == "$new_value" ]] ||
25675                 error "'set_param a=b' failed on a value containing '='"
25676
25677         # Reset the $testname to test the other format
25678         $LCTL set_param $testname=$jobid_var_old
25679         jobid_var_new=$($LCTL get_param -n $testname)
25680         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25681                 error "failed to reset $testname"
25682
25683         $LCTL set_param $testname $new_value ||
25684                 error "'set_param a b' did not accept a value containing '='"
25685
25686         jobid_var_new=$($LCTL get_param -n $testname)
25687         [[ "$jobid_var_new" == "$new_value" ]] ||
25688                 error "'set_param a b' failed on a value containing '='"
25689
25690         $LCTL set_param $testname $jobid_var_old
25691         jobid_var_new=$($LCTL get_param -n $testname)
25692         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25693                 error "failed to reset $testname"
25694 }
25695 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25696
25697 test_401e() { # LU-14779
25698         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25699                 error "lctl list_param MGC* failed"
25700         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25701         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25702                 error "lctl get_param lru_size failed"
25703 }
25704 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25705
25706 test_402() {
25707         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25708         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25709                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25710         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25711                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25712                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25713         remote_mds_nodsh && skip "remote MDS with nodsh"
25714
25715         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25716 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25717         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25718         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25719                 echo "Touch failed - OK"
25720 }
25721 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25722
25723 test_403() {
25724         local file1=$DIR/$tfile.1
25725         local file2=$DIR/$tfile.2
25726         local tfile=$TMP/$tfile
25727
25728         rm -f $file1 $file2 $tfile
25729
25730         touch $file1
25731         ln $file1 $file2
25732
25733         # 30 sec OBD_TIMEOUT in ll_getattr()
25734         # right before populating st_nlink
25735         $LCTL set_param fail_loc=0x80001409
25736         stat -c %h $file1 > $tfile &
25737
25738         # create an alias, drop all locks and reclaim the dentry
25739         < $file2
25740         cancel_lru_locks mdc
25741         cancel_lru_locks osc
25742         sysctl -w vm.drop_caches=2
25743
25744         wait
25745
25746         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25747
25748         rm -f $tfile $file1 $file2
25749 }
25750 run_test 403 "i_nlink should not drop to zero due to aliasing"
25751
25752 test_404() { # LU-6601
25753         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25754                 skip "Need server version newer than 2.8.52"
25755         remote_mds_nodsh && skip "remote MDS with nodsh"
25756
25757         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25758                 awk '/osp .*-osc-MDT/ { print $4}')
25759
25760         local osp
25761         for osp in $mosps; do
25762                 echo "Deactivate: " $osp
25763                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25764                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25765                         awk -vp=$osp '$4 == p { print $2 }')
25766                 [ $stat = IN ] || {
25767                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25768                         error "deactivate error"
25769                 }
25770                 echo "Activate: " $osp
25771                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25772                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25773                         awk -vp=$osp '$4 == p { print $2 }')
25774                 [ $stat = UP ] || {
25775                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25776                         error "activate error"
25777                 }
25778         done
25779 }
25780 run_test 404 "validate manual {de}activated works properly for OSPs"
25781
25782 test_405() {
25783         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25784         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25785                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25786                         skip "Layout swap lock is not supported"
25787
25788         check_swap_layouts_support
25789         check_swap_layout_no_dom $DIR
25790
25791         test_mkdir $DIR/$tdir
25792         swap_lock_test -d $DIR/$tdir ||
25793                 error "One layout swap locked test failed"
25794 }
25795 run_test 405 "Various layout swap lock tests"
25796
25797 test_406() {
25798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25799         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25800         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25802         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25803                 skip "Need MDS version at least 2.8.50"
25804
25805         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25806         local test_pool=$TESTNAME
25807
25808         pool_add $test_pool || error "pool_add failed"
25809         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25810                 error "pool_add_targets failed"
25811
25812         save_layout_restore_at_exit $MOUNT
25813
25814         # parent set default stripe count only, child will stripe from both
25815         # parent and fs default
25816         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25817                 error "setstripe $MOUNT failed"
25818         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25819         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25820         for i in $(seq 10); do
25821                 local f=$DIR/$tdir/$tfile.$i
25822                 touch $f || error "touch failed"
25823                 local count=$($LFS getstripe -c $f)
25824                 [ $count -eq $OSTCOUNT ] ||
25825                         error "$f stripe count $count != $OSTCOUNT"
25826                 local offset=$($LFS getstripe -i $f)
25827                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25828                 local size=$($LFS getstripe -S $f)
25829                 [ $size -eq $((def_stripe_size * 2)) ] ||
25830                         error "$f stripe size $size != $((def_stripe_size * 2))"
25831                 local pool=$($LFS getstripe -p $f)
25832                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25833         done
25834
25835         # change fs default striping, delete parent default striping, now child
25836         # will stripe from new fs default striping only
25837         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25838                 error "change $MOUNT default stripe failed"
25839         $LFS setstripe -c 0 $DIR/$tdir ||
25840                 error "delete $tdir default stripe failed"
25841         for i in $(seq 11 20); do
25842                 local f=$DIR/$tdir/$tfile.$i
25843                 touch $f || error "touch $f failed"
25844                 local count=$($LFS getstripe -c $f)
25845                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25846                 local offset=$($LFS getstripe -i $f)
25847                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25848                 local size=$($LFS getstripe -S $f)
25849                 [ $size -eq $def_stripe_size ] ||
25850                         error "$f stripe size $size != $def_stripe_size"
25851                 local pool=$($LFS getstripe -p $f)
25852                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25853         done
25854
25855         unlinkmany $DIR/$tdir/$tfile. 1 20
25856
25857         local f=$DIR/$tdir/$tfile
25858         pool_remove_all_targets $test_pool $f
25859         pool_remove $test_pool $f
25860 }
25861 run_test 406 "DNE support fs default striping"
25862
25863 test_407() {
25864         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25865         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25866                 skip "Need MDS version at least 2.8.55"
25867         remote_mds_nodsh && skip "remote MDS with nodsh"
25868
25869         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25870                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25871         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25872                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25873         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25874
25875         #define OBD_FAIL_DT_TXN_STOP    0x2019
25876         for idx in $(seq $MDSCOUNT); do
25877                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25878         done
25879         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25880         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25881                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25882         true
25883 }
25884 run_test 407 "transaction fail should cause operation fail"
25885
25886 test_408() {
25887         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25888
25889         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25890         lctl set_param fail_loc=0x8000040a
25891         # let ll_prepare_partial_page() fail
25892         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25893
25894         rm -f $DIR/$tfile
25895
25896         # create at least 100 unused inodes so that
25897         # shrink_icache_memory(0) should not return 0
25898         touch $DIR/$tfile-{0..100}
25899         rm -f $DIR/$tfile-{0..100}
25900         sync
25901
25902         echo 2 > /proc/sys/vm/drop_caches
25903 }
25904 run_test 408 "drop_caches should not hang due to page leaks"
25905
25906 test_409()
25907 {
25908         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25909
25910         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25911         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25912         touch $DIR/$tdir/guard || error "(2) Fail to create"
25913
25914         local PREFIX=$(str_repeat 'A' 128)
25915         echo "Create 1K hard links start at $(date)"
25916         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25917                 error "(3) Fail to hard link"
25918
25919         echo "Links count should be right although linkEA overflow"
25920         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25921         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25922         [ $linkcount -eq 1001 ] ||
25923                 error "(5) Unexpected hard links count: $linkcount"
25924
25925         echo "List all links start at $(date)"
25926         ls -l $DIR/$tdir/foo > /dev/null ||
25927                 error "(6) Fail to list $DIR/$tdir/foo"
25928
25929         echo "Unlink hard links start at $(date)"
25930         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25931                 error "(7) Fail to unlink"
25932         echo "Unlink hard links finished at $(date)"
25933 }
25934 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25935
25936 test_410()
25937 {
25938         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25939                 skip "Need client version at least 2.9.59"
25940         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25941                 skip "Need MODULES build"
25942
25943         # Create a file, and stat it from the kernel
25944         local testfile=$DIR/$tfile
25945         touch $testfile
25946
25947         local run_id=$RANDOM
25948         local my_ino=$(stat --format "%i" $testfile)
25949
25950         # Try to insert the module. This will always fail as the
25951         # module is designed to not be inserted.
25952         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25953             &> /dev/null
25954
25955         # Anything but success is a test failure
25956         dmesg | grep -q \
25957             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25958             error "no inode match"
25959 }
25960 run_test 410 "Test inode number returned from kernel thread"
25961
25962 cleanup_test411_cgroup() {
25963         trap 0
25964         rmdir "$1"
25965 }
25966
25967 test_411() {
25968         local cg_basedir=/sys/fs/cgroup/memory
25969         # LU-9966
25970         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25971                 skip "no setup for cgroup"
25972
25973         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25974                 error "test file creation failed"
25975         cancel_lru_locks osc
25976
25977         # Create a very small memory cgroup to force a slab allocation error
25978         local cgdir=$cg_basedir/osc_slab_alloc
25979         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25980         trap "cleanup_test411_cgroup $cgdir" EXIT
25981         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25982         echo 1M > $cgdir/memory.limit_in_bytes
25983
25984         # Should not LBUG, just be killed by oom-killer
25985         # dd will return 0 even allocation failure in some environment.
25986         # So don't check return value
25987         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25988         cleanup_test411_cgroup $cgdir
25989
25990         return 0
25991 }
25992 run_test 411 "Slab allocation error with cgroup does not LBUG"
25993
25994 test_412() {
25995         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25996         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25997                 skip "Need server version at least 2.10.55"
25998
25999         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26000                 error "mkdir failed"
26001         $LFS getdirstripe $DIR/$tdir
26002         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26003         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26004                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26005         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26006         [ $stripe_count -eq 2 ] ||
26007                 error "expect 2 get $stripe_count"
26008
26009         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26010
26011         local index
26012         local index2
26013
26014         # subdirs should be on the same MDT as parent
26015         for i in $(seq 0 $((MDSCOUNT - 1))); do
26016                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26017                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26018                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26019                 (( index == i )) || error "mdt$i/sub on MDT$index"
26020         done
26021
26022         # stripe offset -1, ditto
26023         for i in {1..10}; do
26024                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26025                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26026                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26027                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26028                 (( index == index2 )) ||
26029                         error "qos$i on MDT$index, sub on MDT$index2"
26030         done
26031
26032         local testdir=$DIR/$tdir/inherit
26033
26034         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26035         # inherit 2 levels
26036         for i in 1 2; do
26037                 testdir=$testdir/s$i
26038                 mkdir $testdir || error "mkdir $testdir failed"
26039                 index=$($LFS getstripe -m $testdir)
26040                 (( index == 1 )) ||
26041                         error "$testdir on MDT$index"
26042         done
26043
26044         # not inherit any more
26045         testdir=$testdir/s3
26046         mkdir $testdir || error "mkdir $testdir failed"
26047         getfattr -d -m dmv $testdir | grep dmv &&
26048                 error "default LMV set on $testdir" || true
26049 }
26050 run_test 412 "mkdir on specific MDTs"
26051
26052 TEST413_COUNT=${TEST413_COUNT:-200}
26053 generate_uneven_mdts() {
26054         local threshold=$1
26055         local lmv_qos_maxage
26056         local lod_qos_maxage
26057         local ffree
26058         local bavail
26059         local max
26060         local min
26061         local max_index
26062         local min_index
26063         local tmp
26064         local i
26065
26066         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26067         $LCTL set_param lmv.*.qos_maxage=1
26068         stack_trap "$LCTL set_param \
26069                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26070         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26071                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26072         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26073                 lod.*.mdt_qos_maxage=1
26074         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26075                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26076
26077         echo
26078         echo "Check for uneven MDTs: "
26079
26080         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26081         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26082         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26083
26084         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26085         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26086         max_index=0
26087         min_index=0
26088         for ((i = 1; i < ${#ffree[@]}; i++)); do
26089                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26090                 if [ $tmp -gt $max ]; then
26091                         max=$tmp
26092                         max_index=$i
26093                 fi
26094                 if [ $tmp -lt $min ]; then
26095                         min=$tmp
26096                         min_index=$i
26097                 fi
26098         done
26099
26100         (( ${ffree[min_index]} > 0 )) ||
26101                 skip "no free files in MDT$min_index"
26102         (( ${ffree[min_index]} < 10000000 )) ||
26103                 skip "too many free files in MDT$min_index"
26104
26105         # Check if we need to generate uneven MDTs
26106         local diff=$(((max - min) * 100 / min))
26107         local testdir=$DIR/$tdir-fillmdt
26108         local start
26109
26110         i=0
26111         while (( diff < threshold )); do
26112                 mkdir -p $testdir
26113                 # generate uneven MDTs, create till $threshold% diff
26114                 echo -n "weight diff=$diff% must be > $threshold% ..."
26115                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26116                 testdir=$DIR/$tdir-fillmdt/$i
26117                 [ -d $testdir ] && continue
26118                 $LFS mkdir -i $min_index $testdir ||
26119                         error "mkdir $testdir failed"
26120                 $LFS setstripe -E 1M -L mdt $testdir ||
26121                         error "setstripe $testdir failed"
26122                 start=$SECONDS
26123                 for ((F=0; F < TEST413_COUNT; F++)); do
26124                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26125                                 /dev/null 2>&1 || error "dd $F failed"
26126                 done
26127                 sync; sleep 1; sync
26128
26129                 # wait for QOS to update
26130                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26131
26132                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26133                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26134                 max=$(((${ffree[max_index]} >> 8) *
26135                         (${bavail[max_index]} * bsize >> 16)))
26136                 min=$(((${ffree[min_index]} >> 8) *
26137                         (${bavail[min_index]} * bsize >> 16)))
26138                 diff=$(((max - min) * 100 / min))
26139                 i=$((i + 1))
26140         done
26141
26142         echo "MDT filesfree available: ${ffree[*]}"
26143         echo "MDT blocks available: ${bavail[*]}"
26144         echo "weight diff=$diff%"
26145 }
26146
26147 test_qos_mkdir() {
26148         local mkdir_cmd=$1
26149         local stripe_count=$2
26150         local mdts=$(comma_list $(mdts_nodes))
26151
26152         local testdir
26153         local lmv_qos_prio_free
26154         local lmv_qos_threshold_rr
26155         local lmv_qos_maxage
26156         local lod_qos_prio_free
26157         local lod_qos_threshold_rr
26158         local lod_qos_maxage
26159         local count
26160         local i
26161
26162         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26163         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26164         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26165                 head -n1)
26166         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26167         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26168         stack_trap "$LCTL set_param \
26169                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26170         stack_trap "$LCTL set_param \
26171                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26172         stack_trap "$LCTL set_param \
26173                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26174
26175         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26176                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26177         lod_qos_prio_free=${lod_qos_prio_free%%%}
26178         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26179                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26180         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26181         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26182                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26183         stack_trap "do_nodes $mdts $LCTL set_param \
26184                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26185         stack_trap "do_nodes $mdts $LCTL set_param \
26186                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26187         stack_trap "do_nodes $mdts $LCTL set_param \
26188                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26189
26190         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26191         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26192
26193         testdir=$DIR/$tdir-s$stripe_count/rr
26194
26195         local stripe_index=$($LFS getstripe -m $testdir)
26196         local test_mkdir_rr=true
26197
26198         getfattr -d -m dmv -e hex $testdir | grep dmv
26199         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26200                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26201                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26202                         test_mkdir_rr=false
26203         fi
26204
26205         echo
26206         $test_mkdir_rr &&
26207                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26208                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26209
26210         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26211         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26212                 eval $mkdir_cmd $testdir/subdir$i ||
26213                         error "$mkdir_cmd subdir$i failed"
26214         done
26215
26216         for (( i = 0; i < $MDSCOUNT; i++ )); do
26217                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26218                 echo "$count directories created on MDT$i"
26219                 if $test_mkdir_rr; then
26220                         (( $count == 100 )) ||
26221                                 error "subdirs are not evenly distributed"
26222                 elif (( $i == $stripe_index )); then
26223                         (( $count == 100 * MDSCOUNT )) ||
26224                                 error "$count subdirs created on MDT$i"
26225                 else
26226                         (( $count == 0 )) ||
26227                                 error "$count subdirs created on MDT$i"
26228                 fi
26229
26230                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26231                         count=$($LFS getdirstripe $testdir/* |
26232                                 grep -c -P "^\s+$i\t")
26233                         echo "$count stripes created on MDT$i"
26234                         # deviation should < 5% of average
26235                         (( $count >= 95 * stripe_count &&
26236                            $count <= 105 * stripe_count)) ||
26237                                 error "stripes are not evenly distributed"
26238                 fi
26239         done
26240
26241         echo
26242         echo "Check for uneven MDTs: "
26243
26244         local ffree
26245         local bavail
26246         local max
26247         local min
26248         local max_index
26249         local min_index
26250         local tmp
26251
26252         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26253         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26254         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26255
26256         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26257         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26258         max_index=0
26259         min_index=0
26260         for ((i = 1; i < ${#ffree[@]}; i++)); do
26261                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26262                 if [ $tmp -gt $max ]; then
26263                         max=$tmp
26264                         max_index=$i
26265                 fi
26266                 if [ $tmp -lt $min ]; then
26267                         min=$tmp
26268                         min_index=$i
26269                 fi
26270         done
26271
26272         (( ${ffree[min_index]} > 0 )) ||
26273                 skip "no free files in MDT$min_index"
26274         (( ${ffree[min_index]} < 10000000 )) ||
26275                 skip "too many free files in MDT$min_index"
26276
26277         echo "MDT filesfree available: ${ffree[*]}"
26278         echo "MDT blocks available: ${bavail[*]}"
26279         echo "weight diff=$(((max - min) * 100 / min))%"
26280         echo
26281         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26282
26283         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26284         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26285         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26286         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26287         # decrease statfs age, so that it can be updated in time
26288         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26289         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26290
26291         sleep 1
26292
26293         testdir=$DIR/$tdir-s$stripe_count/qos
26294         local num=200
26295
26296         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26297         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26298                 eval $mkdir_cmd $testdir/subdir$i ||
26299                         error "$mkdir_cmd subdir$i failed"
26300         done
26301
26302         max=0
26303         for (( i = 0; i < $MDSCOUNT; i++ )); do
26304                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26305                 (( count > max )) && max=$count
26306                 echo "$count directories created on MDT$i"
26307         done
26308
26309         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26310
26311         # D-value should > 10% of averge
26312         (( max - min > num / 10 )) ||
26313                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26314
26315         # ditto for stripes
26316         if (( stripe_count > 1 )); then
26317                 max=0
26318                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26319                         count=$($LFS getdirstripe $testdir/* |
26320                                 grep -c -P "^\s+$i\t")
26321                         (( count > max )) && max=$count
26322                         echo "$count stripes created on MDT$i"
26323                 done
26324
26325                 min=$($LFS getdirstripe $testdir/* |
26326                         grep -c -P "^\s+$min_index\t")
26327                 (( max - min > num * stripe_count / 10 )) ||
26328                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26329         fi
26330 }
26331
26332 most_full_mdt() {
26333         local ffree
26334         local bavail
26335         local bsize
26336         local min
26337         local min_index
26338         local tmp
26339
26340         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26341         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26342         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26343
26344         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26345         min_index=0
26346         for ((i = 1; i < ${#ffree[@]}; i++)); do
26347                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26348                 (( tmp < min )) && min=$tmp && min_index=$i
26349         done
26350
26351         echo -n $min_index
26352 }
26353
26354 test_413a() {
26355         [ $MDSCOUNT -lt 2 ] &&
26356                 skip "We need at least 2 MDTs for this test"
26357
26358         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26359                 skip "Need server version at least 2.12.52"
26360
26361         local stripe_count
26362
26363         generate_uneven_mdts 100
26364         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26365                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26366                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26367                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26368                         error "mkdir failed"
26369                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26370         done
26371 }
26372 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26373
26374 test_413b() {
26375         [ $MDSCOUNT -lt 2 ] &&
26376                 skip "We need at least 2 MDTs for this test"
26377
26378         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26379                 skip "Need server version at least 2.12.52"
26380
26381         local testdir
26382         local stripe_count
26383
26384         generate_uneven_mdts 100
26385         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26386                 testdir=$DIR/$tdir-s$stripe_count
26387                 mkdir $testdir || error "mkdir $testdir failed"
26388                 mkdir $testdir/rr || error "mkdir rr failed"
26389                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26390                         error "mkdir qos failed"
26391                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26392                         $testdir/rr || error "setdirstripe rr failed"
26393                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26394                         error "setdirstripe failed"
26395                 test_qos_mkdir "mkdir" $stripe_count
26396         done
26397 }
26398 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26399
26400 test_413c() {
26401         (( $MDSCOUNT >= 2 )) ||
26402                 skip "We need at least 2 MDTs for this test"
26403
26404         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26405                 skip "Need server version at least 2.14.51"
26406
26407         local testdir
26408         local inherit
26409         local inherit_rr
26410
26411         testdir=$DIR/${tdir}-s1
26412         mkdir $testdir || error "mkdir $testdir failed"
26413         mkdir $testdir/rr || error "mkdir rr failed"
26414         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26415         # default max_inherit is -1, default max_inherit_rr is 0
26416         $LFS setdirstripe -D -c 1 $testdir/rr ||
26417                 error "setdirstripe rr failed"
26418         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26419                 error "setdirstripe qos failed"
26420         test_qos_mkdir "mkdir" 1
26421
26422         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26423         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26424         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26425         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26426         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26427
26428         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26429         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26430         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26431         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26432         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26433         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26434         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26435                 error "level2 shouldn't have default LMV" || true
26436 }
26437 run_test 413c "mkdir with default LMV max inherit rr"
26438
26439 test_413d() {
26440         (( MDSCOUNT >= 2 )) ||
26441                 skip "We need at least 2 MDTs for this test"
26442
26443         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26444                 skip "Need server version at least 2.14.51"
26445
26446         local lmv_qos_threshold_rr
26447
26448         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26449                 head -n1)
26450         stack_trap "$LCTL set_param \
26451                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26452
26453         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26454         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26455         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26456                 error "$tdir shouldn't have default LMV"
26457         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26458                 error "mkdir sub failed"
26459
26460         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26461
26462         (( count == 100 )) || error "$count subdirs on MDT0"
26463 }
26464 run_test 413d "inherit ROOT default LMV"
26465
26466 test_413e() {
26467         (( MDSCOUNT >= 2 )) ||
26468                 skip "We need at least 2 MDTs for this test"
26469         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26470                 skip "Need server version at least 2.14.55"
26471
26472         local testdir=$DIR/$tdir
26473         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26474         local max_inherit
26475         local sub_max_inherit
26476
26477         mkdir -p $testdir || error "failed to create $testdir"
26478
26479         # set default max-inherit to -1 if stripe count is 0 or 1
26480         $LFS setdirstripe -D -c 1 $testdir ||
26481                 error "failed to set default LMV"
26482         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26483         (( max_inherit == -1 )) ||
26484                 error "wrong max_inherit value $max_inherit"
26485
26486         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26487         $LFS setdirstripe -D -c -1 $testdir ||
26488                 error "failed to set default LMV"
26489         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26490         (( max_inherit > 0 )) ||
26491                 error "wrong max_inherit value $max_inherit"
26492
26493         # and the subdir will decrease the max_inherit by 1
26494         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26495         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26496         (( sub_max_inherit == max_inherit - 1)) ||
26497                 error "wrong max-inherit of subdir $sub_max_inherit"
26498
26499         # check specified --max-inherit and warning message
26500         stack_trap "rm -f $tmpfile"
26501         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26502                 error "failed to set default LMV"
26503         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26504         (( max_inherit == -1 )) ||
26505                 error "wrong max_inherit value $max_inherit"
26506
26507         # check the warning messages
26508         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26509                 error "failed to detect warning string"
26510         fi
26511 }
26512 run_test 413e "check default max-inherit value"
26513
26514 test_fs_dmv_inherit()
26515 {
26516         local testdir=$DIR/$tdir
26517
26518         local count
26519         local inherit
26520         local inherit_rr
26521
26522         for i in 1 2 3; do
26523                 mkdir $testdir || error "mkdir $testdir failed"
26524                 count=$($LFS getdirstripe -D -c $testdir)
26525                 (( count == 1 )) ||
26526                         error "$testdir default LMV count mismatch $count != 1"
26527                 inherit=$($LFS getdirstripe -D -X $testdir)
26528                 (( inherit == 3 - i )) ||
26529                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26530                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26531                 (( inherit_rr == 3 - i )) ||
26532                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26533                 testdir=$testdir/sub
26534         done
26535
26536         mkdir $testdir || error "mkdir $testdir failed"
26537         count=$($LFS getdirstripe -D -c $testdir)
26538         (( count == 0 )) ||
26539                 error "$testdir default LMV count not zero: $count"
26540 }
26541
26542 test_413f() {
26543         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26544
26545         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26546                 skip "Need server version at least 2.14.55"
26547
26548         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26549                 error "dump $DIR default LMV failed"
26550         stack_trap "setfattr --restore=$TMP/dmv.ea"
26551
26552         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26553                 error "set $DIR default LMV failed"
26554
26555         test_fs_dmv_inherit
26556 }
26557 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26558
26559 test_413g() {
26560         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26561
26562         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26563         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26564                 error "dump $DIR default LMV failed"
26565         stack_trap "setfattr --restore=$TMP/dmv.ea"
26566
26567         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26568                 error "set $DIR default LMV failed"
26569
26570         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26571                 error "mount $MOUNT2 failed"
26572         stack_trap "umount_client $MOUNT2"
26573
26574         local saved_DIR=$DIR
26575
26576         export DIR=$MOUNT2
26577
26578         stack_trap "export DIR=$saved_DIR"
26579
26580         # first check filesystem-wide default LMV inheritance
26581         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26582
26583         # then check subdirs are spread to all MDTs
26584         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26585
26586         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26587
26588         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26589 }
26590 run_test 413g "enforce ROOT default LMV on subdir mount"
26591
26592 test_413h() {
26593         (( MDSCOUNT >= 2 )) ||
26594                 skip "We need at least 2 MDTs for this test"
26595
26596         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26597                 skip "Need server version at least 2.15.50.6"
26598
26599         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26600
26601         stack_trap "$LCTL set_param \
26602                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26603         $LCTL set_param lmv.*.qos_maxage=1
26604
26605         local depth=5
26606         local rr_depth=4
26607         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26608         local count=$((MDSCOUNT * 20))
26609
26610         generate_uneven_mdts 50
26611
26612         mkdir -p $dir || error "mkdir $dir failed"
26613         stack_trap "rm -rf $dir"
26614         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26615                 --max-inherit-rr=$rr_depth $dir
26616
26617         for ((d=0; d < depth + 2; d++)); do
26618                 log "dir=$dir:"
26619                 for ((sub=0; sub < count; sub++)); do
26620                         mkdir $dir/d$sub
26621                 done
26622                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26623                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26624                 # subdirs within $rr_depth should be created round-robin
26625                 if (( d < rr_depth )); then
26626                         (( ${num[0]} != count )) ||
26627                                 error "all objects created on MDT ${num[1]}"
26628                 fi
26629
26630                 dir=$dir/d0
26631         done
26632 }
26633 run_test 413h "don't stick to parent for round-robin dirs"
26634
26635 test_413z() {
26636         local pids=""
26637         local subdir
26638         local pid
26639
26640         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26641                 unlinkmany $subdir/f. $TEST413_COUNT &
26642                 pids="$pids $!"
26643         done
26644
26645         for pid in $pids; do
26646                 wait $pid
26647         done
26648 }
26649 run_test 413z "413 test cleanup"
26650
26651 test_414() {
26652 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26653         $LCTL set_param fail_loc=0x80000521
26654         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26655         rm -f $DIR/$tfile
26656 }
26657 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26658
26659 test_415() {
26660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26662                 skip "Need server version at least 2.11.52"
26663
26664         # LU-11102
26665         local total
26666         local setattr_pid
26667         local start_time
26668         local end_time
26669         local duration
26670
26671         total=500
26672         # this test may be slow on ZFS
26673         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26674
26675         # though this test is designed for striped directory, let's test normal
26676         # directory too since lock is always saved as CoS lock.
26677         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26678         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26679
26680         (
26681                 while true; do
26682                         touch $DIR/$tdir
26683                 done
26684         ) &
26685         setattr_pid=$!
26686
26687         start_time=$(date +%s)
26688         for i in $(seq $total); do
26689                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26690                         > /dev/null
26691         done
26692         end_time=$(date +%s)
26693         duration=$((end_time - start_time))
26694
26695         kill -9 $setattr_pid
26696
26697         echo "rename $total files took $duration sec"
26698         [ $duration -lt 100 ] || error "rename took $duration sec"
26699 }
26700 run_test 415 "lock revoke is not missing"
26701
26702 test_416() {
26703         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26704                 skip "Need server version at least 2.11.55"
26705
26706         # define OBD_FAIL_OSD_TXN_START    0x19a
26707         do_facet mds1 lctl set_param fail_loc=0x19a
26708
26709         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26710
26711         true
26712 }
26713 run_test 416 "transaction start failure won't cause system hung"
26714
26715 cleanup_417() {
26716         trap 0
26717         do_nodes $(comma_list $(mdts_nodes)) \
26718                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26719         do_nodes $(comma_list $(mdts_nodes)) \
26720                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26721         do_nodes $(comma_list $(mdts_nodes)) \
26722                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26723 }
26724
26725 test_417() {
26726         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26727         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26728                 skip "Need MDS version at least 2.11.56"
26729
26730         trap cleanup_417 RETURN EXIT
26731
26732         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26733         do_nodes $(comma_list $(mdts_nodes)) \
26734                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26735         $LFS migrate -m 0 $DIR/$tdir.1 &&
26736                 error "migrate dir $tdir.1 should fail"
26737
26738         do_nodes $(comma_list $(mdts_nodes)) \
26739                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26740         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26741                 error "create remote dir $tdir.2 should fail"
26742
26743         do_nodes $(comma_list $(mdts_nodes)) \
26744                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26745         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26746                 error "create striped dir $tdir.3 should fail"
26747         true
26748 }
26749 run_test 417 "disable remote dir, striped dir and dir migration"
26750
26751 # Checks that the outputs of df [-i] and lfs df [-i] match
26752 #
26753 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26754 check_lfs_df() {
26755         local dir=$2
26756         local inodes
26757         local df_out
26758         local lfs_df_out
26759         local count
26760         local passed=false
26761
26762         # blocks or inodes
26763         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26764
26765         for count in {1..100}; do
26766                 do_nodes "$CLIENTS" \
26767                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26768                 sync; sleep 0.2
26769
26770                 # read the lines of interest
26771                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26772                         error "df $inodes $dir | tail -n +2 failed"
26773                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26774                         error "lfs df $inodes $dir | grep summary: failed"
26775
26776                 # skip first substrings of each output as they are different
26777                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26778                 # compare the two outputs
26779                 passed=true
26780                 #  skip "available" on MDT until LU-13997 is fixed.
26781                 #for i in {1..5}; do
26782                 for i in 1 2 4 5; do
26783                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26784                 done
26785                 $passed && break
26786         done
26787
26788         if ! $passed; then
26789                 df -P $inodes $dir
26790                 echo
26791                 lfs df $inodes $dir
26792                 error "df and lfs df $1 output mismatch: "      \
26793                       "df ${inodes}: ${df_out[*]}, "            \
26794                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26795         fi
26796 }
26797
26798 test_418() {
26799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26800
26801         local dir=$DIR/$tdir
26802         local numfiles=$((RANDOM % 4096 + 2))
26803         local numblocks=$((RANDOM % 256 + 1))
26804
26805         wait_delete_completed
26806         test_mkdir $dir
26807
26808         # check block output
26809         check_lfs_df blocks $dir
26810         # check inode output
26811         check_lfs_df inodes $dir
26812
26813         # create a single file and retest
26814         echo "Creating a single file and testing"
26815         createmany -o $dir/$tfile- 1 &>/dev/null ||
26816                 error "creating 1 file in $dir failed"
26817         check_lfs_df blocks $dir
26818         check_lfs_df inodes $dir
26819
26820         # create a random number of files
26821         echo "Creating $((numfiles - 1)) files and testing"
26822         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26823                 error "creating $((numfiles - 1)) files in $dir failed"
26824
26825         # write a random number of blocks to the first test file
26826         echo "Writing $numblocks 4K blocks and testing"
26827         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26828                 count=$numblocks &>/dev/null ||
26829                 error "dd to $dir/${tfile}-0 failed"
26830
26831         # retest
26832         check_lfs_df blocks $dir
26833         check_lfs_df inodes $dir
26834
26835         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26836                 error "unlinking $numfiles files in $dir failed"
26837 }
26838 run_test 418 "df and lfs df outputs match"
26839
26840 test_419()
26841 {
26842         local dir=$DIR/$tdir
26843
26844         mkdir -p $dir
26845         touch $dir/file
26846
26847         cancel_lru_locks mdc
26848
26849         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26850         $LCTL set_param fail_loc=0x1410
26851         cat $dir/file
26852         $LCTL set_param fail_loc=0
26853         rm -rf $dir
26854 }
26855 run_test 419 "Verify open file by name doesn't crash kernel"
26856
26857 test_420()
26858 {
26859         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26860                 skip "Need MDS version at least 2.12.53"
26861
26862         local SAVE_UMASK=$(umask)
26863         local dir=$DIR/$tdir
26864         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26865
26866         mkdir -p $dir
26867         umask 0000
26868         mkdir -m03777 $dir/testdir
26869         ls -dn $dir/testdir
26870         # Need to remove trailing '.' when SELinux is enabled
26871         local dirperms=$(ls -dn $dir/testdir |
26872                          awk '{ sub(/\.$/, "", $1); print $1}')
26873         [ $dirperms == "drwxrwsrwt" ] ||
26874                 error "incorrect perms on $dir/testdir"
26875
26876         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26877                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26878         ls -n $dir/testdir/testfile
26879         local fileperms=$(ls -n $dir/testdir/testfile |
26880                           awk '{ sub(/\.$/, "", $1); print $1}')
26881         [ $fileperms == "-rwxr-xr-x" ] ||
26882                 error "incorrect perms on $dir/testdir/testfile"
26883
26884         umask $SAVE_UMASK
26885 }
26886 run_test 420 "clear SGID bit on non-directories for non-members"
26887
26888 test_421a() {
26889         local cnt
26890         local fid1
26891         local fid2
26892
26893         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26894                 skip "Need MDS version at least 2.12.54"
26895
26896         test_mkdir $DIR/$tdir
26897         createmany -o $DIR/$tdir/f 3
26898         cnt=$(ls -1 $DIR/$tdir | wc -l)
26899         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26900
26901         fid1=$(lfs path2fid $DIR/$tdir/f1)
26902         fid2=$(lfs path2fid $DIR/$tdir/f2)
26903         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26904
26905         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26906         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26907
26908         cnt=$(ls -1 $DIR/$tdir | wc -l)
26909         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26910
26911         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26912         createmany -o $DIR/$tdir/f 3
26913         cnt=$(ls -1 $DIR/$tdir | wc -l)
26914         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26915
26916         fid1=$(lfs path2fid $DIR/$tdir/f1)
26917         fid2=$(lfs path2fid $DIR/$tdir/f2)
26918         echo "remove using fsname $FSNAME"
26919         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26920
26921         cnt=$(ls -1 $DIR/$tdir | wc -l)
26922         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26923 }
26924 run_test 421a "simple rm by fid"
26925
26926 test_421b() {
26927         local cnt
26928         local FID1
26929         local FID2
26930
26931         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26932                 skip "Need MDS version at least 2.12.54"
26933
26934         test_mkdir $DIR/$tdir
26935         createmany -o $DIR/$tdir/f 3
26936         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26937         MULTIPID=$!
26938
26939         FID1=$(lfs path2fid $DIR/$tdir/f1)
26940         FID2=$(lfs path2fid $DIR/$tdir/f2)
26941         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26942
26943         kill -USR1 $MULTIPID
26944         wait
26945
26946         cnt=$(ls $DIR/$tdir | wc -l)
26947         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26948 }
26949 run_test 421b "rm by fid on open file"
26950
26951 test_421c() {
26952         local cnt
26953         local FIDS
26954
26955         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26956                 skip "Need MDS version at least 2.12.54"
26957
26958         test_mkdir $DIR/$tdir
26959         createmany -o $DIR/$tdir/f 3
26960         touch $DIR/$tdir/$tfile
26961         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26962         cnt=$(ls -1 $DIR/$tdir | wc -l)
26963         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26964
26965         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26966         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26967
26968         cnt=$(ls $DIR/$tdir | wc -l)
26969         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26970 }
26971 run_test 421c "rm by fid against hardlinked files"
26972
26973 test_421d() {
26974         local cnt
26975         local FIDS
26976
26977         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26978                 skip "Need MDS version at least 2.12.54"
26979
26980         test_mkdir $DIR/$tdir
26981         createmany -o $DIR/$tdir/f 4097
26982         cnt=$(ls -1 $DIR/$tdir | wc -l)
26983         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26984
26985         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26986         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26987
26988         cnt=$(ls $DIR/$tdir | wc -l)
26989         rm -rf $DIR/$tdir
26990         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26991 }
26992 run_test 421d "rmfid en masse"
26993
26994 test_421e() {
26995         local cnt
26996         local FID
26997
26998         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26999         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27000                 skip "Need MDS version at least 2.12.54"
27001
27002         mkdir -p $DIR/$tdir
27003         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27004         createmany -o $DIR/$tdir/striped_dir/f 512
27005         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27006         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27007
27008         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27009                 sed "s/[/][^:]*://g")
27010         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27011
27012         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27013         rm -rf $DIR/$tdir
27014         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27015 }
27016 run_test 421e "rmfid in DNE"
27017
27018 test_421f() {
27019         local cnt
27020         local FID
27021
27022         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27023                 skip "Need MDS version at least 2.12.54"
27024
27025         test_mkdir $DIR/$tdir
27026         touch $DIR/$tdir/f
27027         cnt=$(ls -1 $DIR/$tdir | wc -l)
27028         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27029
27030         FID=$(lfs path2fid $DIR/$tdir/f)
27031         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27032         # rmfid should fail
27033         cnt=$(ls -1 $DIR/$tdir | wc -l)
27034         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27035
27036         chmod a+rw $DIR/$tdir
27037         ls -la $DIR/$tdir
27038         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27039         # rmfid should fail
27040         cnt=$(ls -1 $DIR/$tdir | wc -l)
27041         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27042
27043         rm -f $DIR/$tdir/f
27044         $RUNAS touch $DIR/$tdir/f
27045         FID=$(lfs path2fid $DIR/$tdir/f)
27046         echo "rmfid as root"
27047         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27048         cnt=$(ls -1 $DIR/$tdir | wc -l)
27049         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27050
27051         rm -f $DIR/$tdir/f
27052         $RUNAS touch $DIR/$tdir/f
27053         cnt=$(ls -1 $DIR/$tdir | wc -l)
27054         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27055         FID=$(lfs path2fid $DIR/$tdir/f)
27056         # rmfid w/o user_fid2path mount option should fail
27057         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27058         cnt=$(ls -1 $DIR/$tdir | wc -l)
27059         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27060
27061         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27062         stack_trap "rmdir $tmpdir"
27063         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27064                 error "failed to mount client'"
27065         stack_trap "umount_client $tmpdir"
27066
27067         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27068         # rmfid should succeed
27069         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27070         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27071
27072         # rmfid shouldn't allow to remove files due to dir's permission
27073         chmod a+rwx $tmpdir/$tdir
27074         touch $tmpdir/$tdir/f
27075         ls -la $tmpdir/$tdir
27076         FID=$(lfs path2fid $tmpdir/$tdir/f)
27077         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27078         return 0
27079 }
27080 run_test 421f "rmfid checks permissions"
27081
27082 test_421g() {
27083         local cnt
27084         local FIDS
27085
27086         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27087         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27088                 skip "Need MDS version at least 2.12.54"
27089
27090         mkdir -p $DIR/$tdir
27091         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27092         createmany -o $DIR/$tdir/striped_dir/f 512
27093         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27094         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27095
27096         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27097                 sed "s/[/][^:]*://g")
27098
27099         rm -f $DIR/$tdir/striped_dir/f1*
27100         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27101         removed=$((512 - cnt))
27102
27103         # few files have been just removed, so we expect
27104         # rmfid to fail on their fids
27105         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27106         [ $removed != $errors ] && error "$errors != $removed"
27107
27108         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27109         rm -rf $DIR/$tdir
27110         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27111 }
27112 run_test 421g "rmfid to return errors properly"
27113
27114 test_422() {
27115         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27116         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27117         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27118         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27119         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27120
27121         local amc=$(at_max_get client)
27122         local amo=$(at_max_get mds1)
27123         local timeout=`lctl get_param -n timeout`
27124
27125         at_max_set 0 client
27126         at_max_set 0 mds1
27127
27128 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27129         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27130                         fail_val=$(((2*timeout + 10)*1000))
27131         touch $DIR/$tdir/d3/file &
27132         sleep 2
27133 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27134         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27135                         fail_val=$((2*timeout + 5))
27136         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27137         local pid=$!
27138         sleep 1
27139         kill -9 $pid
27140         sleep $((2 * timeout))
27141         echo kill $pid
27142         kill -9 $pid
27143         lctl mark touch
27144         touch $DIR/$tdir/d2/file3
27145         touch $DIR/$tdir/d2/file4
27146         touch $DIR/$tdir/d2/file5
27147
27148         wait
27149         at_max_set $amc client
27150         at_max_set $amo mds1
27151
27152         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27153         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27154                 error "Watchdog is always throttled"
27155 }
27156 run_test 422 "kill a process with RPC in progress"
27157
27158 stat_test() {
27159     df -h $MOUNT &
27160     df -h $MOUNT &
27161     df -h $MOUNT &
27162     df -h $MOUNT &
27163     df -h $MOUNT &
27164     df -h $MOUNT &
27165 }
27166
27167 test_423() {
27168     local _stats
27169     # ensure statfs cache is expired
27170     sleep 2;
27171
27172     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27173     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27174
27175     return 0
27176 }
27177 run_test 423 "statfs should return a right data"
27178
27179 test_424() {
27180 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27181         $LCTL set_param fail_loc=0x80000522
27182         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27183         rm -f $DIR/$tfile
27184 }
27185 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27186
27187 test_425() {
27188         test_mkdir -c -1 $DIR/$tdir
27189         $LFS setstripe -c -1 $DIR/$tdir
27190
27191         lru_resize_disable "" 100
27192         stack_trap "lru_resize_enable" EXIT
27193
27194         sleep 5
27195
27196         for i in $(seq $((MDSCOUNT * 125))); do
27197                 local t=$DIR/$tdir/$tfile_$i
27198
27199                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27200                         error_noexit "Create file $t"
27201         done
27202         stack_trap "rm -rf $DIR/$tdir" EXIT
27203
27204         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27205                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27206                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27207
27208                 [ $lock_count -le $lru_size ] ||
27209                         error "osc lock count $lock_count > lru size $lru_size"
27210         done
27211
27212         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27213                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27214                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27215
27216                 [ $lock_count -le $lru_size ] ||
27217                         error "mdc lock count $lock_count > lru size $lru_size"
27218         done
27219 }
27220 run_test 425 "lock count should not exceed lru size"
27221
27222 test_426() {
27223         splice-test -r $DIR/$tfile
27224         splice-test -rd $DIR/$tfile
27225         splice-test $DIR/$tfile
27226         splice-test -d $DIR/$tfile
27227 }
27228 run_test 426 "splice test on Lustre"
27229
27230 test_427() {
27231         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27232         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27233                 skip "Need MDS version at least 2.12.4"
27234         local log
27235
27236         mkdir $DIR/$tdir
27237         mkdir $DIR/$tdir/1
27238         mkdir $DIR/$tdir/2
27239         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27240         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27241
27242         $LFS getdirstripe $DIR/$tdir/1/dir
27243
27244         #first setfattr for creating updatelog
27245         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27246
27247 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27248         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27249         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27250         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27251
27252         sleep 2
27253         fail mds2
27254         wait_recovery_complete mds2 $((2*TIMEOUT))
27255
27256         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27257         echo $log | grep "get update log failed" &&
27258                 error "update log corruption is detected" || true
27259 }
27260 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27261
27262 test_428() {
27263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27264         local cache_limit=$CACHE_MAX
27265
27266         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27267         $LCTL set_param -n llite.*.max_cached_mb=64
27268
27269         mkdir $DIR/$tdir
27270         $LFS setstripe -c 1 $DIR/$tdir
27271         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27272         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27273         #test write
27274         for f in $(seq 4); do
27275                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27276         done
27277         wait
27278
27279         cancel_lru_locks osc
27280         # Test read
27281         for f in $(seq 4); do
27282                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27283         done
27284         wait
27285 }
27286 run_test 428 "large block size IO should not hang"
27287
27288 test_429() { # LU-7915 / LU-10948
27289         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27290         local testfile=$DIR/$tfile
27291         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27292         local new_flag=1
27293         local first_rpc
27294         local second_rpc
27295         local third_rpc
27296
27297         $LCTL get_param $ll_opencache_threshold_count ||
27298                 skip "client does not have opencache parameter"
27299
27300         set_opencache $new_flag
27301         stack_trap "restore_opencache"
27302         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27303                 error "enable opencache failed"
27304         touch $testfile
27305         # drop MDC DLM locks
27306         cancel_lru_locks mdc
27307         # clear MDC RPC stats counters
27308         $LCTL set_param $mdc_rpcstats=clear
27309
27310         # According to the current implementation, we need to run 3 times
27311         # open & close file to verify if opencache is enabled correctly.
27312         # 1st, RPCs are sent for lookup/open and open handle is released on
27313         #      close finally.
27314         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27315         #      so open handle won't be released thereafter.
27316         # 3rd, No RPC is sent out.
27317         $MULTIOP $testfile oc || error "multiop failed"
27318         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27319         echo "1st: $first_rpc RPCs in flight"
27320
27321         $MULTIOP $testfile oc || error "multiop failed"
27322         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27323         echo "2nd: $second_rpc RPCs in flight"
27324
27325         $MULTIOP $testfile oc || error "multiop failed"
27326         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27327         echo "3rd: $third_rpc RPCs in flight"
27328
27329         #verify no MDC RPC is sent
27330         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27331 }
27332 run_test 429 "verify if opencache flag on client side does work"
27333
27334 lseek_test_430() {
27335         local offset
27336         local file=$1
27337
27338         # data at [200K, 400K)
27339         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27340                 error "256K->512K dd fails"
27341         # data at [2M, 3M)
27342         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27343                 error "2M->3M dd fails"
27344         # data at [4M, 5M)
27345         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27346                 error "4M->5M dd fails"
27347         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27348         # start at first component hole #1
27349         printf "Seeking hole from 1000 ... "
27350         offset=$(lseek_test -l 1000 $file)
27351         echo $offset
27352         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27353         printf "Seeking data from 1000 ... "
27354         offset=$(lseek_test -d 1000 $file)
27355         echo $offset
27356         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27357
27358         # start at first component data block
27359         printf "Seeking hole from 300000 ... "
27360         offset=$(lseek_test -l 300000 $file)
27361         echo $offset
27362         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27363         printf "Seeking data from 300000 ... "
27364         offset=$(lseek_test -d 300000 $file)
27365         echo $offset
27366         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27367
27368         # start at the first component but beyond end of object size
27369         printf "Seeking hole from 1000000 ... "
27370         offset=$(lseek_test -l 1000000 $file)
27371         echo $offset
27372         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27373         printf "Seeking data from 1000000 ... "
27374         offset=$(lseek_test -d 1000000 $file)
27375         echo $offset
27376         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27377
27378         # start at second component stripe 2 (empty file)
27379         printf "Seeking hole from 1500000 ... "
27380         offset=$(lseek_test -l 1500000 $file)
27381         echo $offset
27382         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27383         printf "Seeking data from 1500000 ... "
27384         offset=$(lseek_test -d 1500000 $file)
27385         echo $offset
27386         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27387
27388         # start at second component stripe 1 (all data)
27389         printf "Seeking hole from 3000000 ... "
27390         offset=$(lseek_test -l 3000000 $file)
27391         echo $offset
27392         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27393         printf "Seeking data from 3000000 ... "
27394         offset=$(lseek_test -d 3000000 $file)
27395         echo $offset
27396         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27397
27398         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27399                 error "2nd dd fails"
27400         echo "Add data block at 640K...1280K"
27401
27402         # start at before new data block, in hole
27403         printf "Seeking hole from 600000 ... "
27404         offset=$(lseek_test -l 600000 $file)
27405         echo $offset
27406         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27407         printf "Seeking data from 600000 ... "
27408         offset=$(lseek_test -d 600000 $file)
27409         echo $offset
27410         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27411
27412         # start at the first component new data block
27413         printf "Seeking hole from 1000000 ... "
27414         offset=$(lseek_test -l 1000000 $file)
27415         echo $offset
27416         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27417         printf "Seeking data from 1000000 ... "
27418         offset=$(lseek_test -d 1000000 $file)
27419         echo $offset
27420         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27421
27422         # start at second component stripe 2, new data
27423         printf "Seeking hole from 1200000 ... "
27424         offset=$(lseek_test -l 1200000 $file)
27425         echo $offset
27426         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27427         printf "Seeking data from 1200000 ... "
27428         offset=$(lseek_test -d 1200000 $file)
27429         echo $offset
27430         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27431
27432         # start beyond file end
27433         printf "Using offset > filesize ... "
27434         lseek_test -l 4000000 $file && error "lseek should fail"
27435         printf "Using offset > filesize ... "
27436         lseek_test -d 4000000 $file && error "lseek should fail"
27437
27438         printf "Done\n\n"
27439 }
27440
27441 test_430a() {
27442         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27443                 skip "MDT does not support SEEK_HOLE"
27444
27445         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27446                 skip "OST does not support SEEK_HOLE"
27447
27448         local file=$DIR/$tdir/$tfile
27449
27450         mkdir -p $DIR/$tdir
27451
27452         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27453         # OST stripe #1 will have continuous data at [1M, 3M)
27454         # OST stripe #2 is empty
27455         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27456         lseek_test_430 $file
27457         rm $file
27458         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27459         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27460         lseek_test_430 $file
27461         rm $file
27462         $LFS setstripe -c2 -S 512K $file
27463         echo "Two stripes, stripe size 512K"
27464         lseek_test_430 $file
27465         rm $file
27466         # FLR with stale mirror
27467         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27468                        -N -c2 -S 1M $file
27469         echo "Mirrored file:"
27470         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27471         echo "Plain 2 stripes 1M"
27472         lseek_test_430 $file
27473         rm $file
27474 }
27475 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27476
27477 test_430b() {
27478         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27479                 skip "OST does not support SEEK_HOLE"
27480
27481         local offset
27482         local file=$DIR/$tdir/$tfile
27483
27484         mkdir -p $DIR/$tdir
27485         # Empty layout lseek should fail
27486         $MCREATE $file
27487         # seek from 0
27488         printf "Seeking hole from 0 ... "
27489         lseek_test -l 0 $file && error "lseek should fail"
27490         printf "Seeking data from 0 ... "
27491         lseek_test -d 0 $file && error "lseek should fail"
27492         rm $file
27493
27494         # 1M-hole file
27495         $LFS setstripe -E 1M -c2 -E eof $file
27496         $TRUNCATE $file 1048576
27497         printf "Seeking hole from 1000000 ... "
27498         offset=$(lseek_test -l 1000000 $file)
27499         echo $offset
27500         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27501         printf "Seeking data from 1000000 ... "
27502         lseek_test -d 1000000 $file && error "lseek should fail"
27503         rm $file
27504
27505         # full component followed by non-inited one
27506         $LFS setstripe -E 1M -c2 -E eof $file
27507         dd if=/dev/urandom of=$file bs=1M count=1
27508         printf "Seeking hole from 1000000 ... "
27509         offset=$(lseek_test -l 1000000 $file)
27510         echo $offset
27511         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27512         printf "Seeking hole from 1048576 ... "
27513         lseek_test -l 1048576 $file && error "lseek should fail"
27514         # init second component and truncate back
27515         echo "123" >> $file
27516         $TRUNCATE $file 1048576
27517         printf "Seeking hole from 1000000 ... "
27518         offset=$(lseek_test -l 1000000 $file)
27519         echo $offset
27520         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27521         printf "Seeking hole from 1048576 ... "
27522         lseek_test -l 1048576 $file && error "lseek should fail"
27523         # boundary checks for big values
27524         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27525         offset=$(lseek_test -d 0 $file.10g)
27526         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27527         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27528         offset=$(lseek_test -d 0 $file.100g)
27529         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27530         return 0
27531 }
27532 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27533
27534 test_430c() {
27535         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27536                 skip "OST does not support SEEK_HOLE"
27537
27538         local file=$DIR/$tdir/$tfile
27539         local start
27540
27541         mkdir -p $DIR/$tdir
27542         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27543
27544         # cp version 8.33+ prefers lseek over fiemap
27545         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27546                 start=$SECONDS
27547                 time cp $file /dev/null
27548                 (( SECONDS - start < 5 )) ||
27549                         error "cp: too long runtime $((SECONDS - start))"
27550
27551         fi
27552         # tar version 1.29+ supports SEEK_HOLE/DATA
27553         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27554                 start=$SECONDS
27555                 time tar cS $file - | cat > /dev/null
27556                 (( SECONDS - start < 5 )) ||
27557                         error "tar: too long runtime $((SECONDS - start))"
27558         fi
27559 }
27560 run_test 430c "lseek: external tools check"
27561
27562 test_431() { # LU-14187
27563         local file=$DIR/$tdir/$tfile
27564
27565         mkdir -p $DIR/$tdir
27566         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27567         dd if=/dev/urandom of=$file bs=4k count=1
27568         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27569         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27570         #define OBD_FAIL_OST_RESTART_IO 0x251
27571         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27572         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27573         cp $file $file.0
27574         cancel_lru_locks
27575         sync_all_data
27576         echo 3 > /proc/sys/vm/drop_caches
27577         diff  $file $file.0 || error "data diff"
27578 }
27579 run_test 431 "Restart transaction for IO"
27580
27581 cleanup_test_432() {
27582         do_facet mgs $LCTL nodemap_activate 0
27583         wait_nm_sync active
27584 }
27585
27586 test_432() {
27587         local tmpdir=$TMP/dir432
27588
27589         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27590                 skip "Need MDS version at least 2.14.52"
27591
27592         stack_trap cleanup_test_432 EXIT
27593         mkdir $DIR/$tdir
27594         mkdir $tmpdir
27595
27596         do_facet mgs $LCTL nodemap_activate 1
27597         wait_nm_sync active
27598         do_facet mgs $LCTL nodemap_modify --name default \
27599                 --property admin --value 1
27600         do_facet mgs $LCTL nodemap_modify --name default \
27601                 --property trusted --value 1
27602         cancel_lru_locks mdc
27603         wait_nm_sync default admin_nodemap
27604         wait_nm_sync default trusted_nodemap
27605
27606         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27607                grep -ci "Operation not permitted") -ne 0 ]; then
27608                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27609         fi
27610 }
27611 run_test 432 "mv dir from outside Lustre"
27612
27613 test_433() {
27614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27615
27616         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27617                 skip "inode cache not supported"
27618
27619         $LCTL set_param llite.*.inode_cache=0
27620         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27621
27622         local count=256
27623         local before
27624         local after
27625
27626         cancel_lru_locks mdc
27627         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27628         createmany -m $DIR/$tdir/f $count
27629         createmany -d $DIR/$tdir/d $count
27630         ls -l $DIR/$tdir > /dev/null
27631         stack_trap "rm -rf $DIR/$tdir"
27632
27633         before=$(num_objects)
27634         cancel_lru_locks mdc
27635         after=$(num_objects)
27636
27637         # sometimes even @before is less than 2 * count
27638         while (( before - after < count )); do
27639                 sleep 1
27640                 after=$(num_objects)
27641                 wait=$((wait + 1))
27642                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27643                 if (( wait > 60 )); then
27644                         error "inode slab grew from $before to $after"
27645                 fi
27646         done
27647
27648         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27649 }
27650 run_test 433 "ldlm lock cancel releases dentries and inodes"
27651
27652 test_434() {
27653         local file
27654         local getxattr_count
27655         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27656         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27657
27658         [[ $(getenforce) == "Disabled" ]] ||
27659                 skip "lsm selinux module have to be disabled for this test"
27660
27661         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27662                 error "fail to create $DIR/$tdir/ on MDT0000"
27663
27664         touch $DIR/$tdir/$tfile-{001..100}
27665
27666         # disable the xattr cache
27667         save_lustre_params client "llite.*.xattr_cache" > $p
27668         lctl set_param llite.*.xattr_cache=0
27669         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27670
27671         # clear clients mdc stats
27672         clear_stats $mdc_stat_param ||
27673                 error "fail to clear stats on mdc MDT0000"
27674
27675         for file in $DIR/$tdir/$tfile-{001..100}; do
27676                 getfattr -n security.selinux $file |&
27677                         grep -q "Operation not supported" ||
27678                         error "getxattr on security.selinux should return EOPNOTSUPP"
27679         done
27680
27681         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27682         (( getxattr_count < 100 )) ||
27683                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27684 }
27685 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27686
27687 prep_801() {
27688         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27689         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27690                 skip "Need server version at least 2.9.55"
27691
27692         start_full_debug_logging
27693 }
27694
27695 post_801() {
27696         stop_full_debug_logging
27697 }
27698
27699 barrier_stat() {
27700         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27701                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27702                            awk '/The barrier for/ { print $7 }')
27703                 echo $st
27704         else
27705                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27706                 echo \'$st\'
27707         fi
27708 }
27709
27710 barrier_expired() {
27711         local expired
27712
27713         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27714                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27715                           awk '/will be expired/ { print $7 }')
27716         else
27717                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27718         fi
27719
27720         echo $expired
27721 }
27722
27723 test_801a() {
27724         prep_801
27725
27726         echo "Start barrier_freeze at: $(date)"
27727         #define OBD_FAIL_BARRIER_DELAY          0x2202
27728         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27729         # Do not reduce barrier time - See LU-11873
27730         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27731
27732         sleep 2
27733         local b_status=$(barrier_stat)
27734         echo "Got barrier status at: $(date)"
27735         [ "$b_status" = "'freezing_p1'" ] ||
27736                 error "(1) unexpected barrier status $b_status"
27737
27738         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27739         wait
27740         b_status=$(barrier_stat)
27741         [ "$b_status" = "'frozen'" ] ||
27742                 error "(2) unexpected barrier status $b_status"
27743
27744         local expired=$(barrier_expired)
27745         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27746         sleep $((expired + 3))
27747
27748         b_status=$(barrier_stat)
27749         [ "$b_status" = "'expired'" ] ||
27750                 error "(3) unexpected barrier status $b_status"
27751
27752         # Do not reduce barrier time - See LU-11873
27753         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27754                 error "(4) fail to freeze barrier"
27755
27756         b_status=$(barrier_stat)
27757         [ "$b_status" = "'frozen'" ] ||
27758                 error "(5) unexpected barrier status $b_status"
27759
27760         echo "Start barrier_thaw at: $(date)"
27761         #define OBD_FAIL_BARRIER_DELAY          0x2202
27762         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27763         do_facet mgs $LCTL barrier_thaw $FSNAME &
27764
27765         sleep 2
27766         b_status=$(barrier_stat)
27767         echo "Got barrier status at: $(date)"
27768         [ "$b_status" = "'thawing'" ] ||
27769                 error "(6) unexpected barrier status $b_status"
27770
27771         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27772         wait
27773         b_status=$(barrier_stat)
27774         [ "$b_status" = "'thawed'" ] ||
27775                 error "(7) unexpected barrier status $b_status"
27776
27777         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27778         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27779         do_facet mgs $LCTL barrier_freeze $FSNAME
27780
27781         b_status=$(barrier_stat)
27782         [ "$b_status" = "'failed'" ] ||
27783                 error "(8) unexpected barrier status $b_status"
27784
27785         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27786         do_facet mgs $LCTL barrier_thaw $FSNAME
27787
27788         post_801
27789 }
27790 run_test 801a "write barrier user interfaces and stat machine"
27791
27792 test_801b() {
27793         prep_801
27794
27795         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27796         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27797         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27798         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27799         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27800
27801         cancel_lru_locks mdc
27802
27803         # 180 seconds should be long enough
27804         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27805
27806         local b_status=$(barrier_stat)
27807         [ "$b_status" = "'frozen'" ] ||
27808                 error "(6) unexpected barrier status $b_status"
27809
27810         mkdir $DIR/$tdir/d0/d10 &
27811         mkdir_pid=$!
27812
27813         touch $DIR/$tdir/d1/f13 &
27814         touch_pid=$!
27815
27816         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27817         ln_pid=$!
27818
27819         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27820         mv_pid=$!
27821
27822         rm -f $DIR/$tdir/d4/f12 &
27823         rm_pid=$!
27824
27825         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27826
27827         # To guarantee taht the 'stat' is not blocked
27828         b_status=$(barrier_stat)
27829         [ "$b_status" = "'frozen'" ] ||
27830                 error "(8) unexpected barrier status $b_status"
27831
27832         # let above commands to run at background
27833         sleep 5
27834
27835         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27836         ps -p $touch_pid || error "(10) touch should be blocked"
27837         ps -p $ln_pid || error "(11) link should be blocked"
27838         ps -p $mv_pid || error "(12) rename should be blocked"
27839         ps -p $rm_pid || error "(13) unlink should be blocked"
27840
27841         b_status=$(barrier_stat)
27842         [ "$b_status" = "'frozen'" ] ||
27843                 error "(14) unexpected barrier status $b_status"
27844
27845         do_facet mgs $LCTL barrier_thaw $FSNAME
27846         b_status=$(barrier_stat)
27847         [ "$b_status" = "'thawed'" ] ||
27848                 error "(15) unexpected barrier status $b_status"
27849
27850         wait $mkdir_pid || error "(16) mkdir should succeed"
27851         wait $touch_pid || error "(17) touch should succeed"
27852         wait $ln_pid || error "(18) link should succeed"
27853         wait $mv_pid || error "(19) rename should succeed"
27854         wait $rm_pid || error "(20) unlink should succeed"
27855
27856         post_801
27857 }
27858 run_test 801b "modification will be blocked by write barrier"
27859
27860 test_801c() {
27861         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27862
27863         prep_801
27864
27865         stop mds2 || error "(1) Fail to stop mds2"
27866
27867         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27868
27869         local b_status=$(barrier_stat)
27870         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27871                 do_facet mgs $LCTL barrier_thaw $FSNAME
27872                 error "(2) unexpected barrier status $b_status"
27873         }
27874
27875         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27876                 error "(3) Fail to rescan barrier bitmap"
27877
27878         # Do not reduce barrier time - See LU-11873
27879         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27880
27881         b_status=$(barrier_stat)
27882         [ "$b_status" = "'frozen'" ] ||
27883                 error "(4) unexpected barrier status $b_status"
27884
27885         do_facet mgs $LCTL barrier_thaw $FSNAME
27886         b_status=$(barrier_stat)
27887         [ "$b_status" = "'thawed'" ] ||
27888                 error "(5) unexpected barrier status $b_status"
27889
27890         local devname=$(mdsdevname 2)
27891
27892         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27893
27894         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27895                 error "(7) Fail to rescan barrier bitmap"
27896
27897         post_801
27898 }
27899 run_test 801c "rescan barrier bitmap"
27900
27901 test_802b() {
27902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27903         remote_mds_nodsh && skip "remote MDS with nodsh"
27904
27905         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27906                 skip "readonly option not available"
27907
27908         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27909
27910         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27911                 error "(2) Fail to copy"
27912
27913         # write back all cached data before setting MDT to readonly
27914         cancel_lru_locks
27915         sync_all_data
27916
27917         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27918         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27919
27920         echo "Modify should be refused"
27921         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27922
27923         echo "Read should be allowed"
27924         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27925                 error "(7) Read should succeed under ro mode"
27926
27927         # disable readonly
27928         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27929 }
27930 run_test 802b "be able to set MDTs to readonly"
27931
27932 test_803a() {
27933         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27934         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27935                 skip "MDS needs to be newer than 2.10.54"
27936
27937         mkdir_on_mdt0 $DIR/$tdir
27938         # Create some objects on all MDTs to trigger related logs objects
27939         for idx in $(seq $MDSCOUNT); do
27940                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27941                         $DIR/$tdir/dir${idx} ||
27942                         error "Fail to create $DIR/$tdir/dir${idx}"
27943         done
27944
27945         wait_delete_completed # ensure old test cleanups are finished
27946         sleep 3
27947         echo "before create:"
27948         $LFS df -i $MOUNT
27949         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27950
27951         for i in {1..10}; do
27952                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27953                         error "Fail to create $DIR/$tdir/foo$i"
27954         done
27955
27956         # sync ZFS-on-MDS to refresh statfs data
27957         wait_zfs_commit mds1
27958         sleep 3
27959         echo "after create:"
27960         $LFS df -i $MOUNT
27961         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27962
27963         # allow for an llog to be cleaned up during the test
27964         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27965                 error "before ($before_used) + 10 > after ($after_used)"
27966
27967         for i in {1..10}; do
27968                 rm -rf $DIR/$tdir/foo$i ||
27969                         error "Fail to remove $DIR/$tdir/foo$i"
27970         done
27971
27972         # sync ZFS-on-MDS to refresh statfs data
27973         wait_zfs_commit mds1
27974         wait_delete_completed
27975         sleep 3 # avoid MDT return cached statfs
27976         echo "after unlink:"
27977         $LFS df -i $MOUNT
27978         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27979
27980         # allow for an llog to be created during the test
27981         [ $after_used -le $((before_used + 1)) ] ||
27982                 error "after ($after_used) > before ($before_used) + 1"
27983 }
27984 run_test 803a "verify agent object for remote object"
27985
27986 test_803b() {
27987         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27988         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27989                 skip "MDS needs to be newer than 2.13.56"
27990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27991
27992         for i in $(seq 0 $((MDSCOUNT - 1))); do
27993                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27994         done
27995
27996         local before=0
27997         local after=0
27998
27999         local tmp
28000
28001         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28002         for i in $(seq 0 $((MDSCOUNT - 1))); do
28003                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28004                         awk '/getattr/ { print $2 }')
28005                 before=$((before + tmp))
28006         done
28007         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28008         for i in $(seq 0 $((MDSCOUNT - 1))); do
28009                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28010                         awk '/getattr/ { print $2 }')
28011                 after=$((after + tmp))
28012         done
28013
28014         [ $before -eq $after ] || error "getattr count $before != $after"
28015 }
28016 run_test 803b "remote object can getattr from cache"
28017
28018 test_804() {
28019         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28020         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28021                 skip "MDS needs to be newer than 2.10.54"
28022         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28023
28024         mkdir -p $DIR/$tdir
28025         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28026                 error "Fail to create $DIR/$tdir/dir0"
28027
28028         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28029         local dev=$(mdsdevname 2)
28030
28031         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28032                 grep ${fid} || error "NOT found agent entry for dir0"
28033
28034         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28035                 error "Fail to create $DIR/$tdir/dir1"
28036
28037         touch $DIR/$tdir/dir1/foo0 ||
28038                 error "Fail to create $DIR/$tdir/dir1/foo0"
28039         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28040         local rc=0
28041
28042         for idx in $(seq $MDSCOUNT); do
28043                 dev=$(mdsdevname $idx)
28044                 do_facet mds${idx} \
28045                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28046                         grep ${fid} && rc=$idx
28047         done
28048
28049         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28050                 error "Fail to rename foo0 to foo1"
28051         if [ $rc -eq 0 ]; then
28052                 for idx in $(seq $MDSCOUNT); do
28053                         dev=$(mdsdevname $idx)
28054                         do_facet mds${idx} \
28055                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28056                         grep ${fid} && rc=$idx
28057                 done
28058         fi
28059
28060         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28061                 error "Fail to rename foo1 to foo2"
28062         if [ $rc -eq 0 ]; then
28063                 for idx in $(seq $MDSCOUNT); do
28064                         dev=$(mdsdevname $idx)
28065                         do_facet mds${idx} \
28066                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28067                         grep ${fid} && rc=$idx
28068                 done
28069         fi
28070
28071         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28072
28073         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28074                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28075         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28076                 error "Fail to rename foo2 to foo0"
28077         unlink $DIR/$tdir/dir1/foo0 ||
28078                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28079         rm -rf $DIR/$tdir/dir0 ||
28080                 error "Fail to rm $DIR/$tdir/dir0"
28081
28082         for idx in $(seq $MDSCOUNT); do
28083                 rc=0
28084
28085                 stop mds${idx}
28086                 dev=$(mdsdevname $idx)
28087                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28088                         rc=$?
28089                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28090                         error "mount mds$idx failed"
28091                 df $MOUNT > /dev/null 2>&1
28092
28093                 # e2fsck should not return error
28094                 [ $rc -eq 0 ] ||
28095                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28096         done
28097 }
28098 run_test 804 "verify agent entry for remote entry"
28099
28100 cleanup_805() {
28101         do_facet $SINGLEMDS zfs set quota=$old $fsset
28102         unlinkmany $DIR/$tdir/f- 1000000
28103         trap 0
28104 }
28105
28106 test_805() {
28107         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28108         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28109         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28110                 skip "netfree not implemented before 0.7"
28111         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28112                 skip "Need MDS version at least 2.10.57"
28113
28114         local fsset
28115         local freekb
28116         local usedkb
28117         local old
28118         local quota
28119         local pref="osd-zfs.$FSNAME-MDT0000."
28120
28121         # limit available space on MDS dataset to meet nospace issue
28122         # quickly. then ZFS 0.7.2 can use reserved space if asked
28123         # properly (using netfree flag in osd_declare_destroy()
28124         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28125         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28126                 gawk '{print $3}')
28127         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28128         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28129         let "usedkb=usedkb-freekb"
28130         let "freekb=freekb/2"
28131         if let "freekb > 5000"; then
28132                 let "freekb=5000"
28133         fi
28134         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28135         trap cleanup_805 EXIT
28136         mkdir_on_mdt0 $DIR/$tdir
28137         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28138                 error "Can't set PFL layout"
28139         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28140         rm -rf $DIR/$tdir || error "not able to remove"
28141         do_facet $SINGLEMDS zfs set quota=$old $fsset
28142         trap 0
28143 }
28144 run_test 805 "ZFS can remove from full fs"
28145
28146 # Size-on-MDS test
28147 check_lsom_data()
28148 {
28149         local file=$1
28150         local expect=$(stat -c %s $file)
28151
28152         check_lsom_size $1 $expect
28153
28154         local blocks=$($LFS getsom -b $file)
28155         expect=$(stat -c %b $file)
28156         [[ $blocks == $expect ]] ||
28157                 error "$file expected blocks: $expect, got: $blocks"
28158 }
28159
28160 check_lsom_size()
28161 {
28162         local size
28163         local expect=$2
28164
28165         cancel_lru_locks mdc
28166
28167         size=$($LFS getsom -s $1)
28168         [[ $size == $expect ]] ||
28169                 error "$file expected size: $expect, got: $size"
28170 }
28171
28172 test_806() {
28173         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28174                 skip "Need MDS version at least 2.11.52"
28175
28176         local bs=1048576
28177
28178         touch $DIR/$tfile || error "touch $tfile failed"
28179
28180         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28181         save_lustre_params client "llite.*.xattr_cache" > $save
28182         lctl set_param llite.*.xattr_cache=0
28183         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28184
28185         # single-threaded write
28186         echo "Test SOM for single-threaded write"
28187         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28188                 error "write $tfile failed"
28189         check_lsom_size $DIR/$tfile $bs
28190
28191         local num=32
28192         local size=$(($num * $bs))
28193         local offset=0
28194         local i
28195
28196         echo "Test SOM for single client multi-threaded($num) write"
28197         $TRUNCATE $DIR/$tfile 0
28198         for ((i = 0; i < $num; i++)); do
28199                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28200                 local pids[$i]=$!
28201                 offset=$((offset + $bs))
28202         done
28203         for (( i=0; i < $num; i++ )); do
28204                 wait ${pids[$i]}
28205         done
28206         check_lsom_size $DIR/$tfile $size
28207
28208         $TRUNCATE $DIR/$tfile 0
28209         for ((i = 0; i < $num; i++)); do
28210                 offset=$((offset - $bs))
28211                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28212                 local pids[$i]=$!
28213         done
28214         for (( i=0; i < $num; i++ )); do
28215                 wait ${pids[$i]}
28216         done
28217         check_lsom_size $DIR/$tfile $size
28218
28219         # multi-client writes
28220         num=$(get_node_count ${CLIENTS//,/ })
28221         size=$(($num * $bs))
28222         offset=0
28223         i=0
28224
28225         echo "Test SOM for multi-client ($num) writes"
28226         $TRUNCATE $DIR/$tfile 0
28227         for client in ${CLIENTS//,/ }; do
28228                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28229                 local pids[$i]=$!
28230                 i=$((i + 1))
28231                 offset=$((offset + $bs))
28232         done
28233         for (( i=0; i < $num; i++ )); do
28234                 wait ${pids[$i]}
28235         done
28236         check_lsom_size $DIR/$tfile $offset
28237
28238         i=0
28239         $TRUNCATE $DIR/$tfile 0
28240         for client in ${CLIENTS//,/ }; do
28241                 offset=$((offset - $bs))
28242                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28243                 local pids[$i]=$!
28244                 i=$((i + 1))
28245         done
28246         for (( i=0; i < $num; i++ )); do
28247                 wait ${pids[$i]}
28248         done
28249         check_lsom_size $DIR/$tfile $size
28250
28251         # verify truncate
28252         echo "Test SOM for truncate"
28253         $TRUNCATE $DIR/$tfile 1048576
28254         check_lsom_size $DIR/$tfile 1048576
28255         $TRUNCATE $DIR/$tfile 1234
28256         check_lsom_size $DIR/$tfile 1234
28257
28258         # verify SOM blocks count
28259         echo "Verify SOM block count"
28260         $TRUNCATE $DIR/$tfile 0
28261         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28262                 error "failed to write file $tfile"
28263         check_lsom_data $DIR/$tfile
28264 }
28265 run_test 806 "Verify Lazy Size on MDS"
28266
28267 test_807() {
28268         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28269         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28270                 skip "Need MDS version at least 2.11.52"
28271
28272         # Registration step
28273         changelog_register || error "changelog_register failed"
28274         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28275         changelog_users $SINGLEMDS | grep -q $cl_user ||
28276                 error "User $cl_user not found in changelog_users"
28277
28278         rm -rf $DIR/$tdir || error "rm $tdir failed"
28279         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28280         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28281         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28282         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28283                 error "truncate $tdir/trunc failed"
28284
28285         local bs=1048576
28286         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28287                 error "write $tfile failed"
28288
28289         # multi-client wirtes
28290         local num=$(get_node_count ${CLIENTS//,/ })
28291         local offset=0
28292         local i=0
28293
28294         echo "Test SOM for multi-client ($num) writes"
28295         touch $DIR/$tfile || error "touch $tfile failed"
28296         $TRUNCATE $DIR/$tfile 0
28297         for client in ${CLIENTS//,/ }; do
28298                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28299                 local pids[$i]=$!
28300                 i=$((i + 1))
28301                 offset=$((offset + $bs))
28302         done
28303         for (( i=0; i < $num; i++ )); do
28304                 wait ${pids[$i]}
28305         done
28306
28307         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28308         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28309         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28310         check_lsom_data $DIR/$tdir/trunc
28311         check_lsom_data $DIR/$tdir/single_dd
28312         check_lsom_data $DIR/$tfile
28313
28314         rm -rf $DIR/$tdir
28315         # Deregistration step
28316         changelog_deregister || error "changelog_deregister failed"
28317 }
28318 run_test 807 "verify LSOM syncing tool"
28319
28320 check_som_nologged()
28321 {
28322         local lines=$($LFS changelog $FSNAME-MDT0000 |
28323                 grep 'x=trusted.som' | wc -l)
28324         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28325 }
28326
28327 test_808() {
28328         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28329                 skip "Need MDS version at least 2.11.55"
28330
28331         # Registration step
28332         changelog_register || error "changelog_register failed"
28333
28334         touch $DIR/$tfile || error "touch $tfile failed"
28335         check_som_nologged
28336
28337         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28338                 error "write $tfile failed"
28339         check_som_nologged
28340
28341         $TRUNCATE $DIR/$tfile 1234
28342         check_som_nologged
28343
28344         $TRUNCATE $DIR/$tfile 1048576
28345         check_som_nologged
28346
28347         # Deregistration step
28348         changelog_deregister || error "changelog_deregister failed"
28349 }
28350 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28351
28352 check_som_nodata()
28353 {
28354         $LFS getsom $1
28355         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28356 }
28357
28358 test_809() {
28359         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28360                 skip "Need MDS version at least 2.11.56"
28361
28362         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28363                 error "failed to create DoM-only file $DIR/$tfile"
28364         touch $DIR/$tfile || error "touch $tfile failed"
28365         check_som_nodata $DIR/$tfile
28366
28367         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28368                 error "write $tfile failed"
28369         check_som_nodata $DIR/$tfile
28370
28371         $TRUNCATE $DIR/$tfile 1234
28372         check_som_nodata $DIR/$tfile
28373
28374         $TRUNCATE $DIR/$tfile 4097
28375         check_som_nodata $DIR/$file
28376 }
28377 run_test 809 "Verify no SOM xattr store for DoM-only files"
28378
28379 test_810() {
28380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28381         $GSS && skip_env "could not run with gss"
28382         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28383                 skip "OST < 2.12.58 doesn't align checksum"
28384
28385         set_checksums 1
28386         stack_trap "set_checksums $ORIG_CSUM" EXIT
28387         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28388
28389         local csum
28390         local before
28391         local after
28392         for csum in $CKSUM_TYPES; do
28393                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28394                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28395                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28396                         eval set -- $i
28397                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28398                         before=$(md5sum $DIR/$tfile)
28399                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28400                         after=$(md5sum $DIR/$tfile)
28401                         [ "$before" == "$after" ] ||
28402                                 error "$csum: $before != $after bs=$1 seek=$2"
28403                 done
28404         done
28405 }
28406 run_test 810 "partial page writes on ZFS (LU-11663)"
28407
28408 test_812a() {
28409         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28410                 skip "OST < 2.12.51 doesn't support this fail_loc"
28411
28412         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28413         # ensure ost1 is connected
28414         stat $DIR/$tfile >/dev/null || error "can't stat"
28415         wait_osc_import_state client ost1 FULL
28416         # no locks, no reqs to let the connection idle
28417         cancel_lru_locks osc
28418
28419         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28420 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28421         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28422         wait_osc_import_state client ost1 CONNECTING
28423         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28424
28425         stat $DIR/$tfile >/dev/null || error "can't stat file"
28426 }
28427 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28428
28429 test_812b() { # LU-12378
28430         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28431                 skip "OST < 2.12.51 doesn't support this fail_loc"
28432
28433         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28434         # ensure ost1 is connected
28435         stat $DIR/$tfile >/dev/null || error "can't stat"
28436         wait_osc_import_state client ost1 FULL
28437         # no locks, no reqs to let the connection idle
28438         cancel_lru_locks osc
28439
28440         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28441 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28442         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28443         wait_osc_import_state client ost1 CONNECTING
28444         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28445
28446         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28447         wait_osc_import_state client ost1 IDLE
28448 }
28449 run_test 812b "do not drop no resend request for idle connect"
28450
28451 test_812c() {
28452         local old
28453
28454         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28455
28456         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28457         $LFS getstripe $DIR/$tfile
28458         $LCTL set_param osc.*.idle_timeout=10
28459         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28460         # ensure ost1 is connected
28461         stat $DIR/$tfile >/dev/null || error "can't stat"
28462         wait_osc_import_state client ost1 FULL
28463         # no locks, no reqs to let the connection idle
28464         cancel_lru_locks osc
28465
28466 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28467         $LCTL set_param fail_loc=0x80000533
28468         sleep 15
28469         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28470 }
28471 run_test 812c "idle import vs lock enqueue race"
28472
28473 test_813() {
28474         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28475         [ -z "$file_heat_sav" ] && skip "no file heat support"
28476
28477         local readsample
28478         local writesample
28479         local readbyte
28480         local writebyte
28481         local readsample1
28482         local writesample1
28483         local readbyte1
28484         local writebyte1
28485
28486         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28487         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28488
28489         $LCTL set_param -n llite.*.file_heat=1
28490         echo "Turn on file heat"
28491         echo "Period second: $period_second, Decay percentage: $decay_pct"
28492
28493         echo "QQQQ" > $DIR/$tfile
28494         echo "QQQQ" > $DIR/$tfile
28495         echo "QQQQ" > $DIR/$tfile
28496         cat $DIR/$tfile > /dev/null
28497         cat $DIR/$tfile > /dev/null
28498         cat $DIR/$tfile > /dev/null
28499         cat $DIR/$tfile > /dev/null
28500
28501         local out=$($LFS heat_get $DIR/$tfile)
28502
28503         $LFS heat_get $DIR/$tfile
28504         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28505         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28506         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28507         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28508
28509         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28510         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28511         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28512         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28513
28514         sleep $((period_second + 3))
28515         echo "Sleep $((period_second + 3)) seconds..."
28516         # The recursion formula to calculate the heat of the file f is as
28517         # follow:
28518         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28519         # Where Hi is the heat value in the period between time points i*I and
28520         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28521         # to the weight of Ci.
28522         out=$($LFS heat_get $DIR/$tfile)
28523         $LFS heat_get $DIR/$tfile
28524         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28525         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28526         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28527         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28528
28529         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28530                 error "read sample ($readsample) is wrong"
28531         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28532                 error "write sample ($writesample) is wrong"
28533         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28534                 error "read bytes ($readbyte) is wrong"
28535         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28536                 error "write bytes ($writebyte) is wrong"
28537
28538         echo "QQQQ" > $DIR/$tfile
28539         echo "QQQQ" > $DIR/$tfile
28540         echo "QQQQ" > $DIR/$tfile
28541         cat $DIR/$tfile > /dev/null
28542         cat $DIR/$tfile > /dev/null
28543         cat $DIR/$tfile > /dev/null
28544         cat $DIR/$tfile > /dev/null
28545
28546         sleep $((period_second + 3))
28547         echo "Sleep $((period_second + 3)) seconds..."
28548
28549         out=$($LFS heat_get $DIR/$tfile)
28550         $LFS heat_get $DIR/$tfile
28551         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28552         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28553         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28554         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28555
28556         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28557                 4 * $decay_pct) / 100") -eq 1 ] ||
28558                 error "read sample ($readsample1) is wrong"
28559         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28560                 3 * $decay_pct) / 100") -eq 1 ] ||
28561                 error "write sample ($writesample1) is wrong"
28562         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28563                 20 * $decay_pct) / 100") -eq 1 ] ||
28564                 error "read bytes ($readbyte1) is wrong"
28565         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28566                 15 * $decay_pct) / 100") -eq 1 ] ||
28567                 error "write bytes ($writebyte1) is wrong"
28568
28569         echo "Turn off file heat for the file $DIR/$tfile"
28570         $LFS heat_set -o $DIR/$tfile
28571
28572         echo "QQQQ" > $DIR/$tfile
28573         echo "QQQQ" > $DIR/$tfile
28574         echo "QQQQ" > $DIR/$tfile
28575         cat $DIR/$tfile > /dev/null
28576         cat $DIR/$tfile > /dev/null
28577         cat $DIR/$tfile > /dev/null
28578         cat $DIR/$tfile > /dev/null
28579
28580         out=$($LFS heat_get $DIR/$tfile)
28581         $LFS heat_get $DIR/$tfile
28582         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28583         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28584         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28585         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28586
28587         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28588         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28589         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28590         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28591
28592         echo "Trun on file heat for the file $DIR/$tfile"
28593         $LFS heat_set -O $DIR/$tfile
28594
28595         echo "QQQQ" > $DIR/$tfile
28596         echo "QQQQ" > $DIR/$tfile
28597         echo "QQQQ" > $DIR/$tfile
28598         cat $DIR/$tfile > /dev/null
28599         cat $DIR/$tfile > /dev/null
28600         cat $DIR/$tfile > /dev/null
28601         cat $DIR/$tfile > /dev/null
28602
28603         out=$($LFS heat_get $DIR/$tfile)
28604         $LFS heat_get $DIR/$tfile
28605         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28606         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28607         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28608         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28609
28610         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28611         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28612         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28613         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28614
28615         $LFS heat_set -c $DIR/$tfile
28616         $LCTL set_param -n llite.*.file_heat=0
28617         echo "Turn off file heat support for the Lustre filesystem"
28618
28619         echo "QQQQ" > $DIR/$tfile
28620         echo "QQQQ" > $DIR/$tfile
28621         echo "QQQQ" > $DIR/$tfile
28622         cat $DIR/$tfile > /dev/null
28623         cat $DIR/$tfile > /dev/null
28624         cat $DIR/$tfile > /dev/null
28625         cat $DIR/$tfile > /dev/null
28626
28627         out=$($LFS heat_get $DIR/$tfile)
28628         $LFS heat_get $DIR/$tfile
28629         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28630         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28631         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28632         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28633
28634         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28635         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28636         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28637         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28638
28639         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28640         rm -f $DIR/$tfile
28641 }
28642 run_test 813 "File heat verfication"
28643
28644 test_814()
28645 {
28646         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28647         echo -n y >> $DIR/$tfile
28648         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28649         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28650 }
28651 run_test 814 "sparse cp works as expected (LU-12361)"
28652
28653 test_815()
28654 {
28655         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28656         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28657 }
28658 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28659
28660 test_816() {
28661         local ost1_imp=$(get_osc_import_name client ost1)
28662         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28663                          cut -d'.' -f2)
28664
28665         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28666         # ensure ost1 is connected
28667
28668         stat $DIR/$tfile >/dev/null || error "can't stat"
28669         wait_osc_import_state client ost1 FULL
28670         # no locks, no reqs to let the connection idle
28671         cancel_lru_locks osc
28672         lru_resize_disable osc
28673         local before
28674         local now
28675         before=$($LCTL get_param -n \
28676                  ldlm.namespaces.$imp_name.lru_size)
28677
28678         wait_osc_import_state client ost1 IDLE
28679         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28680         now=$($LCTL get_param -n \
28681               ldlm.namespaces.$imp_name.lru_size)
28682         [ $before == $now ] || error "lru_size changed $before != $now"
28683 }
28684 run_test 816 "do not reset lru_resize on idle reconnect"
28685
28686 cleanup_817() {
28687         umount $tmpdir
28688         exportfs -u localhost:$DIR/nfsexp
28689         rm -rf $DIR/nfsexp
28690 }
28691
28692 test_817() {
28693         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28694
28695         mkdir -p $DIR/nfsexp
28696         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28697                 error "failed to export nfs"
28698
28699         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28700         stack_trap cleanup_817 EXIT
28701
28702         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28703                 error "failed to mount nfs to $tmpdir"
28704
28705         cp /bin/true $tmpdir
28706         $DIR/nfsexp/true || error "failed to execute 'true' command"
28707 }
28708 run_test 817 "nfsd won't cache write lock for exec file"
28709
28710 test_818() {
28711         test_mkdir -i0 -c1 $DIR/$tdir
28712         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28713         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28714         stop $SINGLEMDS
28715
28716         # restore osp-syn threads
28717         stack_trap "fail $SINGLEMDS"
28718
28719         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28720         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28721         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28722                 error "start $SINGLEMDS failed"
28723         rm -rf $DIR/$tdir
28724
28725         local testid=$(echo $TESTNAME | tr '_' ' ')
28726
28727         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28728                 grep "run LFSCK" || error "run LFSCK is not suggested"
28729 }
28730 run_test 818 "unlink with failed llog"
28731
28732 test_819a() {
28733         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28734         cancel_lru_locks osc
28735         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28736         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28737         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28738         rm -f $TDIR/$tfile
28739 }
28740 run_test 819a "too big niobuf in read"
28741
28742 test_819b() {
28743         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28744         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28745         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28746         cancel_lru_locks osc
28747         sleep 1
28748         rm -f $TDIR/$tfile
28749 }
28750 run_test 819b "too big niobuf in write"
28751
28752
28753 function test_820_start_ost() {
28754         sleep 5
28755
28756         for num in $(seq $OSTCOUNT); do
28757                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28758         done
28759 }
28760
28761 test_820() {
28762         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28763
28764         mkdir $DIR/$tdir
28765         umount_client $MOUNT || error "umount failed"
28766         for num in $(seq $OSTCOUNT); do
28767                 stop ost$num
28768         done
28769
28770         # mount client with no active OSTs
28771         # so that the client can't initialize max LOV EA size
28772         # from OSC notifications
28773         mount_client $MOUNT || error "mount failed"
28774         # delay OST starting to keep this 0 max EA size for a while
28775         test_820_start_ost &
28776
28777         # create a directory on MDS2
28778         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28779                 error "Failed to create directory"
28780         # open intent should update default EA size
28781         # see mdc_update_max_ea_from_body()
28782         # notice this is the very first RPC to MDS2
28783         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28784         ret=$?
28785         echo $out
28786         # With SSK, this situation can lead to -EPERM being returned.
28787         # In that case, simply retry.
28788         if [ $ret -ne 0 ] && $SHARED_KEY; then
28789                 if echo "$out" | grep -q "not permitted"; then
28790                         cp /etc/services $DIR/$tdir/mds2
28791                         ret=$?
28792                 fi
28793         fi
28794         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28795 }
28796 run_test 820 "update max EA from open intent"
28797
28798 test_823() {
28799         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28800         local OST_MAX_PRECREATE=20000
28801
28802         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28803                 skip "Need MDS version at least 2.14.56"
28804
28805         save_lustre_params mds1 \
28806                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28807         do_facet $SINGLEMDS "$LCTL set_param -n \
28808                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28809         do_facet $SINGLEMDS "$LCTL set_param -n \
28810                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28811
28812         stack_trap "restore_lustre_params < $p; rm $p"
28813
28814         do_facet $SINGLEMDS "$LCTL set_param -n \
28815                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28816
28817         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28818                       osp.$FSNAME-OST0000*MDT0000.create_count")
28819         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28820                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28821         local expect_count=$(((($max/2)/256) * 256))
28822
28823         log "setting create_count to 100200:"
28824         log " -result- count: $count with max: $max, expecting: $expect_count"
28825
28826         [[ $count -eq expect_count ]] ||
28827                 error "Create count not set to max precreate."
28828 }
28829 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28830
28831 test_831() {
28832         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28833                 skip "Need MDS version 2.14.56"
28834
28835         local sync_changes=$(do_facet $SINGLEMDS \
28836                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28837
28838         [ "$sync_changes" -gt 100 ] &&
28839                 skip "Sync changes $sync_changes > 100 already"
28840
28841         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28842
28843         $LFS mkdir -i 0 $DIR/$tdir
28844         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28845
28846         save_lustre_params mds1 \
28847                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28848         save_lustre_params mds1 \
28849                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28850
28851         do_facet mds1 "$LCTL set_param -n \
28852                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28853                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28854         stack_trap "restore_lustre_params < $p" EXIT
28855
28856         createmany -o $DIR/$tdir/f- 1000
28857         unlinkmany $DIR/$tdir/f- 1000 &
28858         local UNLINK_PID=$!
28859
28860         while sleep 1; do
28861                 sync_changes=$(do_facet mds1 \
28862                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28863                 # the check in the code is racy, fail the test
28864                 # if the value above the limit by 10.
28865                 [ $sync_changes -gt 110 ] && {
28866                         kill -2 $UNLINK_PID
28867                         wait
28868                         error "osp changes throttling failed, $sync_changes>110"
28869                 }
28870                 kill -0 $UNLINK_PID 2> /dev/null || break
28871         done
28872         wait
28873 }
28874 run_test 831 "throttling unlink/setattr queuing on OSP"
28875
28876 #
28877 # tests that do cleanup/setup should be run at the end
28878 #
28879
28880 test_900() {
28881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28882         local ls
28883
28884         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28885         $LCTL set_param fail_loc=0x903
28886
28887         cancel_lru_locks MGC
28888
28889         FAIL_ON_ERROR=true cleanup
28890         FAIL_ON_ERROR=true setup
28891 }
28892 run_test 900 "umount should not race with any mgc requeue thread"
28893
28894 # LUS-6253/LU-11185
28895 test_901() {
28896         local old
28897         local count
28898         local oldc
28899         local newc
28900         local olds
28901         local news
28902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28903
28904         # some get_param have a bug to handle dot in param name
28905         cancel_lru_locks MGC
28906         old=$(mount -t lustre | wc -l)
28907         # 1 config+sptlrpc
28908         # 2 params
28909         # 3 nodemap
28910         # 4 IR
28911         old=$((old * 4))
28912         oldc=0
28913         count=0
28914         while [ $old -ne $oldc ]; do
28915                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28916                 sleep 1
28917                 ((count++))
28918                 if [ $count -ge $TIMEOUT ]; then
28919                         error "too large timeout"
28920                 fi
28921         done
28922         umount_client $MOUNT || error "umount failed"
28923         mount_client $MOUNT || error "mount failed"
28924         cancel_lru_locks MGC
28925         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28926
28927         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28928
28929         return 0
28930 }
28931 run_test 901 "don't leak a mgc lock on client umount"
28932
28933 # LU-13377
28934 test_902() {
28935         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28936                 skip "client does not have LU-13377 fix"
28937         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28938         $LCTL set_param fail_loc=0x1415
28939         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28940         cancel_lru_locks osc
28941         rm -f $DIR/$tfile
28942 }
28943 run_test 902 "test short write doesn't hang lustre"
28944
28945 # LU-14711
28946 test_903() {
28947         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28948         echo "blah" > $DIR/${tfile}-2
28949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28950         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28951         $LCTL set_param fail_loc=0x417 fail_val=20
28952
28953         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28954         sleep 1 # To start the destroy
28955         wait_destroy_complete 150 || error "Destroy taking too long"
28956         cat $DIR/$tfile > /dev/null || error "Evicted"
28957 }
28958 run_test 903 "Test long page discard does not cause evictions"
28959
28960 test_904() {
28961         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28962         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28963                 grep -q project || skip "skip project quota not supported"
28964
28965         local testfile="$DIR/$tdir/$tfile"
28966         local xattr="trusted.projid"
28967         local projid
28968         local mdts=$(comma_list $(mdts_nodes))
28969         local saved=$(do_facet mds1 $LCTL get_param -n \
28970                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28971
28972         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28973         stack_trap "do_nodes $mdts $LCTL set_param \
28974                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28975
28976         mkdir -p $DIR/$tdir
28977         touch $testfile
28978         #hide projid xattr on server
28979         $LFS project -p 1 $testfile ||
28980                 error "set $testfile project id failed"
28981         getfattr -m - $testfile | grep $xattr &&
28982                 error "do not show trusted.projid when disabled on server"
28983         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28984         #should be hidden when projid is 0
28985         $LFS project -p 0 $testfile ||
28986                 error "set $testfile project id failed"
28987         getfattr -m - $testfile | grep $xattr &&
28988                 error "do not show trusted.projid with project ID 0"
28989
28990         #still can getxattr explicitly
28991         projid=$(getfattr -n $xattr $testfile |
28992                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28993         [ $projid == "0" ] ||
28994                 error "projid expected 0 not $projid"
28995
28996         #set the projid via setxattr
28997         setfattr -n $xattr -v "1000" $testfile ||
28998                 error "setattr failed with $?"
28999         projid=($($LFS project $testfile))
29000         [ ${projid[0]} == "1000" ] ||
29001                 error "projid expected 1000 not $projid"
29002
29003         #check the new projid via getxattr
29004         $LFS project -p 1001 $testfile ||
29005                 error "set $testfile project id failed"
29006         getfattr -m - $testfile | grep $xattr ||
29007                 error "should show trusted.projid when project ID != 0"
29008         projid=$(getfattr -n $xattr $testfile |
29009                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29010         [ $projid == "1001" ] ||
29011                 error "projid expected 1001 not $projid"
29012
29013         #try to set invalid projid
29014         setfattr -n $xattr -v "4294967295" $testfile &&
29015                 error "set invalid projid should fail"
29016
29017         #remove the xattr means setting projid to 0
29018         setfattr -x $xattr $testfile ||
29019                 error "setfattr failed with $?"
29020         projid=($($LFS project $testfile))
29021         [ ${projid[0]} == "0" ] ||
29022                 error "projid expected 0 not $projid"
29023
29024         #should be hidden when parent has inherit flag and same projid
29025         $LFS project -srp 1002 $DIR/$tdir ||
29026                 error "set $tdir project id failed"
29027         getfattr -m - $testfile | grep $xattr &&
29028                 error "do not show trusted.projid with inherit flag"
29029
29030         #still can getxattr explicitly
29031         projid=$(getfattr -n $xattr $testfile |
29032                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29033         [ $projid == "1002" ] ||
29034                 error "projid expected 1002 not $projid"
29035 }
29036 run_test 904 "virtual project ID xattr"
29037
29038 # LU-8582
29039 test_905() {
29040         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29041                 skip "lustre < 2.8.54 does not support ladvise"
29042
29043         remote_ost_nodsh && skip "remote OST with nodsh"
29044         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29045
29046         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29047
29048         #define OBD_FAIL_OST_OPCODE 0x253
29049         # OST_LADVISE = 21
29050         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29051         $LFS ladvise -a willread $DIR/$tfile &&
29052                 error "unexpected success of ladvise with fault injection"
29053         $LFS ladvise -a willread $DIR/$tfile |&
29054                 grep -q "Operation not supported"
29055         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29056 }
29057 run_test 905 "bad or new opcode should not stuck client"
29058
29059 test_906() {
29060         grep -q io_uring_setup /proc/kallsyms ||
29061                 skip "Client OS does not support io_uring I/O engine"
29062         io_uring_probe || skip "kernel does not support io_uring fully"
29063         which fio || skip_env "no fio installed"
29064         fio --enghelp | grep -q io_uring ||
29065                 skip_env "fio does not support io_uring I/O engine"
29066
29067         local file=$DIR/$tfile
29068         local ioengine="io_uring"
29069         local numjobs=2
29070         local size=50M
29071
29072         fio --name=seqwrite --ioengine=$ioengine        \
29073                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29074                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29075                 error "fio seqwrite $file failed"
29076
29077         fio --name=seqread --ioengine=$ioengine \
29078                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29079                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29080                 error "fio seqread $file failed"
29081
29082         rm -f $file || error "rm -f $file failed"
29083 }
29084 run_test 906 "Simple test for io_uring I/O engine via fio"
29085
29086 complete $SECONDS
29087 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29088 check_and_cleanup_lustre
29089 if [ "$I_MOUNTED" != "yes" ]; then
29090         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29091 fi
29092 exit_status