Whamcloud - gitweb
7f55e1660eb2e81e3e179427cdf8dcae9f1a2efd
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 #                                  5              12     8   12  15   (min)"
66 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
67
68 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
69         #                                               13    (min)"
70         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
71 fi
72
73 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
74         always_except LU-1941 130b 130c 130d 130e 130f 130g
75         always_except LU-9054 312
76 fi
77
78 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
79
80 # Get the SLES distro version
81 #
82 # Returns a version string that should only be used in comparing
83 # strings returned by version_code()
84 sles_version_code()
85 {
86         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
87
88         # All SuSE Linux versions have one decimal. version_code expects two
89         local sles_version=$version.0
90         version_code $sles_version
91 }
92
93 # Check if we are running on Ubuntu or SLES so we can make decisions on
94 # what tests to run
95 if [ -r /etc/SuSE-release ]; then
96         sles_version=$(sles_version_code)
97         [ $sles_version -lt $(version_code 11.4.0) ] &&
98                 always_except LU-4341 170
99
100         [ $sles_version -lt $(version_code 12.0.0) ] &&
101                 always_except LU-3703 234
102 elif [ -r /etc/os-release ]; then
103         if grep -qi ubuntu /etc/os-release; then
104                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
105                                                 -e 's/^VERSION=//p' \
106                                                 /etc/os-release |
107                                                 awk '{ print $1 }'))
108
109                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
110                         always_except LU-10366 410
111                 fi
112         fi
113 fi
114
115 build_test_filter
116 FAIL_ON_ERROR=false
117
118 cleanup() {
119         echo -n "cln.."
120         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
121         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
122 }
123 setup() {
124         echo -n "mnt.."
125         load_modules
126         setupall || exit 10
127         echo "done"
128 }
129
130 check_swap_layouts_support()
131 {
132         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
133                 skip "Does not support layout lock."
134 }
135
136 check_swap_layout_no_dom()
137 {
138         local FOLDER=$1
139         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
140         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
141 }
142
143 check_and_setup_lustre
144 DIR=${DIR:-$MOUNT}
145 assert_DIR
146
147 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
148
149 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
150 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
151 rm -rf $DIR/[Rdfs][0-9]*
152
153 # $RUNAS_ID may get set incorrectly somewhere else
154 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
155         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
156
157 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
158
159 if [ "${ONLY}" = "MOUNT" ] ; then
160         echo "Lustre is up, please go on"
161         exit
162 fi
163
164 echo "preparing for tests involving mounts"
165 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
166 touch $EXT2_DEV
167 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
168 echo # add a newline after mke2fs.
169
170 umask 077
171
172 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
173 lctl set_param debug=-1 2> /dev/null || true
174 test_0a() {
175         touch $DIR/$tfile
176         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
177         rm $DIR/$tfile
178         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
179 }
180 run_test 0a "touch; rm ====================="
181
182 test_0b() {
183         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
184         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
185 }
186 run_test 0b "chmod 0755 $DIR ============================="
187
188 test_0c() {
189         $LCTL get_param mdc.*.import | grep "state: FULL" ||
190                 error "import not FULL"
191         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
192                 error "bad target"
193 }
194 run_test 0c "check import proc"
195
196 test_0d() { # LU-3397
197         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
198                 skip "proc exports not supported before 2.10.57"
199
200         local mgs_exp="mgs.MGS.exports"
201         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
202         local exp_client_nid
203         local exp_client_version
204         local exp_val
205         local imp_val
206         local temp_imp=$DIR/$tfile.import
207         local temp_exp=$DIR/$tfile.export
208
209         # save mgc import file to $temp_imp
210         $LCTL get_param mgc.*.import | tee $temp_imp
211         # Check if client uuid is found in MGS export
212         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
213                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
214                         $client_uuid ] &&
215                         break;
216         done
217         # save mgs export file to $temp_exp
218         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
219
220         # Compare the value of field "connect_flags"
221         imp_val=$(grep "connect_flags" $temp_imp)
222         exp_val=$(grep "connect_flags" $temp_exp)
223         [ "$exp_val" == "$imp_val" ] ||
224                 error "export flags '$exp_val' != import flags '$imp_val'"
225
226         # Compare client versions.  Only compare top-3 fields for compatibility
227         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
228         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
229         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
230         [ "$exp_val" == "$imp_val" ] ||
231                 error "exp version '$exp_client_version'($exp_val) != " \
232                         "'$(lustre_build_version client)'($imp_val)"
233 }
234 run_test 0d "check export proc ============================="
235
236 test_0e() { # LU-13417
237         (( $MDSCOUNT > 1 )) ||
238                 skip "We need at least 2 MDTs for this test"
239
240         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
241                 skip "Need server version at least 2.14.51"
242
243         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
244         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
245
246         [ $default_lmv_count -eq 1 ] ||
247                 error "$MOUNT default stripe count $default_lmv_count"
248
249         [ $default_lmv_index -eq -1 ] ||
250                 error "$MOUNT default stripe index $default_lmv_index"
251
252         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
253         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
254
255         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
256         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
257
258         [ $mdt_index1 -eq $mdt_index2 ] &&
259                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
260
261         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
262 }
263 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
264
265 test_1() {
266         test_mkdir $DIR/$tdir
267         test_mkdir $DIR/$tdir/d2
268         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
269         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
270         rmdir $DIR/$tdir/d2
271         rmdir $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
273 }
274 run_test 1 "mkdir; remkdir; rmdir"
275
276 test_2() {
277         test_mkdir $DIR/$tdir
278         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
279         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
280         rm -r $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
282 }
283 run_test 2 "mkdir; touch; rmdir; check file"
284
285 test_3() {
286         test_mkdir $DIR/$tdir
287         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
288         touch $DIR/$tdir/$tfile
289         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
290         rm -r $DIR/$tdir
291         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
292 }
293 run_test 3 "mkdir; touch; rmdir; check dir"
294
295 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
296 test_4() {
297         test_mkdir -i 1 $DIR/$tdir
298
299         touch $DIR/$tdir/$tfile ||
300                 error "Create file under remote directory failed"
301
302         rmdir $DIR/$tdir &&
303                 error "Expect error removing in-use dir $DIR/$tdir"
304
305         test -d $DIR/$tdir || error "Remote directory disappeared"
306
307         rm -rf $DIR/$tdir || error "remove remote dir error"
308 }
309 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
310
311 test_5() {
312         test_mkdir $DIR/$tdir
313         test_mkdir $DIR/$tdir/d2
314         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
315         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
316         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
317 }
318 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
319
320 test_6a() {
321         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
322         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
323         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
324                 error "$tfile does not have perm 0666 or UID $UID"
325         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile should be 0666 and owned by UID $UID"
328 }
329 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
330
331 test_6c() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         touch $DIR/$tfile
335         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
336         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
337                 error "$tfile should be owned by UID $RUNAS_ID"
338         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341 }
342 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
343
344 test_6e() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by GID $UID"
351         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
354 }
355 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
356
357 test_6g() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         test_mkdir $DIR/$tdir
361         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
362         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
363         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
364         test_mkdir $DIR/$tdir/d/subdir
365         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
366                 error "$tdir/d/subdir should be GID $RUNAS_GID"
367         if [[ $MDSCOUNT -gt 1 ]]; then
368                 # check remote dir sgid inherite
369                 $LFS mkdir -i 0 $DIR/$tdir.local ||
370                         error "mkdir $tdir.local failed"
371                 chmod g+s $DIR/$tdir.local ||
372                         error "chmod $tdir.local failed"
373                 chgrp $RUNAS_GID $DIR/$tdir.local ||
374                         error "chgrp $tdir.local failed"
375                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
376                         error "mkdir $tdir.remote failed"
377                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
378                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
379                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
380                         error "$tdir.remote should be mode 02755"
381         fi
382 }
383 run_test 6g "verify new dir in sgid dir inherits group"
384
385 test_6h() { # bug 7331
386         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
387
388         touch $DIR/$tfile || error "touch failed"
389         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
390         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
391                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
392         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
393                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
394 }
395 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
396
397 test_7a() {
398         test_mkdir $DIR/$tdir
399         $MCREATE $DIR/$tdir/$tfile
400         chmod 0666 $DIR/$tdir/$tfile
401         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
402                 error "$tdir/$tfile should be mode 0666"
403 }
404 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
405
406 test_7b() {
407         if [ ! -d $DIR/$tdir ]; then
408                 test_mkdir $DIR/$tdir
409         fi
410         $MCREATE $DIR/$tdir/$tfile
411         echo -n foo > $DIR/$tdir/$tfile
412         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
413         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
414 }
415 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
416
417 test_8() {
418         test_mkdir $DIR/$tdir
419         touch $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tfile mode not 0666"
423 }
424 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
425
426 test_9() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         test_mkdir $DIR/$tdir/d2/d3
430         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
431 }
432 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
433
434 test_10() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         touch $DIR/$tdir/d2/$tfile
438         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
439                 error "$tdir/d2/$tfile not a file"
440 }
441 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
442
443 test_11() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         chmod 0666 $DIR/$tdir/d2
447         chmod 0705 $DIR/$tdir/d2
448         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
449                 error "$tdir/d2 mode not 0705"
450 }
451 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
452
453 test_12() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         chmod 0666 $DIR/$tdir/$tfile
457         chmod 0654 $DIR/$tdir/$tfile
458         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
459                 error "$tdir/d2 mode not 0654"
460 }
461 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
462
463 test_13() {
464         test_mkdir $DIR/$tdir
465         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
466         >  $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
468                 error "$tdir/$tfile size not 0 after truncate"
469 }
470 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
471
472 test_14() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         rm $DIR/$tdir/$tfile
476         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
477 }
478 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
479
480 test_15() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
484         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
485                 error "$tdir/${tfile_2} not a file after rename"
486         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
487 }
488 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
489
490 test_16() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         rm -rf $DIR/$tdir/$tfile
494         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
495 }
496 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
497
498 test_17a() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
502         ls -l $DIR/$tdir
503         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
504                 error "$tdir/l-exist not a symlink"
505         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
506                 error "$tdir/l-exist not referencing a file"
507         rm -f $DIR/$tdir/l-exist
508         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
509 }
510 run_test 17a "symlinks: create, remove (real)"
511
512 test_17b() {
513         test_mkdir $DIR/$tdir
514         ln -s no-such-file $DIR/$tdir/l-dangle
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
517                 error "$tdir/l-dangle not referencing no-such-file"
518         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
519                 error "$tdir/l-dangle not referencing non-existent file"
520         rm -f $DIR/$tdir/l-dangle
521         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
522 }
523 run_test 17b "symlinks: create, remove (dangling)"
524
525 test_17c() { # bug 3440 - don't save failed open RPC for replay
526         test_mkdir $DIR/$tdir
527         ln -s foo $DIR/$tdir/$tfile
528         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
529 }
530 run_test 17c "symlinks: open dangling (should return error)"
531
532 test_17d() {
533         test_mkdir $DIR/$tdir
534         ln -s foo $DIR/$tdir/$tfile
535         touch $DIR/$tdir/$tfile || error "creating to new symlink"
536 }
537 run_test 17d "symlinks: create dangling"
538
539 test_17e() {
540         test_mkdir $DIR/$tdir
541         local foo=$DIR/$tdir/$tfile
542         ln -s $foo $foo || error "create symlink failed"
543         ls -l $foo || error "ls -l failed"
544         ls $foo && error "ls not failed" || true
545 }
546 run_test 17e "symlinks: create recursive symlink (should return error)"
547
548 test_17f() {
549         test_mkdir $DIR/$tdir
550         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
556         ls -l  $DIR/$tdir
557 }
558 run_test 17f "symlinks: long and very long symlink name"
559
560 # str_repeat(S, N) generate a string that is string S repeated N times
561 str_repeat() {
562         local s=$1
563         local n=$2
564         local ret=''
565         while [ $((n -= 1)) -ge 0 ]; do
566                 ret=$ret$s
567         done
568         echo $ret
569 }
570
571 # Long symlinks and LU-2241
572 test_17g() {
573         test_mkdir $DIR/$tdir
574         local TESTS="59 60 61 4094 4095"
575
576         # Fix for inode size boundary in 2.1.4
577         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
578                 TESTS="4094 4095"
579
580         # Patch not applied to 2.2 or 2.3 branches
581         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
582         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
583                 TESTS="4094 4095"
584
585         for i in $TESTS; do
586                 local SYMNAME=$(str_repeat 'x' $i)
587                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
588                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
589         done
590 }
591 run_test 17g "symlinks: really long symlink name and inode boundaries"
592
593 test_17h() { #bug 17378
594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
595         remote_mds_nodsh && skip "remote MDS with nodsh"
596
597         local mdt_idx
598
599         test_mkdir $DIR/$tdir
600         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
601         $LFS setstripe -c -1 $DIR/$tdir
602         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
603         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
604         touch $DIR/$tdir/$tfile || true
605 }
606 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
607
608 test_17i() { #bug 20018
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         remote_mds_nodsh && skip "remote MDS with nodsh"
611
612         local foo=$DIR/$tdir/$tfile
613         local mdt_idx
614
615         test_mkdir -c1 $DIR/$tdir
616         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
617         ln -s $foo $foo || error "create symlink failed"
618 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
619         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
620         ls -l $foo && error "error not detected"
621         return 0
622 }
623 run_test 17i "don't panic on short symlink (should return error)"
624
625 test_17k() { #bug 22301
626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
627         [[ -z "$(which rsync 2>/dev/null)" ]] &&
628                 skip "no rsync command"
629         rsync --help | grep -q xattr ||
630                 skip_env "$(rsync --version | head -n1) does not support xattrs"
631         test_mkdir $DIR/$tdir
632         test_mkdir $DIR/$tdir.new
633         touch $DIR/$tdir/$tfile
634         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
635         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
636                 error "rsync failed with xattrs enabled"
637 }
638 run_test 17k "symlinks: rsync with xattrs enabled"
639
640 test_17l() { # LU-279
641         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
642                 skip "no getfattr command"
643
644         test_mkdir $DIR/$tdir
645         touch $DIR/$tdir/$tfile
646         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
647         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
648                 # -h to not follow symlinks. -m '' to list all the xattrs.
649                 # grep to remove first line: '# file: $path'.
650                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
651                 do
652                         lgetxattr_size_check $path $xattr ||
653                                 error "lgetxattr_size_check $path $xattr failed"
654                 done
655         done
656 }
657 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
658
659 # LU-1540
660 test_17m() {
661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
663         remote_mds_nodsh && skip "remote MDS with nodsh"
664         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
665         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
666                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
667
668         local short_sym="0123456789"
669         local wdir=$DIR/$tdir
670         local i
671
672         test_mkdir $wdir
673         long_sym=$short_sym
674         # create a long symlink file
675         for ((i = 0; i < 4; ++i)); do
676                 long_sym=${long_sym}${long_sym}
677         done
678
679         echo "create 512 short and long symlink files under $wdir"
680         for ((i = 0; i < 256; ++i)); do
681                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
682                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
683         done
684
685         echo "erase them"
686         rm -f $wdir/*
687         sync
688         wait_delete_completed
689
690         echo "recreate the 512 symlink files with a shorter string"
691         for ((i = 0; i < 512; ++i)); do
692                 # rewrite the symlink file with a shorter string
693                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
694                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
695         done
696
697         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
698
699         echo "stop and checking mds${mds_index}:"
700         # e2fsck should not return error
701         stop mds${mds_index}
702         local devname=$(mdsdevname $mds_index)
703         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
704         rc=$?
705
706         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
707                 error "start mds${mds_index} failed"
708         df $MOUNT > /dev/null 2>&1
709         [ $rc -eq 0 ] ||
710                 error "e2fsck detected error for short/long symlink: rc=$rc"
711         rm -f $wdir/*
712 }
713 run_test 17m "run e2fsck against MDT which contains short/long symlink"
714
715 check_fs_consistency_17n() {
716         local mdt_index
717         local rc=0
718
719         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
720         # so it only check MDT1/MDT2 instead of all of MDTs.
721         for mdt_index in 1 2; do
722                 # e2fsck should not return error
723                 stop mds${mdt_index}
724                 local devname=$(mdsdevname $mdt_index)
725                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
726                         rc=$((rc + $?))
727
728                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
729                         error "mount mds$mdt_index failed"
730                 df $MOUNT > /dev/null 2>&1
731         done
732         return $rc
733 }
734
735 test_17n() {
736         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
738         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
739         remote_mds_nodsh && skip "remote MDS with nodsh"
740         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
741         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
742                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
743
744         local i
745
746         test_mkdir $DIR/$tdir
747         for ((i=0; i<10; i++)); do
748                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
749                         error "create remote dir error $i"
750                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
751                         error "create files under remote dir failed $i"
752         done
753
754         check_fs_consistency_17n ||
755                 error "e2fsck report error after create files under remote dir"
756
757         for ((i = 0; i < 10; i++)); do
758                 rm -rf $DIR/$tdir/remote_dir_${i} ||
759                         error "destroy remote dir error $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after unlink files under remote dir"
764
765         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
766                 skip "lustre < 2.4.50 does not support migrate mv"
767
768         for ((i = 0; i < 10; i++)); do
769                 mkdir -p $DIR/$tdir/remote_dir_${i}
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
773                         error "migrate remote dir error $i"
774         done
775         check_fs_consistency_17n || error "e2fsck report error after migration"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n || error "e2fsck report error after unlink"
783 }
784 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
785
786 test_17o() {
787         remote_mds_nodsh && skip "remote MDS with nodsh"
788         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
789                 skip "Need MDS version at least 2.3.64"
790
791         local wdir=$DIR/${tdir}o
792         local mdt_index
793         local rc=0
794
795         test_mkdir $wdir
796         touch $wdir/$tfile
797         mdt_index=$($LFS getstripe -m $wdir/$tfile)
798         mdt_index=$((mdt_index + 1))
799
800         cancel_lru_locks mdc
801         #fail mds will wait the failover finish then set
802         #following fail_loc to avoid interfer the recovery process.
803         fail mds${mdt_index}
804
805         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
806         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
807         ls -l $wdir/$tfile && rc=1
808         do_facet mds${mdt_index} lctl set_param fail_loc=0
809         [[ $rc -eq 0 ]] || error "stat file should fail"
810 }
811 run_test 17o "stat file with incompat LMA feature"
812
813 test_18() {
814         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
815         ls $DIR || error "Failed to ls $DIR: $?"
816 }
817 run_test 18 "touch .../f ; ls ... =============================="
818
819 test_19a() {
820         touch $DIR/$tfile
821         ls -l $DIR
822         rm $DIR/$tfile
823         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
824 }
825 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
826
827 test_19b() {
828         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
829 }
830 run_test 19b "ls -l .../f19 (should return error) =============="
831
832 test_19c() {
833         [ $RUNAS_ID -eq $UID ] &&
834                 skip_env "RUNAS_ID = UID = $UID -- skipping"
835
836         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
837 }
838 run_test 19c "$RUNAS touch .../f19 (should return error) =="
839
840 test_19d() {
841         cat $DIR/f19 && error || true
842 }
843 run_test 19d "cat .../f19 (should return error) =============="
844
845 test_20() {
846         touch $DIR/$tfile
847         rm $DIR/$tfile
848         touch $DIR/$tfile
849         rm $DIR/$tfile
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
853 }
854 run_test 20 "touch .../f ; ls -l ..."
855
856 test_21() {
857         test_mkdir $DIR/$tdir
858         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
859         ln -s dangle $DIR/$tdir/link
860         echo foo >> $DIR/$tdir/link
861         cat $DIR/$tdir/dangle
862         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
863         $CHECKSTAT -f -t file $DIR/$tdir/link ||
864                 error "$tdir/link not linked to a file"
865 }
866 run_test 21 "write to dangling link"
867
868 test_22() {
869         local wdir=$DIR/$tdir
870         test_mkdir $wdir
871         chown $RUNAS_ID:$RUNAS_GID $wdir
872         (cd $wdir || error "cd $wdir failed";
873                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
874                 $RUNAS tar xf -)
875         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
876         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
877         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
878                 error "checkstat -u failed"
879 }
880 run_test 22 "unpack tar archive as non-root user"
881
882 # was test_23
883 test_23a() {
884         test_mkdir $DIR/$tdir
885         local file=$DIR/$tdir/$tfile
886
887         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
888         openfile -f O_CREAT:O_EXCL $file &&
889                 error "$file recreate succeeded" || true
890 }
891 run_test 23a "O_CREAT|O_EXCL in subdir"
892
893 test_23b() { # bug 18988
894         test_mkdir $DIR/$tdir
895         local file=$DIR/$tdir/$tfile
896
897         rm -f $file
898         echo foo > $file || error "write filed"
899         echo bar >> $file || error "append filed"
900         $CHECKSTAT -s 8 $file || error "wrong size"
901         rm $file
902 }
903 run_test 23b "O_APPEND check"
904
905 # LU-9409, size with O_APPEND and tiny writes
906 test_23c() {
907         local file=$DIR/$tfile
908
909         # single dd
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
911         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
912         rm -f $file
913
914         # racing tiny writes
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
917         wait
918         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
919         rm -f $file
920
921         #racing tiny & normal writes
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
924         wait
925         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
926         rm -f $file
927
928         #racing tiny & normal writes 2, ugly numbers
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
931         wait
932         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
933         rm -f $file
934 }
935 run_test 23c "O_APPEND size checks for tiny writes"
936
937 # LU-11069 file offset is correct after appending writes
938 test_23d() {
939         local file=$DIR/$tfile
940         local offset
941
942         echo CentaurHauls > $file
943         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
944         if ((offset != 26)); then
945                 error "wrong offset, expected 26, got '$offset'"
946         fi
947 }
948 run_test 23d "file offset is correct after appending writes"
949
950 # rename sanity
951 test_24a() {
952         echo '-- same directory rename'
953         test_mkdir $DIR/$tdir
954         touch $DIR/$tdir/$tfile.1
955         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
956         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
957 }
958 run_test 24a "rename file to non-existent target"
959
960 test_24b() {
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.{1,2}
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24b "rename file to existing target"
968
969 test_24c() {
970         test_mkdir $DIR/$tdir
971         test_mkdir $DIR/$tdir/d$testnum.1
972         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
973         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
974         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
975 }
976 run_test 24c "rename directory to non-existent target"
977
978 test_24d() {
979         test_mkdir -c1 $DIR/$tdir
980         test_mkdir -c1 $DIR/$tdir/d$testnum.1
981         test_mkdir -c1 $DIR/$tdir/d$testnum.2
982         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
983         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
984         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
985 }
986 run_test 24d "rename directory to existing target"
987
988 test_24e() {
989         echo '-- cross directory renames --'
990         test_mkdir $DIR/R5a
991         test_mkdir $DIR/R5b
992         touch $DIR/R5a/f
993         mv $DIR/R5a/f $DIR/R5b/g
994         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
995         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
996 }
997 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
998
999 test_24f() {
1000         test_mkdir $DIR/R6a
1001         test_mkdir $DIR/R6b
1002         touch $DIR/R6a/f $DIR/R6b/g
1003         mv $DIR/R6a/f $DIR/R6b/g
1004         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1005         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1006 }
1007 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1008
1009 test_24g() {
1010         test_mkdir $DIR/R7a
1011         test_mkdir $DIR/R7b
1012         test_mkdir $DIR/R7a/d
1013         mv $DIR/R7a/d $DIR/R7b/e
1014         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1015         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1016 }
1017 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1018
1019 test_24h() {
1020         test_mkdir -c1 $DIR/R8a
1021         test_mkdir -c1 $DIR/R8b
1022         test_mkdir -c1 $DIR/R8a/d
1023         test_mkdir -c1 $DIR/R8b/e
1024         mrename $DIR/R8a/d $DIR/R8b/e
1025         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1026         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1027 }
1028 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1029
1030 test_24i() {
1031         echo "-- rename error cases"
1032         test_mkdir $DIR/R9
1033         test_mkdir $DIR/R9/a
1034         touch $DIR/R9/f
1035         mrename $DIR/R9/f $DIR/R9/a
1036         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1037         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1038         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1039 }
1040 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1041
1042 test_24j() {
1043         test_mkdir $DIR/R10
1044         mrename $DIR/R10/f $DIR/R10/g
1045         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1046         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1047         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1048 }
1049 run_test 24j "source does not exist ============================"
1050
1051 test_24k() {
1052         test_mkdir $DIR/R11a
1053         test_mkdir $DIR/R11a/d
1054         touch $DIR/R11a/f
1055         mv $DIR/R11a/f $DIR/R11a/d
1056         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1057         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1058 }
1059 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1060
1061 # bug 2429 - rename foo foo foo creates invalid file
1062 test_24l() {
1063         f="$DIR/f24l"
1064         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1065 }
1066 run_test 24l "Renaming a file to itself ========================"
1067
1068 test_24m() {
1069         f="$DIR/f24m"
1070         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1071         # on ext3 this does not remove either the source or target files
1072         # though the "expected" operation would be to remove the source
1073         $CHECKSTAT -t file ${f} || error "${f} missing"
1074         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1075 }
1076 run_test 24m "Renaming a file to a hard link to itself ========="
1077
1078 test_24n() {
1079     f="$DIR/f24n"
1080     # this stats the old file after it was renamed, so it should fail
1081     touch ${f}
1082     $CHECKSTAT ${f} || error "${f} missing"
1083     mv ${f} ${f}.rename
1084     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1085     $CHECKSTAT -a ${f} || error "${f} exists"
1086 }
1087 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1088
1089 test_24o() {
1090         test_mkdir $DIR/$tdir
1091         rename_many -s random -v -n 10 $DIR/$tdir
1092 }
1093 run_test 24o "rename of files during htree split"
1094
1095 test_24p() {
1096         test_mkdir $DIR/R12a
1097         test_mkdir $DIR/R12b
1098         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1099         mrename $DIR/R12a $DIR/R12b
1100         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1101         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1102         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1103         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1104 }
1105 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1106
1107 cleanup_multiop_pause() {
1108         trap 0
1109         kill -USR1 $MULTIPID
1110 }
1111
1112 test_24q() {
1113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1114
1115         test_mkdir $DIR/R13a
1116         test_mkdir $DIR/R13b
1117         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1118         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1119         MULTIPID=$!
1120
1121         trap cleanup_multiop_pause EXIT
1122         mrename $DIR/R13a $DIR/R13b
1123         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1124         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1125         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1126         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1127         cleanup_multiop_pause
1128         wait $MULTIPID || error "multiop close failed"
1129 }
1130 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1131
1132 test_24r() { #bug 3789
1133         test_mkdir $DIR/R14a
1134         test_mkdir $DIR/R14a/b
1135         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1137         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1138 }
1139 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1140
1141 test_24s() {
1142         test_mkdir $DIR/R15a
1143         test_mkdir $DIR/R15a/b
1144         test_mkdir $DIR/R15a/b/c
1145         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1147         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1148 }
1149 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1150
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27cg() {
1714         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1715                 skip "server does not support overstriping"
1716         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1717         large_xattr_enabled || skip_env "ea_inode feature disabled"
1718
1719         local osts="0"
1720
1721         for ((i=1;i<1000;i++)); do
1722                 osts+=",$((i % OSTCOUNT))"
1723         done
1724
1725         local mdts=$(comma_list $(mdts_nodes))
1726         local before=$(do_nodes $mdts \
1727                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1728                 awk '/many credits/{print $3}' |
1729                 calc_sum)
1730
1731         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1732         $LFS getstripe $DIR/$tfile | grep stripe
1733
1734         rm -f $DIR/$tfile || error "can't unlink"
1735
1736         after=$(do_nodes $mdts \
1737                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1738                 awk '/many credits/{print $3}' |
1739                 calc_sum)
1740
1741         (( before == after )) ||
1742                 error "too many credits happened: $after > $before"
1743 }
1744 run_test 27cg "1000 shouldn't cause too many credits"
1745
1746 test_27d() {
1747         test_mkdir $DIR/$tdir
1748         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1749                 error "setstripe failed"
1750         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1751         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1752 }
1753 run_test 27d "create file with default settings"
1754
1755 test_27e() {
1756         # LU-5839 adds check for existed layout before setting it
1757         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1758                 skip "Need MDS version at least 2.7.56"
1759
1760         test_mkdir $DIR/$tdir
1761         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1762         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1763         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1764 }
1765 run_test 27e "setstripe existing file (should return error)"
1766
1767 test_27f() {
1768         test_mkdir $DIR/$tdir
1769         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1770                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1771         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1772                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1773         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1774         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1775 }
1776 run_test 27f "setstripe with bad stripe size (should return error)"
1777
1778 test_27g() {
1779         test_mkdir $DIR/$tdir
1780         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1781         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1782                 error "$DIR/$tdir/$tfile has object"
1783 }
1784 run_test 27g "$LFS getstripe with no objects"
1785
1786 test_27ga() {
1787         test_mkdir $DIR/$tdir
1788         touch $DIR/$tdir/$tfile || error "touch failed"
1789         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1790         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1791         local rc=$?
1792         (( rc == 2 )) || error "getstripe did not return ENOENT"
1793 }
1794 run_test 27ga "$LFS getstripe with missing file (should return error)"
1795
1796 test_27i() {
1797         test_mkdir $DIR/$tdir
1798         touch $DIR/$tdir/$tfile || error "touch failed"
1799         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1800                 error "missing objects"
1801 }
1802 run_test 27i "$LFS getstripe with some objects"
1803
1804 test_27j() {
1805         test_mkdir $DIR/$tdir
1806         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1807                 error "setstripe failed" || true
1808 }
1809 run_test 27j "setstripe with bad stripe offset (should return error)"
1810
1811 test_27k() { # bug 2844
1812         test_mkdir $DIR/$tdir
1813         local file=$DIR/$tdir/$tfile
1814         local ll_max_blksize=$((4 * 1024 * 1024))
1815         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1816         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1817         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1818         dd if=/dev/zero of=$file bs=4k count=1
1819         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1820         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1821 }
1822 run_test 27k "limit i_blksize for broken user apps"
1823
1824 test_27l() {
1825         mcreate $DIR/$tfile || error "creating file"
1826         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1827                 error "setstripe should have failed" || true
1828 }
1829 run_test 27l "check setstripe permissions (should return error)"
1830
1831 test_27m() {
1832         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1833
1834         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1835                 skip_env "multiple clients -- skipping"
1836
1837         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1838                    head -n1)
1839         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1840                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1841         fi
1842         stack_trap simple_cleanup_common
1843         test_mkdir $DIR/$tdir
1844         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1845         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1846                 error "dd should fill OST0"
1847         i=2
1848         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1849                 i=$((i + 1))
1850                 [ $i -gt 256 ] && break
1851         done
1852         i=$((i + 1))
1853         touch $DIR/$tdir/$tfile.$i
1854         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1855             awk '{print $1}'| grep -w "0") ] &&
1856                 error "OST0 was full but new created file still use it"
1857         i=$((i + 1))
1858         touch $DIR/$tdir/$tfile.$i
1859         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1860             awk '{print $1}'| grep -w "0") ] &&
1861                 error "OST0 was full but new created file still use it" || true
1862 }
1863 run_test 27m "create file while OST0 was full"
1864
1865 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1866 # if the OST isn't full anymore.
1867 reset_enospc() {
1868         local ostidx=${1:-""}
1869         local delay
1870         local ready
1871         local get_prealloc
1872
1873         local list=$(comma_list $(osts_nodes))
1874         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1875
1876         do_nodes $list lctl set_param fail_loc=0
1877         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1878         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1879                 awk '{print $1 * 2;exit;}')
1880         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1881                         grep -v \"^0$\""
1882         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1883 }
1884
1885 test_27n() {
1886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1888         remote_mds_nodsh && skip "remote MDS with nodsh"
1889         remote_ost_nodsh && skip "remote OST with nodsh"
1890
1891         reset_enospc
1892         rm -f $DIR/$tdir/$tfile
1893         exhaust_precreations 0 0x80000215
1894         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1895         touch $DIR/$tdir/$tfile || error "touch failed"
1896         $LFS getstripe $DIR/$tdir/$tfile
1897         reset_enospc
1898 }
1899 run_test 27n "create file with some full OSTs"
1900
1901 test_27o() {
1902         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1904         remote_mds_nodsh && skip "remote MDS with nodsh"
1905         remote_ost_nodsh && skip "remote OST with nodsh"
1906
1907         reset_enospc
1908         rm -f $DIR/$tdir/$tfile
1909         exhaust_all_precreations 0x215
1910
1911         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1912
1913         reset_enospc
1914         rm -rf $DIR/$tdir/*
1915 }
1916 run_test 27o "create file with all full OSTs (should error)"
1917
1918 function create_and_checktime() {
1919         local fname=$1
1920         local loops=$2
1921         local i
1922
1923         for ((i=0; i < $loops; i++)); do
1924                 local start=$SECONDS
1925                 multiop $fname-$i Oc
1926                 ((SECONDS-start < TIMEOUT)) ||
1927                         error "creation took " $((SECONDS-$start)) && return 1
1928         done
1929 }
1930
1931 test_27oo() {
1932         local mdts=$(comma_list $(mdts_nodes))
1933
1934         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1935                 skip "Need MDS version at least 2.13.57"
1936
1937         local f0=$DIR/${tfile}-0
1938         local f1=$DIR/${tfile}-1
1939
1940         wait_delete_completed
1941
1942         # refill precreated objects
1943         $LFS setstripe -i0 -c1 $f0
1944
1945         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1946         # force QoS allocation policy
1947         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1948         stack_trap "do_nodes $mdts $LCTL set_param \
1949                 lov.*.qos_threshold_rr=$saved" EXIT
1950         sleep_maxage
1951
1952         # one OST is unavailable, but still have few objects preallocated
1953         stop ost1
1954         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1955                 rm -rf $f1 $DIR/$tdir*" EXIT
1956
1957         for ((i=0; i < 7; i++)); do
1958                 mkdir $DIR/$tdir$i || error "can't create dir"
1959                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1960                         error "can't set striping"
1961         done
1962         for ((i=0; i < 7; i++)); do
1963                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1964         done
1965         wait
1966 }
1967 run_test 27oo "don't let few threads to reserve too many objects"
1968
1969 test_27p() {
1970         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973         remote_ost_nodsh && skip "remote OST with nodsh"
1974
1975         reset_enospc
1976         rm -f $DIR/$tdir/$tfile
1977         test_mkdir $DIR/$tdir
1978
1979         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1980         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1981         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1982
1983         exhaust_precreations 0 0x80000215
1984         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1985         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1986         $LFS getstripe $DIR/$tdir/$tfile
1987
1988         reset_enospc
1989 }
1990 run_test 27p "append to a truncated file with some full OSTs"
1991
1992 test_27q() {
1993         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1995         remote_mds_nodsh && skip "remote MDS with nodsh"
1996         remote_ost_nodsh && skip "remote OST with nodsh"
1997
1998         reset_enospc
1999         rm -f $DIR/$tdir/$tfile
2000
2001         mkdir_on_mdt0 $DIR/$tdir
2002         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2003         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2004                 error "truncate $DIR/$tdir/$tfile failed"
2005         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2006
2007         exhaust_all_precreations 0x215
2008
2009         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2010         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2011
2012         reset_enospc
2013 }
2014 run_test 27q "append to truncated file with all OSTs full (should error)"
2015
2016 test_27r() {
2017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2019         remote_mds_nodsh && skip "remote MDS with nodsh"
2020         remote_ost_nodsh && skip "remote OST with nodsh"
2021
2022         reset_enospc
2023         rm -f $DIR/$tdir/$tfile
2024         exhaust_precreations 0 0x80000215
2025
2026         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2027
2028         reset_enospc
2029 }
2030 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2031
2032 test_27s() { # bug 10725
2033         test_mkdir $DIR/$tdir
2034         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2035         local stripe_count=0
2036         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2037         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2038                 error "stripe width >= 2^32 succeeded" || true
2039
2040 }
2041 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2042
2043 test_27t() { # bug 10864
2044         WDIR=$(pwd)
2045         WLFS=$(which lfs)
2046         cd $DIR
2047         touch $tfile
2048         $WLFS getstripe $tfile
2049         cd $WDIR
2050 }
2051 run_test 27t "check that utils parse path correctly"
2052
2053 test_27u() { # bug 4900
2054         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2055         remote_mds_nodsh && skip "remote MDS with nodsh"
2056
2057         local index
2058         local list=$(comma_list $(mdts_nodes))
2059
2060 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2061         do_nodes $list $LCTL set_param fail_loc=0x139
2062         test_mkdir -p $DIR/$tdir
2063         stack_trap "simple_cleanup_common 1000"
2064         createmany -o $DIR/$tdir/$tfile 1000
2065         do_nodes $list $LCTL set_param fail_loc=0
2066
2067         TLOG=$TMP/$tfile.getstripe
2068         $LFS getstripe $DIR/$tdir > $TLOG
2069         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2070         [[ $OBJS -gt 0 ]] &&
2071                 error "$OBJS objects created on OST-0. See $TLOG" ||
2072                 rm -f $TLOG
2073 }
2074 run_test 27u "skip object creation on OSC w/o objects"
2075
2076 test_27v() { # bug 4900
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2079         remote_mds_nodsh && skip "remote MDS with nodsh"
2080         remote_ost_nodsh && skip "remote OST with nodsh"
2081
2082         exhaust_all_precreations 0x215
2083         reset_enospc
2084
2085         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2086
2087         touch $DIR/$tdir/$tfile
2088         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2089         # all except ost1
2090         for (( i=1; i < OSTCOUNT; i++ )); do
2091                 do_facet ost$i lctl set_param fail_loc=0x705
2092         done
2093         local START=`date +%s`
2094         createmany -o $DIR/$tdir/$tfile 32
2095
2096         local FINISH=`date +%s`
2097         local TIMEOUT=`lctl get_param -n timeout`
2098         local PROCESS=$((FINISH - START))
2099         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2100                error "$FINISH - $START >= $TIMEOUT / 2"
2101         sleep $((TIMEOUT / 2 - PROCESS))
2102         reset_enospc
2103 }
2104 run_test 27v "skip object creation on slow OST"
2105
2106 test_27w() { # bug 10997
2107         test_mkdir $DIR/$tdir
2108         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2109         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2110                 error "stripe size $size != 65536" || true
2111         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2112                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2113 }
2114 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2115
2116 test_27wa() {
2117         [[ $OSTCOUNT -lt 2 ]] &&
2118                 skip_env "skipping multiple stripe count/offset test"
2119
2120         test_mkdir $DIR/$tdir
2121         for i in $(seq 1 $OSTCOUNT); do
2122                 offset=$((i - 1))
2123                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2124                         error "setstripe -c $i -i $offset failed"
2125                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2126                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2127                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2128                 [ $index -ne $offset ] &&
2129                         error "stripe offset $index != $offset" || true
2130         done
2131 }
2132 run_test 27wa "check $LFS setstripe -c -i options"
2133
2134 test_27x() {
2135         remote_ost_nodsh && skip "remote OST with nodsh"
2136         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2138
2139         OFFSET=$(($OSTCOUNT - 1))
2140         OSTIDX=0
2141         local OST=$(ostname_from_index $OSTIDX)
2142
2143         test_mkdir $DIR/$tdir
2144         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2145         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2146         sleep_maxage
2147         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2148         for i in $(seq 0 $OFFSET); do
2149                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2150                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2151                 error "OST0 was degraded but new created file still use it"
2152         done
2153         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2154 }
2155 run_test 27x "create files while OST0 is degraded"
2156
2157 test_27y() {
2158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2159         remote_mds_nodsh && skip "remote MDS with nodsh"
2160         remote_ost_nodsh && skip "remote OST with nodsh"
2161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2162
2163         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2164         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2165                 osp.$mdtosc.prealloc_last_id)
2166         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2167                 osp.$mdtosc.prealloc_next_id)
2168         local fcount=$((last_id - next_id))
2169         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2170         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2171
2172         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2173                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2174         local OST_DEACTIVE_IDX=-1
2175         local OSC
2176         local OSTIDX
2177         local OST
2178
2179         for OSC in $MDS_OSCS; do
2180                 OST=$(osc_to_ost $OSC)
2181                 OSTIDX=$(index_from_ostuuid $OST)
2182                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2183                         OST_DEACTIVE_IDX=$OSTIDX
2184                 fi
2185                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2186                         echo $OSC "is Deactivated:"
2187                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2188                 fi
2189         done
2190
2191         OSTIDX=$(index_from_ostuuid $OST)
2192         test_mkdir $DIR/$tdir
2193         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2194
2195         for OSC in $MDS_OSCS; do
2196                 OST=$(osc_to_ost $OSC)
2197                 OSTIDX=$(index_from_ostuuid $OST)
2198                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2199                         echo $OST "is degraded:"
2200                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2201                                                 obdfilter.$OST.degraded=1
2202                 fi
2203         done
2204
2205         sleep_maxage
2206         createmany -o $DIR/$tdir/$tfile $fcount
2207
2208         for OSC in $MDS_OSCS; do
2209                 OST=$(osc_to_ost $OSC)
2210                 OSTIDX=$(index_from_ostuuid $OST)
2211                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2212                         echo $OST "is recovered from degraded:"
2213                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2214                                                 obdfilter.$OST.degraded=0
2215                 else
2216                         do_facet $SINGLEMDS lctl --device %$OSC activate
2217                 fi
2218         done
2219
2220         # all osp devices get activated, hence -1 stripe count restored
2221         local stripe_count=0
2222
2223         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2224         # devices get activated.
2225         sleep_maxage
2226         $LFS setstripe -c -1 $DIR/$tfile
2227         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2228         rm -f $DIR/$tfile
2229         [ $stripe_count -ne $OSTCOUNT ] &&
2230                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2231         return 0
2232 }
2233 run_test 27y "create files while OST0 is degraded and the rest inactive"
2234
2235 check_seq_oid()
2236 {
2237         log "check file $1"
2238
2239         lmm_count=$($LFS getstripe -c $1)
2240         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2241         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2242
2243         local old_ifs="$IFS"
2244         IFS=$'[:]'
2245         fid=($($LFS path2fid $1))
2246         IFS="$old_ifs"
2247
2248         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2249         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2250
2251         # compare lmm_seq and lu_fid->f_seq
2252         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2253         # compare lmm_object_id and lu_fid->oid
2254         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2255
2256         # check the trusted.fid attribute of the OST objects of the file
2257         local have_obdidx=false
2258         local stripe_nr=0
2259         $LFS getstripe $1 | while read obdidx oid hex seq; do
2260                 # skip lines up to and including "obdidx"
2261                 [ -z "$obdidx" ] && break
2262                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2263                 $have_obdidx || continue
2264
2265                 local ost=$((obdidx + 1))
2266                 local dev=$(ostdevname $ost)
2267                 local oid_hex
2268
2269                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2270
2271                 seq=$(echo $seq | sed -e "s/^0x//g")
2272                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2273                         oid_hex=$(echo $oid)
2274                 else
2275                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2276                 fi
2277                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2278
2279                 local ff=""
2280                 #
2281                 # Don't unmount/remount the OSTs if we don't need to do that.
2282                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2283                 # update too, until that use mount/ll_decode_filter_fid/mount.
2284                 # Re-enable when debugfs will understand new filter_fid.
2285                 #
2286                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2287                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2288                                 $dev 2>/dev/null" | grep "parent=")
2289                 fi
2290                 if [ -z "$ff" ]; then
2291                         stop ost$ost
2292                         mount_fstype ost$ost
2293                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2294                                 $(facet_mntpt ost$ost)/$obj_file)
2295                         unmount_fstype ost$ost
2296                         start ost$ost $dev $OST_MOUNT_OPTS
2297                         clients_up
2298                 fi
2299
2300                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2301
2302                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2303
2304                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2305                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2306                 #
2307                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2308                 #       stripe_size=1048576 component_id=1 component_start=0 \
2309                 #       component_end=33554432
2310                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2311                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2312                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2313                 local ff_pstripe
2314                 if grep -q 'stripe=' <<<$ff; then
2315                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2316                 else
2317                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2318                         # into f_ver in this case.  See comment on ff_parent.
2319                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2320                 fi
2321
2322                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2323                 [ $ff_pseq = $lmm_seq ] ||
2324                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2325                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2326                 [ $ff_poid = $lmm_oid ] ||
2327                         error "FF parent OID $ff_poid != $lmm_oid"
2328                 (($ff_pstripe == $stripe_nr)) ||
2329                         error "FF stripe $ff_pstripe != $stripe_nr"
2330
2331                 stripe_nr=$((stripe_nr + 1))
2332                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2333                         continue
2334                 if grep -q 'stripe_count=' <<<$ff; then
2335                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2336                                             -e 's/ .*//' <<<$ff)
2337                         [ $lmm_count = $ff_scnt ] ||
2338                                 error "FF stripe count $lmm_count != $ff_scnt"
2339                 fi
2340         done
2341 }
2342
2343 test_27z() {
2344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2345         remote_ost_nodsh && skip "remote OST with nodsh"
2346
2347         test_mkdir $DIR/$tdir
2348         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2349                 { error "setstripe -c -1 failed"; return 1; }
2350         # We need to send a write to every object to get parent FID info set.
2351         # This _should_ also work for setattr, but does not currently.
2352         # touch $DIR/$tdir/$tfile-1 ||
2353         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2354                 { error "dd $tfile-1 failed"; return 2; }
2355         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2356                 { error "setstripe -c -1 failed"; return 3; }
2357         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2358                 { error "dd $tfile-2 failed"; return 4; }
2359
2360         # make sure write RPCs have been sent to OSTs
2361         sync; sleep 5; sync
2362
2363         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2364         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2365 }
2366 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2367
2368 test_27A() { # b=19102
2369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2370
2371         save_layout_restore_at_exit $MOUNT
2372         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2373         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2374                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2375         local default_size=$($LFS getstripe -S $MOUNT)
2376         local default_offset=$($LFS getstripe -i $MOUNT)
2377         local dsize=$(do_facet $SINGLEMDS \
2378                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2379         [ $default_size -eq $dsize ] ||
2380                 error "stripe size $default_size != $dsize"
2381         [ $default_offset -eq -1 ] ||
2382                 error "stripe offset $default_offset != -1"
2383 }
2384 run_test 27A "check filesystem-wide default LOV EA values"
2385
2386 test_27B() { # LU-2523
2387         test_mkdir $DIR/$tdir
2388         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2389         touch $DIR/$tdir/f0
2390         # open f1 with O_LOV_DELAY_CREATE
2391         # rename f0 onto f1
2392         # call setstripe ioctl on open file descriptor for f1
2393         # close
2394         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2395                 $DIR/$tdir/f0
2396
2397         rm -f $DIR/$tdir/f1
2398         # open f1 with O_LOV_DELAY_CREATE
2399         # unlink f1
2400         # call setstripe ioctl on open file descriptor for f1
2401         # close
2402         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2403
2404         # Allow multiop to fail in imitation of NFS's busted semantics.
2405         true
2406 }
2407 run_test 27B "call setstripe on open unlinked file/rename victim"
2408
2409 # 27C family tests full striping and overstriping
2410 test_27Ca() { #LU-2871
2411         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2412
2413         declare -a ost_idx
2414         local index
2415         local found
2416         local i
2417         local j
2418
2419         test_mkdir $DIR/$tdir
2420         cd $DIR/$tdir
2421         for i in $(seq 0 $((OSTCOUNT - 1))); do
2422                 # set stripe across all OSTs starting from OST$i
2423                 $LFS setstripe -i $i -c -1 $tfile$i
2424                 # get striping information
2425                 ost_idx=($($LFS getstripe $tfile$i |
2426                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2427                 echo "OST Index: ${ost_idx[*]}"
2428
2429                 # check the layout
2430                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2431                         error "${#ost_idx[@]} != $OSTCOUNT"
2432
2433                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2434                         found=0
2435                         for j in "${ost_idx[@]}"; do
2436                                 if [ $index -eq $j ]; then
2437                                         found=1
2438                                         break
2439                                 fi
2440                         done
2441                         [ $found = 1 ] ||
2442                                 error "Can not find $index in ${ost_idx[*]}"
2443                 done
2444         done
2445 }
2446 run_test 27Ca "check full striping across all OSTs"
2447
2448 test_27Cb() {
2449         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2450                 skip "server does not support overstriping"
2451         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2452                 skip_env "too many osts, skipping"
2453
2454         test_mkdir -p $DIR/$tdir
2455         local setcount=$(($OSTCOUNT * 2))
2456         [ $setcount -lt 160 ] || large_xattr_enabled ||
2457                 skip_env "ea_inode feature disabled"
2458
2459         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2460                 error "setstripe failed"
2461
2462         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2463         [ $count -eq $setcount ] ||
2464                 error "stripe count $count, should be $setcount"
2465
2466         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2467                 error "overstriped should be set in pattern"
2468
2469         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2470                 error "dd failed"
2471 }
2472 run_test 27Cb "more stripes than OSTs with -C"
2473
2474 test_27Cc() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2478
2479         test_mkdir -p $DIR/$tdir
2480         local setcount=$(($OSTCOUNT - 1))
2481
2482         [ $setcount -lt 160 ] || large_xattr_enabled ||
2483                 skip_env "ea_inode feature disabled"
2484
2485         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2486                 error "setstripe failed"
2487
2488         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2489         [ $count -eq $setcount ] ||
2490                 error "stripe count $count, should be $setcount"
2491
2492         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2493                 error "overstriped should not be set in pattern"
2494
2495         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2496                 error "dd failed"
2497 }
2498 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2499
2500 test_27Cd() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2504         large_xattr_enabled || skip_env "ea_inode feature disabled"
2505
2506         test_mkdir -p $DIR/$tdir
2507         local setcount=$LOV_MAX_STRIPE_COUNT
2508
2509         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2510                 error "setstripe failed"
2511
2512         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2513         [ $count -eq $setcount ] ||
2514                 error "stripe count $count, should be $setcount"
2515
2516         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2517                 error "overstriped should be set in pattern"
2518
2519         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2520                 error "dd failed"
2521
2522         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2523 }
2524 run_test 27Cd "test maximum stripe count"
2525
2526 test_27Ce() {
2527         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2528                 skip "server does not support overstriping"
2529         test_mkdir -p $DIR/$tdir
2530
2531         pool_add $TESTNAME || error "Pool creation failed"
2532         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2533
2534         local setcount=8
2535
2536         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2537                 error "setstripe failed"
2538
2539         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2540         [ $count -eq $setcount ] ||
2541                 error "stripe count $count, should be $setcount"
2542
2543         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2544                 error "overstriped should be set in pattern"
2545
2546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2547                 error "dd failed"
2548
2549         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2550 }
2551 run_test 27Ce "test pool with overstriping"
2552
2553 test_27Cf() {
2554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2555                 skip "server does not support overstriping"
2556         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2557                 skip_env "too many osts, skipping"
2558
2559         test_mkdir -p $DIR/$tdir
2560
2561         local setcount=$(($OSTCOUNT * 2))
2562         [ $setcount -lt 160 ] || large_xattr_enabled ||
2563                 skip_env "ea_inode feature disabled"
2564
2565         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2566                 error "setstripe failed"
2567
2568         echo 1 > $DIR/$tdir/$tfile
2569
2570         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2571         [ $count -eq $setcount ] ||
2572                 error "stripe count $count, should be $setcount"
2573
2574         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2575                 error "overstriped should be set in pattern"
2576
2577         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2578                 error "dd failed"
2579
2580         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2581 }
2582 run_test 27Cf "test default inheritance with overstriping"
2583
2584 test_27D() {
2585         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2586         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2587         remote_mds_nodsh && skip "remote MDS with nodsh"
2588
2589         local POOL=${POOL:-testpool}
2590         local first_ost=0
2591         local last_ost=$(($OSTCOUNT - 1))
2592         local ost_step=1
2593         local ost_list=$(seq $first_ost $ost_step $last_ost)
2594         local ost_range="$first_ost $last_ost $ost_step"
2595
2596         test_mkdir $DIR/$tdir
2597         pool_add $POOL || error "pool_add failed"
2598         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2599
2600         local skip27D
2601         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2602                 skip27D+="-s 29"
2603         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2604                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2605                         skip27D+=" -s 30,31"
2606         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2607           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2608                 skip27D+=" -s 32,33"
2609         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2610                 skip27D+=" -s 34"
2611         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2612                 error "llapi_layout_test failed"
2613
2614         destroy_test_pools || error "destroy test pools failed"
2615 }
2616 run_test 27D "validate llapi_layout API"
2617
2618 # Verify that default_easize is increased from its initial value after
2619 # accessing a widely striped file.
2620 test_27E() {
2621         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2622         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2623                 skip "client does not have LU-3338 fix"
2624
2625         # 72 bytes is the minimum space required to store striping
2626         # information for a file striped across one OST:
2627         # (sizeof(struct lov_user_md_v3) +
2628         #  sizeof(struct lov_user_ost_data_v1))
2629         local min_easize=72
2630         $LCTL set_param -n llite.*.default_easize $min_easize ||
2631                 error "lctl set_param failed"
2632         local easize=$($LCTL get_param -n llite.*.default_easize)
2633
2634         [ $easize -eq $min_easize ] ||
2635                 error "failed to set default_easize"
2636
2637         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2638                 error "setstripe failed"
2639         # In order to ensure stat() call actually talks to MDS we need to
2640         # do something drastic to this file to shake off all lock, e.g.
2641         # rename it (kills lookup lock forcing cache cleaning)
2642         mv $DIR/$tfile $DIR/${tfile}-1
2643         ls -l $DIR/${tfile}-1
2644         rm $DIR/${tfile}-1
2645
2646         easize=$($LCTL get_param -n llite.*.default_easize)
2647
2648         [ $easize -gt $min_easize ] ||
2649                 error "default_easize not updated"
2650 }
2651 run_test 27E "check that default extended attribute size properly increases"
2652
2653 test_27F() { # LU-5346/LU-7975
2654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2655         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2656         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2657                 skip "Need MDS version at least 2.8.51"
2658         remote_ost_nodsh && skip "remote OST with nodsh"
2659
2660         test_mkdir $DIR/$tdir
2661         rm -f $DIR/$tdir/f0
2662         $LFS setstripe -c 2 $DIR/$tdir
2663
2664         # stop all OSTs to reproduce situation for LU-7975 ticket
2665         for num in $(seq $OSTCOUNT); do
2666                 stop ost$num
2667         done
2668
2669         # open/create f0 with O_LOV_DELAY_CREATE
2670         # truncate f0 to a non-0 size
2671         # close
2672         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2673
2674         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2675         # open/write it again to force delayed layout creation
2676         cat /etc/hosts > $DIR/$tdir/f0 &
2677         catpid=$!
2678
2679         # restart OSTs
2680         for num in $(seq $OSTCOUNT); do
2681                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2682                         error "ost$num failed to start"
2683         done
2684
2685         wait $catpid || error "cat failed"
2686
2687         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2688         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2689                 error "wrong stripecount"
2690
2691 }
2692 run_test 27F "Client resend delayed layout creation with non-zero size"
2693
2694 test_27G() { #LU-10629
2695         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2696                 skip "Need MDS version at least 2.11.51"
2697         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2698         remote_mds_nodsh && skip "remote MDS with nodsh"
2699         local POOL=${POOL:-testpool}
2700         local ostrange="0 0 1"
2701
2702         test_mkdir $DIR/$tdir
2703         touch $DIR/$tdir/$tfile.nopool
2704         pool_add $POOL || error "pool_add failed"
2705         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2706         $LFS setstripe -p $POOL $DIR/$tdir
2707
2708         local pool=$($LFS getstripe -p $DIR/$tdir)
2709
2710         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2711         touch $DIR/$tdir/$tfile.default
2712         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2713         $LFS find $DIR/$tdir -type f --pool $POOL
2714         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2715         [[ "$found" == "2" ]] ||
2716                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2717
2718         $LFS setstripe -d $DIR/$tdir
2719
2720         pool=$($LFS getstripe -p -d $DIR/$tdir)
2721
2722         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2723 }
2724 run_test 27G "Clear OST pool from stripe"
2725
2726 test_27H() {
2727         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2728                 skip "Need MDS version newer than 2.11.54"
2729         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2730         test_mkdir $DIR/$tdir
2731         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2732         touch $DIR/$tdir/$tfile
2733         $LFS getstripe -c $DIR/$tdir/$tfile
2734         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2735                 error "two-stripe file doesn't have two stripes"
2736
2737         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2738         $LFS getstripe -y $DIR/$tdir/$tfile
2739         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2740              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2741                 error "expected l_ost_idx: [02]$ not matched"
2742
2743         # make sure ost list has been cleared
2744         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2745         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2746                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2747         touch $DIR/$tdir/f3
2748         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2749 }
2750 run_test 27H "Set specific OSTs stripe"
2751
2752 test_27I() {
2753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2754         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2755         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2756                 skip "Need MDS version newer than 2.12.52"
2757         local pool=$TESTNAME
2758         local ostrange="1 1 1"
2759
2760         save_layout_restore_at_exit $MOUNT
2761         $LFS setstripe -c 2 -i 0 $MOUNT
2762         pool_add $pool || error "pool_add failed"
2763         pool_add_targets $pool $ostrange ||
2764                 error "pool_add_targets failed"
2765         test_mkdir $DIR/$tdir
2766         $LFS setstripe -p $pool $DIR/$tdir
2767         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2768         $LFS getstripe $DIR/$tdir/$tfile
2769 }
2770 run_test 27I "check that root dir striping does not break parent dir one"
2771
2772 test_27J() {
2773         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2774                 skip "Need MDS version newer than 2.12.51"
2775
2776         test_mkdir $DIR/$tdir
2777         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2778         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2779
2780         # create foreign file (raw way)
2781         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2782                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2783
2784         ! $LFS setstripe --foreign --flags foo \
2785                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2786                         error "creating $tfile with '--flags foo' should fail"
2787
2788         ! $LFS setstripe --foreign --flags 0xffffffff \
2789                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2790                         error "creating $tfile w/ 0xffffffff flags should fail"
2791
2792         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2793                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2794
2795         # verify foreign file (raw way)
2796         parse_foreign_file -f $DIR/$tdir/$tfile |
2797                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2798                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2799         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_size: 73" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2804         parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_type: 1" ||
2806                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2807         parse_foreign_file -f $DIR/$tdir/$tfile |
2808                 grep "lov_foreign_flags: 0x0000DA08" ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2810         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2811                 grep "lov_foreign_value: 0x" |
2812                 sed -e 's/lov_foreign_value: 0x//')
2813         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2814         [[ $lov = ${lov2// /} ]] ||
2815                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2816
2817         # create foreign file (lfs + API)
2818         $LFS setstripe --foreign=none --flags 0xda08 \
2819                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2820                 error "$DIR/$tdir/${tfile}2: create failed"
2821
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2823                 grep "lfm_magic:.*0x0BD70BD0" ||
2824                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2825         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2826         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2827                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2828         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2830         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2831                 grep "lfm_flags:.*0x0000DA08" ||
2832                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2833         $LFS getstripe $DIR/$tdir/${tfile}2 |
2834                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2835                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2836
2837         # modify striping should fail
2838         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2839                 error "$DIR/$tdir/$tfile: setstripe should fail"
2840         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2841                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2842
2843         # R/W should fail
2844         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2845         cat $DIR/$tdir/${tfile}2 &&
2846                 error "$DIR/$tdir/${tfile}2: read should fail"
2847         cat /etc/passwd > $DIR/$tdir/$tfile &&
2848                 error "$DIR/$tdir/$tfile: write should fail"
2849         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2850                 error "$DIR/$tdir/${tfile}2: write should fail"
2851
2852         # chmod should work
2853         chmod 222 $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chmod failed"
2855         chmod 222 $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chmod failed"
2857
2858         # chown should work
2859         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2860                 error "$DIR/$tdir/$tfile: chown failed"
2861         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2862                 error "$DIR/$tdir/${tfile}2: chown failed"
2863
2864         # rename should work
2865         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2867         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2869
2870         #remove foreign file
2871         rm $DIR/$tdir/${tfile}.new ||
2872                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2873         rm $DIR/$tdir/${tfile}2.new ||
2874                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2875 }
2876 run_test 27J "basic ops on file with foreign LOV"
2877
2878 test_27K() {
2879         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2880                 skip "Need MDS version newer than 2.12.49"
2881
2882         test_mkdir $DIR/$tdir
2883         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2884         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2885
2886         # create foreign dir (raw way)
2887         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2888                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2889
2890         ! $LFS setdirstripe --foreign --flags foo \
2891                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2892                         error "creating $tdir with '--flags foo' should fail"
2893
2894         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2895                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2896                         error "creating $tdir w/ 0xffffffff flags should fail"
2897
2898         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2899                 error "create_foreign_dir FAILED"
2900
2901         # verify foreign dir (raw way)
2902         parse_foreign_dir -d $DIR/$tdir/$tdir |
2903                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2904                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2905         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2906                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2907         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2908                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2909         parse_foreign_dir -d $DIR/$tdir/$tdir |
2910                 grep "lmv_foreign_flags: 55813$" ||
2911                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2912         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2913                 grep "lmv_foreign_value: 0x" |
2914                 sed 's/lmv_foreign_value: 0x//')
2915         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2916                 sed 's/ //g')
2917         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2918
2919         # create foreign dir (lfs + API)
2920         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2921                 $DIR/$tdir/${tdir}2 ||
2922                 error "$DIR/$tdir/${tdir}2: create failed"
2923
2924         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2925
2926         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2927                 grep "lfm_magic:.*0x0CD50CD0" ||
2928                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2929         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2930         # - sizeof(lfm_type) - sizeof(lfm_flags)
2931         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2933         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2934                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2935         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2936                 grep "lfm_flags:.*0x0000DA05" ||
2937                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2938         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2939                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2940                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2941
2942         # file create in dir should fail
2943         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2944         touch $DIR/$tdir/${tdir}2/$tfile &&
2945                 error "$DIR/${tdir}2: file create should fail"
2946
2947         # chmod should work
2948         chmod 777 $DIR/$tdir/$tdir ||
2949                 error "$DIR/$tdir: chmod failed"
2950         chmod 777 $DIR/$tdir/${tdir}2 ||
2951                 error "$DIR/${tdir}2: chmod failed"
2952
2953         # chown should work
2954         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2955                 error "$DIR/$tdir: chown failed"
2956         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2957                 error "$DIR/${tdir}2: chown failed"
2958
2959         # rename should work
2960         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2961                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2962         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2963                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2964
2965         #remove foreign dir
2966         rmdir $DIR/$tdir/${tdir}.new ||
2967                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2968         rmdir $DIR/$tdir/${tdir}2.new ||
2969                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2970 }
2971 run_test 27K "basic ops on dir with foreign LMV"
2972
2973 test_27L() {
2974         remote_mds_nodsh && skip "remote MDS with nodsh"
2975
2976         local POOL=${POOL:-$TESTNAME}
2977
2978         pool_add $POOL || error "pool_add failed"
2979
2980         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2981                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2982                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2983 }
2984 run_test 27L "lfs pool_list gives correct pool name"
2985
2986 test_27M() {
2987         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2988                 skip "Need MDS version >= than 2.12.57"
2989         remote_mds_nodsh && skip "remote MDS with nodsh"
2990         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2991
2992         # Set default striping on directory
2993         local setcount=4
2994         local stripe_opt
2995         local mdts=$(comma_list $(mdts_nodes))
2996
2997         # if we run against a 2.12 server which lacks overstring support
2998         # then the connect_flag will not report overstriping, even if client
2999         # is 2.14+
3000         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3001                 stripe_opt="-C $setcount"
3002         elif (( $OSTCOUNT >= $setcount )); then
3003                 stripe_opt="-c $setcount"
3004         else
3005                 skip "server does not support overstriping"
3006         fi
3007
3008         test_mkdir $DIR/$tdir
3009
3010         # Validate existing append_* params and ensure restore
3011         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3012         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3013         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3014
3015         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3016         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3017         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3018
3019         $LFS setstripe $stripe_opt $DIR/$tdir
3020
3021         echo 1 > $DIR/$tdir/${tfile}.1
3022         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3023         [ $count -eq $setcount ] ||
3024                 error "(1) stripe count $count, should be $setcount"
3025
3026         local appendcount=$orig_count
3027         echo 1 >> $DIR/$tdir/${tfile}.2_append
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3029         [ $count -eq $appendcount ] ||
3030                 error "(2)stripe count $count, should be $appendcount for append"
3031
3032         # Disable O_APPEND striping, verify it works
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3034
3035         # Should now get the default striping, which is 4
3036         setcount=4
3037         echo 1 >> $DIR/$tdir/${tfile}.3_append
3038         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3039         [ $count -eq $setcount ] ||
3040                 error "(3) stripe count $count, should be $setcount"
3041
3042         # Try changing the stripe count for append files
3043         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3044
3045         # Append striping is now 2 (directory default is still 4)
3046         appendcount=2
3047         echo 1 >> $DIR/$tdir/${tfile}.4_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(4) stripe count $count, should be $appendcount for append"
3051
3052         # Test append stripe count of -1
3053         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3054         appendcount=$OSTCOUNT
3055         echo 1 >> $DIR/$tdir/${tfile}.5
3056         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3057         [ $count -eq $appendcount ] ||
3058                 error "(5) stripe count $count, should be $appendcount for append"
3059
3060         # Set append striping back to default of 1
3061         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3062
3063         # Try a new default striping, PFL + DOM
3064         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3065
3066         # Create normal DOM file, DOM returns stripe count == 0
3067         setcount=0
3068         touch $DIR/$tdir/${tfile}.6
3069         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3070         [ $count -eq $setcount ] ||
3071                 error "(6) stripe count $count, should be $setcount"
3072
3073         # Show
3074         appendcount=1
3075         echo 1 >> $DIR/$tdir/${tfile}.7_append
3076         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3077         [ $count -eq $appendcount ] ||
3078                 error "(7) stripe count $count, should be $appendcount for append"
3079
3080         # Clean up DOM layout
3081         $LFS setstripe -d $DIR/$tdir
3082
3083         save_layout_restore_at_exit $MOUNT
3084         # Now test that append striping works when layout is from root
3085         $LFS setstripe -c 2 $MOUNT
3086         # Make a special directory for this
3087         mkdir $DIR/${tdir}/${tdir}.2
3088
3089         # Verify for normal file
3090         setcount=2
3091         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3092         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3093         [ $count -eq $setcount ] ||
3094                 error "(8) stripe count $count, should be $setcount"
3095
3096         appendcount=1
3097         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3098         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3099         [ $count -eq $appendcount ] ||
3100                 error "(9) stripe count $count, should be $appendcount for append"
3101
3102         # Now test O_APPEND striping with pools
3103         pool_add $TESTNAME || error "pool creation failed"
3104         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.10_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3110         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3111
3112         # Check that count is still correct
3113         appendcount=1
3114         echo 1 >> $DIR/$tdir/${tfile}.11_append
3115         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3116         [ $count -eq $appendcount ] ||
3117                 error "(11) stripe count $count, should be $appendcount for append"
3118
3119         # Disable O_APPEND stripe count, verify pool works separately
3120         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3121
3122         echo 1 >> $DIR/$tdir/${tfile}.12_append
3123
3124         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3125         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3126
3127         # Remove pool setting, verify it's not applied
3128         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3129
3130         echo 1 >> $DIR/$tdir/${tfile}.13_append
3131
3132         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3133         [ "$pool" = "" ] || error "(13) pool found: $pool"
3134 }
3135 run_test 27M "test O_APPEND striping"
3136
3137 test_27N() {
3138         combined_mgs_mds && skip "needs separate MGS/MDT"
3139
3140         pool_add $TESTNAME || error "pool_add failed"
3141         do_facet mgs "$LCTL pool_list $FSNAME" |
3142                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3143                 error "lctl pool_list on MGS failed"
3144 }
3145 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3146
3147 clean_foreign_symlink() {
3148         trap 0
3149         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3150         for i in $DIR/$tdir/* ; do
3151                 $LFS unlink_foreign $i || true
3152         done
3153 }
3154
3155 test_27O() {
3156         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3157                 skip "Need MDS version newer than 2.12.51"
3158
3159         test_mkdir $DIR/$tdir
3160         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3161         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3162
3163         trap clean_foreign_symlink EXIT
3164
3165         # enable foreign_symlink behaviour
3166         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3167
3168         # foreign symlink LOV format is a partial path by default
3169
3170         # create foreign file (lfs + API)
3171         $LFS setstripe --foreign=symlink --flags 0xda05 \
3172                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3173                 error "$DIR/$tdir/${tfile}: create failed"
3174
3175         $LFS getstripe -v $DIR/$tdir/${tfile} |
3176                 grep "lfm_magic:.*0x0BD70BD0" ||
3177                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3178         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3179                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3180         $LFS getstripe -v $DIR/$tdir/${tfile} |
3181                 grep "lfm_flags:.*0x0000DA05" ||
3182                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3183         $LFS getstripe $DIR/$tdir/${tfile} |
3184                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3185                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3186
3187         # modify striping should fail
3188         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3189                 error "$DIR/$tdir/$tfile: setstripe should fail"
3190
3191         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3192         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3193         cat /etc/passwd > $DIR/$tdir/$tfile &&
3194                 error "$DIR/$tdir/$tfile: write should fail"
3195
3196         # rename should succeed
3197         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3198                 error "$DIR/$tdir/$tfile: rename has failed"
3199
3200         #remove foreign_symlink file should fail
3201         rm $DIR/$tdir/${tfile}.new &&
3202                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3203
3204         #test fake symlink
3205         mkdir /tmp/${uuid1} ||
3206                 error "/tmp/${uuid1}: mkdir has failed"
3207         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3208                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3209         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3210         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3211                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3212         #read should succeed now
3213         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3214                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3215         #write should succeed now
3216         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3217                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3218         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3219                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3220         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3221                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3222
3223         #check that getstripe still works
3224         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3225                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3226
3227         # chmod should still succeed
3228         chmod 644 $DIR/$tdir/${tfile}.new ||
3229                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3230
3231         # chown should still succeed
3232         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3233                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3234
3235         # rename should still succeed
3236         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3237                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3238
3239         #remove foreign_symlink file should still fail
3240         rm $DIR/$tdir/${tfile} &&
3241                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3242
3243         #use special ioctl() to unlink foreign_symlink file
3244         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3245                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3246
3247 }
3248 run_test 27O "basic ops on foreign file of symlink type"
3249
3250 test_27P() {
3251         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3252                 skip "Need MDS version newer than 2.12.49"
3253
3254         test_mkdir $DIR/$tdir
3255         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3256         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3257
3258         trap clean_foreign_symlink EXIT
3259
3260         # enable foreign_symlink behaviour
3261         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3262
3263         # foreign symlink LMV format is a partial path by default
3264
3265         # create foreign dir (lfs + API)
3266         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3267                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3268                 error "$DIR/$tdir/${tdir}: create failed"
3269
3270         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3271
3272         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3273                 grep "lfm_magic:.*0x0CD50CD0" ||
3274                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3275         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3276                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3277         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3278                 grep "lfm_flags:.*0x0000DA05" ||
3279                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3280         $LFS getdirstripe $DIR/$tdir/${tdir} |
3281                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3282                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3283
3284         # file create in dir should fail
3285         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3286         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3287
3288         # rename should succeed
3289         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3290                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3291
3292         #remove foreign_symlink dir should fail
3293         rmdir $DIR/$tdir/${tdir}.new &&
3294                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3295
3296         #test fake symlink
3297         mkdir -p /tmp/${uuid1}/${uuid2} ||
3298                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3299         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3300                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3301         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3302         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3303                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3304         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3305                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3306
3307         #check that getstripe fails now that foreign_symlink enabled
3308         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3309                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3310
3311         # file create in dir should work now
3312         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3313                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3314         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3315                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3316         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3317                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3318
3319         # chmod should still succeed
3320         chmod 755 $DIR/$tdir/${tdir}.new ||
3321                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3322
3323         # chown should still succeed
3324         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3325                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3326
3327         # rename should still succeed
3328         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3329                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3330
3331         #remove foreign_symlink dir should still fail
3332         rmdir $DIR/$tdir/${tdir} &&
3333                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3334
3335         #use special ioctl() to unlink foreign_symlink file
3336         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3337                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3338
3339         #created file should still exist
3340         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3341                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3342         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3343                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3344 }
3345 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3346
3347 test_27Q() {
3348         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3349         stack_trap "rm -f $TMP/$tfile*"
3350
3351         test_mkdir $DIR/$tdir-1
3352         test_mkdir $DIR/$tdir-2
3353
3354         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3355         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3356
3357         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3358         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3359
3360         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3361         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3362
3363         # Create some bad symlinks and ensure that we don't loop
3364         # forever or something. These should return ELOOP (40) and
3365         # ENOENT (2) but I don't want to test for that because there's
3366         # always some weirdo architecture that needs to ruin
3367         # everything by defining these error numbers differently.
3368
3369         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3370         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3371
3372         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3373         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3374
3375         return 0
3376 }
3377 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3378
3379 test_27R() {
3380         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3381                 skip "need MDS 2.14.55 or later"
3382         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3383
3384         local testdir="$DIR/$tdir"
3385         test_mkdir -p $testdir
3386         stack_trap "rm -rf $testdir"
3387         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3388
3389         local f1="$testdir/f1"
3390         touch $f1 || error "failed to touch $f1"
3391         local count=$($LFS getstripe -c $f1)
3392         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3393
3394         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3395         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3396
3397         local maxcount=$(($OSTCOUNT - 1))
3398         local mdts=$(comma_list $(mdts_nodes))
3399         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3400         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3401
3402         local f2="$testdir/f2"
3403         touch $f2 || error "failed to touch $f2"
3404         local count=$($LFS getstripe -c $f2)
3405         (( $count == $maxcount )) || error "wrong stripe count"
3406 }
3407 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3408
3409 test_27T() {
3410         [ $(facet_host client) == $(facet_host ost1) ] &&
3411                 skip "need ost1 and client on different nodes"
3412
3413 #define OBD_FAIL_OSC_NO_GRANT            0x411
3414         $LCTL set_param fail_loc=0x20000411 fail_val=1
3415 #define OBD_FAIL_OST_ENOSPC              0x215
3416         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3417         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3418         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3419                 error "multiop failed"
3420 }
3421 run_test 27T "no eio on close on partial write due to enosp"
3422
3423 test_27U() {
3424         local dir=$DIR/$tdir
3425         local file=$dir/$tfile
3426         local append_pool=${TESTNAME}-append
3427         local normal_pool=${TESTNAME}-normal
3428         local pool
3429         local stripe_count
3430         local stripe_count2
3431         local mdts=$(comma_list $(mdts_nodes))
3432
3433         # FIMXE
3434         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3435         #       skip "Need MDS version at least 2.15.42"
3436
3437         # Validate existing append_* params and ensure restore
3438         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3439         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3440         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3441
3442         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3443         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3444         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3445
3446         pool_add $append_pool || error "pool creation failed"
3447         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3448
3449         pool_add $normal_pool || error "pool creation failed"
3450         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3451
3452         test_mkdir $dir
3453         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3454
3455         echo XXX >> $file.1
3456         $LFS getstripe $file.1
3457
3458         pool=$($LFS getstripe -p $file.1)
3459         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3460
3461         stripe_count2=$($LFS getstripe -c $file.1)
3462         ((stripe_count2 == stripe_count)) ||
3463                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3464
3465         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3466
3467         echo XXX >> $file.2
3468         $LFS getstripe $file.2
3469
3470         pool=$($LFS getstripe -p $file.2)
3471         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3472
3473         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3474
3475         echo XXX >> $file.3
3476         $LFS getstripe $file.3
3477
3478         stripe_count2=$($LFS getstripe -c $file.3)
3479         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3480 }
3481 run_test 27U "append pool and stripe count work with composite default layout"
3482
3483 # createtest also checks that device nodes are created and
3484 # then visible correctly (#2091)
3485 test_28() { # bug 2091
3486         test_mkdir $DIR/d28
3487         $CREATETEST $DIR/d28/ct || error "createtest failed"
3488 }
3489 run_test 28 "create/mknod/mkdir with bad file types ============"
3490
3491 test_29() {
3492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3493
3494         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3495                 disable_opencache
3496                 stack_trap "restore_opencache"
3497         }
3498
3499         sync; sleep 1; sync # flush out any dirty pages from previous tests
3500         cancel_lru_locks
3501         test_mkdir $DIR/d29
3502         touch $DIR/d29/foo
3503         log 'first d29'
3504         ls -l $DIR/d29
3505
3506         declare -i LOCKCOUNTORIG=0
3507         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3508                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3509         done
3510         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3511
3512         declare -i LOCKUNUSEDCOUNTORIG=0
3513         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3514                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3515         done
3516
3517         log 'second d29'
3518         ls -l $DIR/d29
3519         log 'done'
3520
3521         declare -i LOCKCOUNTCURRENT=0
3522         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3523                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3524         done
3525
3526         declare -i LOCKUNUSEDCOUNTCURRENT=0
3527         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3528                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3529         done
3530
3531         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3532                 $LCTL set_param -n ldlm.dump_namespaces ""
3533                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3534                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3535                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3536                 return 2
3537         fi
3538         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3539                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3540                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3541                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3542                 return 3
3543         fi
3544 }
3545 run_test 29 "IT_GETATTR regression  ============================"
3546
3547 test_30a() { # was test_30
3548         cp $(which ls) $DIR || cp /bin/ls $DIR
3549         $DIR/ls / || error "Can't execute binary from lustre"
3550         rm $DIR/ls
3551 }
3552 run_test 30a "execute binary from Lustre (execve) =============="
3553
3554 test_30b() {
3555         cp `which ls` $DIR || cp /bin/ls $DIR
3556         chmod go+rx $DIR/ls
3557         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3558         rm $DIR/ls
3559 }
3560 run_test 30b "execute binary from Lustre as non-root ==========="
3561
3562 test_30c() { # b=22376
3563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3564
3565         cp $(which ls) $DIR || cp /bin/ls $DIR
3566         chmod a-rw $DIR/ls
3567         cancel_lru_locks mdc
3568         cancel_lru_locks osc
3569         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3570         rm -f $DIR/ls
3571 }
3572 run_test 30c "execute binary from Lustre without read perms ===="
3573
3574 test_30d() {
3575         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3576
3577         for i in {1..10}; do
3578                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3579                 local PID=$!
3580                 sleep 1
3581                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3582                 wait $PID || error "executing dd from Lustre failed"
3583                 rm -f $DIR/$tfile
3584         done
3585
3586         rm -f $DIR/dd
3587 }
3588 run_test 30d "execute binary from Lustre while clear locks"
3589
3590 test_31a() {
3591         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3592         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3593 }
3594 run_test 31a "open-unlink file =================================="
3595
3596 test_31b() {
3597         touch $DIR/f31 || error "touch $DIR/f31 failed"
3598         ln $DIR/f31 $DIR/f31b || error "ln failed"
3599         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3600         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3601 }
3602 run_test 31b "unlink file with multiple links while open ======="
3603
3604 test_31c() {
3605         touch $DIR/f31 || error "touch $DIR/f31 failed"
3606         ln $DIR/f31 $DIR/f31c || error "ln failed"
3607         multiop_bg_pause $DIR/f31 O_uc ||
3608                 error "multiop_bg_pause for $DIR/f31 failed"
3609         MULTIPID=$!
3610         $MULTIOP $DIR/f31c Ouc
3611         kill -USR1 $MULTIPID
3612         wait $MULTIPID
3613 }
3614 run_test 31c "open-unlink file with multiple links ============="
3615
3616 test_31d() {
3617         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3618         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3619 }
3620 run_test 31d "remove of open directory ========================="
3621
3622 test_31e() { # bug 2904
3623         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3624 }
3625 run_test 31e "remove of open non-empty directory ==============="
3626
3627 test_31f() { # bug 4554
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         set -vx
3631         test_mkdir $DIR/d31f
3632         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3633         cp /etc/hosts $DIR/d31f
3634         ls -l $DIR/d31f
3635         $LFS getstripe $DIR/d31f/hosts
3636         multiop_bg_pause $DIR/d31f D_c || return 1
3637         MULTIPID=$!
3638
3639         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3640         test_mkdir $DIR/d31f
3641         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3642         cp /etc/hosts $DIR/d31f
3643         ls -l $DIR/d31f
3644         $LFS getstripe $DIR/d31f/hosts
3645         multiop_bg_pause $DIR/d31f D_c || return 1
3646         MULTIPID2=$!
3647
3648         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3649         wait $MULTIPID || error "first opendir $MULTIPID failed"
3650
3651         sleep 6
3652
3653         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3654         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3655         set +vx
3656 }
3657 run_test 31f "remove of open directory with open-unlink file ==="
3658
3659 test_31g() {
3660         echo "-- cross directory link --"
3661         test_mkdir -c1 $DIR/${tdir}ga
3662         test_mkdir -c1 $DIR/${tdir}gb
3663         touch $DIR/${tdir}ga/f
3664         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3665         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3666         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3667         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3668         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3669 }
3670 run_test 31g "cross directory link==============="
3671
3672 test_31h() {
3673         echo "-- cross directory link --"
3674         test_mkdir -c1 $DIR/${tdir}
3675         test_mkdir -c1 $DIR/${tdir}/dir
3676         touch $DIR/${tdir}/f
3677         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3678         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3679         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3680         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3681         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3682 }
3683 run_test 31h "cross directory link under child==============="
3684
3685 test_31i() {
3686         echo "-- cross directory link --"
3687         test_mkdir -c1 $DIR/$tdir
3688         test_mkdir -c1 $DIR/$tdir/dir
3689         touch $DIR/$tdir/dir/f
3690         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3691         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3692         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3693         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3694         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3695 }
3696 run_test 31i "cross directory link under parent==============="
3697
3698 test_31j() {
3699         test_mkdir -c1 -p $DIR/$tdir
3700         test_mkdir -c1 -p $DIR/$tdir/dir1
3701         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3702         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3703         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3704         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3705         return 0
3706 }
3707 run_test 31j "link for directory==============="
3708
3709 test_31k() {
3710         test_mkdir -c1 -p $DIR/$tdir
3711         touch $DIR/$tdir/s
3712         touch $DIR/$tdir/exist
3713         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3714         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3715         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3716         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3717         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3718         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3719         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3720         return 0
3721 }
3722 run_test 31k "link to file: the same, non-existing, dir==============="
3723
3724 test_31m() {
3725         mkdir $DIR/d31m
3726         touch $DIR/d31m/s
3727         mkdir $DIR/d31m2
3728         touch $DIR/d31m2/exist
3729         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3730         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3731         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3732         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3733         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3734         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3735         return 0
3736 }
3737 run_test 31m "link to file: the same, non-existing, dir==============="
3738
3739 test_31n() {
3740         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3741         nlink=$(stat --format=%h $DIR/$tfile)
3742         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3743         local fd=$(free_fd)
3744         local cmd="exec $fd<$DIR/$tfile"
3745         eval $cmd
3746         cmd="exec $fd<&-"
3747         trap "eval $cmd" EXIT
3748         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3749         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3750         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3751         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3752         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3753         eval $cmd
3754 }
3755 run_test 31n "check link count of unlinked file"
3756
3757 link_one() {
3758         local tempfile=$(mktemp $1_XXXXXX)
3759         mlink $tempfile $1 2> /dev/null &&
3760                 echo "$BASHPID: link $tempfile to $1 succeeded"
3761         munlink $tempfile
3762 }
3763
3764 test_31o() { # LU-2901
3765         test_mkdir $DIR/$tdir
3766         for LOOP in $(seq 100); do
3767                 rm -f $DIR/$tdir/$tfile*
3768                 for THREAD in $(seq 8); do
3769                         link_one $DIR/$tdir/$tfile.$LOOP &
3770                 done
3771                 wait
3772                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3773                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3774                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3775                         break || true
3776         done
3777 }
3778 run_test 31o "duplicate hard links with same filename"
3779
3780 test_31p() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782
3783         test_mkdir $DIR/$tdir
3784         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3785         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3786
3787         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3788                 error "open unlink test1 failed"
3789         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3790                 error "open unlink test2 failed"
3791
3792         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3793                 error "test1 still exists"
3794         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3795                 error "test2 still exists"
3796 }
3797 run_test 31p "remove of open striped directory"
3798
3799 test_31q() {
3800         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3801
3802         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3803         index=$($LFS getdirstripe -i $DIR/$tdir)
3804         [ $index -eq 3 ] || error "first stripe index $index != 3"
3805         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3806         [ $index -eq 1 ] || error "second stripe index $index != 1"
3807
3808         # when "-c <stripe_count>" is set, the number of MDTs specified after
3809         # "-i" should equal to the stripe count
3810         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3811 }
3812 run_test 31q "create striped directory on specific MDTs"
3813
3814 #LU-14949
3815 test_31r() {
3816         touch $DIR/$tfile.target
3817         touch $DIR/$tfile.source
3818
3819         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3820         $LCTL set_param fail_loc=0x1419 fail_val=3
3821         cat $DIR/$tfile.target &
3822         CATPID=$!
3823
3824         # Guarantee open is waiting before we get here
3825         sleep 1
3826         mv $DIR/$tfile.source $DIR/$tfile.target
3827
3828         wait $CATPID
3829         RC=$?
3830         if [[ $RC -ne 0 ]]; then
3831                 error "open with cat failed, rc=$RC"
3832         fi
3833 }
3834 run_test 31r "open-rename(replace) race"
3835
3836 cleanup_test32_mount() {
3837         local rc=0
3838         trap 0
3839         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3840         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3841         losetup -d $loopdev || true
3842         rm -rf $DIR/$tdir
3843         return $rc
3844 }
3845
3846 test_32a() {
3847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3848
3849         echo "== more mountpoints and symlinks ================="
3850         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3851         trap cleanup_test32_mount EXIT
3852         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3853         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3854                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3855         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3856                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3857         cleanup_test32_mount
3858 }
3859 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3860
3861 test_32b() {
3862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3863
3864         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3865         trap cleanup_test32_mount EXIT
3866         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3867         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3868                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3869         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3870                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3871         cleanup_test32_mount
3872 }
3873 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3874
3875 test_32c() {
3876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3877
3878         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3879         trap cleanup_test32_mount EXIT
3880         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3881         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3882                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3883         test_mkdir -p $DIR/$tdir/d2/test_dir
3884         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3885                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3886         cleanup_test32_mount
3887 }
3888 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3889
3890 test_32d() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3894         trap cleanup_test32_mount EXIT
3895         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3896         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3897                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3898         test_mkdir -p $DIR/$tdir/d2/test_dir
3899         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3900                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3901         cleanup_test32_mount
3902 }
3903 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3904
3905 test_32e() {
3906         rm -fr $DIR/$tdir
3907         test_mkdir -p $DIR/$tdir/tmp
3908         local tmp_dir=$DIR/$tdir/tmp
3909         ln -s $DIR/$tdir $tmp_dir/symlink11
3910         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3911         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3912         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3913 }
3914 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3915
3916 test_32f() {
3917         rm -fr $DIR/$tdir
3918         test_mkdir -p $DIR/$tdir/tmp
3919         local tmp_dir=$DIR/$tdir/tmp
3920         ln -s $DIR/$tdir $tmp_dir/symlink11
3921         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3922         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3923         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3924 }
3925 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3926
3927 test_32g() {
3928         local tmp_dir=$DIR/$tdir/tmp
3929         test_mkdir -p $tmp_dir
3930         test_mkdir $DIR/${tdir}2
3931         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3932         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3933         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3934         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3935         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3936         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3937 }
3938 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3939
3940 test_32h() {
3941         rm -fr $DIR/$tdir $DIR/${tdir}2
3942         tmp_dir=$DIR/$tdir/tmp
3943         test_mkdir -p $tmp_dir
3944         test_mkdir $DIR/${tdir}2
3945         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3946         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3947         ls $tmp_dir/symlink12 || error "listing symlink12"
3948         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3949 }
3950 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3951
3952 test_32i() {
3953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3954
3955         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3956         trap cleanup_test32_mount EXIT
3957         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3958         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3959                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3960         touch $DIR/$tdir/test_file
3961         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3962                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3963         cleanup_test32_mount
3964 }
3965 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3966
3967 test_32j() {
3968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3969
3970         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3971         trap cleanup_test32_mount EXIT
3972         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3973         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3974                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3975         touch $DIR/$tdir/test_file
3976         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3977                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3978         cleanup_test32_mount
3979 }
3980 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3981
3982 test_32k() {
3983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3984
3985         rm -fr $DIR/$tdir
3986         trap cleanup_test32_mount EXIT
3987         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3988         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3989                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3990         test_mkdir -p $DIR/$tdir/d2
3991         touch $DIR/$tdir/d2/test_file || error "touch failed"
3992         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3993                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3994         cleanup_test32_mount
3995 }
3996 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3997
3998 test_32l() {
3999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4000
4001         rm -fr $DIR/$tdir
4002         trap cleanup_test32_mount EXIT
4003         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4004         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4005                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4006         test_mkdir -p $DIR/$tdir/d2
4007         touch $DIR/$tdir/d2/test_file || error "touch failed"
4008         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4009                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4010         cleanup_test32_mount
4011 }
4012 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4013
4014 test_32m() {
4015         rm -fr $DIR/d32m
4016         test_mkdir -p $DIR/d32m/tmp
4017         TMP_DIR=$DIR/d32m/tmp
4018         ln -s $DIR $TMP_DIR/symlink11
4019         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4020         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4021                 error "symlink11 not a link"
4022         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4023                 error "symlink01 not a link"
4024 }
4025 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4026
4027 test_32n() {
4028         rm -fr $DIR/d32n
4029         test_mkdir -p $DIR/d32n/tmp
4030         TMP_DIR=$DIR/d32n/tmp
4031         ln -s $DIR $TMP_DIR/symlink11
4032         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4033         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4034         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4035 }
4036 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4037
4038 test_32o() {
4039         touch $DIR/$tfile
4040         test_mkdir -p $DIR/d32o/tmp
4041         TMP_DIR=$DIR/d32o/tmp
4042         ln -s $DIR/$tfile $TMP_DIR/symlink12
4043         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4044         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4045                 error "symlink12 not a link"
4046         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4047         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4048                 error "$DIR/d32o/tmp/symlink12 not file type"
4049         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4050                 error "$DIR/d32o/symlink02 not file type"
4051 }
4052 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4053
4054 test_32p() {
4055         log 32p_1
4056         rm -fr $DIR/d32p
4057         log 32p_2
4058         rm -f $DIR/$tfile
4059         log 32p_3
4060         touch $DIR/$tfile
4061         log 32p_4
4062         test_mkdir -p $DIR/d32p/tmp
4063         log 32p_5
4064         TMP_DIR=$DIR/d32p/tmp
4065         log 32p_6
4066         ln -s $DIR/$tfile $TMP_DIR/symlink12
4067         log 32p_7
4068         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4069         log 32p_8
4070         cat $DIR/d32p/tmp/symlink12 ||
4071                 error "Can't open $DIR/d32p/tmp/symlink12"
4072         log 32p_9
4073         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4074         log 32p_10
4075 }
4076 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4077
4078 test_32q() {
4079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4080
4081         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4082         trap cleanup_test32_mount EXIT
4083         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4084         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4085         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4086                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4087         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4088         cleanup_test32_mount
4089 }
4090 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4091
4092 test_32r() {
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4096         trap cleanup_test32_mount EXIT
4097         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4098         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4099         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4100                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4101         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4102         cleanup_test32_mount
4103 }
4104 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4105
4106 test_33aa() {
4107         rm -f $DIR/$tfile
4108         touch $DIR/$tfile
4109         chmod 444 $DIR/$tfile
4110         chown $RUNAS_ID $DIR/$tfile
4111         log 33_1
4112         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4113         log 33_2
4114 }
4115 run_test 33aa "write file with mode 444 (should return error)"
4116
4117 test_33a() {
4118         rm -fr $DIR/$tdir
4119         test_mkdir $DIR/$tdir
4120         chown $RUNAS_ID $DIR/$tdir
4121         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4122                 error "$RUNAS create $tdir/$tfile failed"
4123         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4124                 error "open RDWR" || true
4125 }
4126 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4127
4128 test_33b() {
4129         rm -fr $DIR/$tdir
4130         test_mkdir $DIR/$tdir
4131         chown $RUNAS_ID $DIR/$tdir
4132         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4133 }
4134 run_test 33b "test open file with malformed flags (No panic)"
4135
4136 test_33c() {
4137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4138         remote_ost_nodsh && skip "remote OST with nodsh"
4139
4140         local ostnum
4141         local ostname
4142         local write_bytes
4143         local all_zeros
4144
4145         all_zeros=true
4146         test_mkdir $DIR/$tdir
4147         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4148
4149         sync
4150         for ostnum in $(seq $OSTCOUNT); do
4151                 # test-framework's OST numbering is one-based, while Lustre's
4152                 # is zero-based
4153                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4154                 # check if at least some write_bytes stats are counted
4155                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4156                               obdfilter.$ostname.stats |
4157                               awk '/^write_bytes/ {print $7}' )
4158                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4159                 if (( ${write_bytes:-0} > 0 )); then
4160                         all_zeros=false
4161                         break
4162                 fi
4163         done
4164
4165         $all_zeros || return 0
4166
4167         # Write four bytes
4168         echo foo > $DIR/$tdir/bar
4169         # Really write them
4170         sync
4171
4172         # Total up write_bytes after writing.  We'd better find non-zeros.
4173         for ostnum in $(seq $OSTCOUNT); do
4174                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4175                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4176                               obdfilter/$ostname/stats |
4177                               awk '/^write_bytes/ {print $7}' )
4178                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4179                 if (( ${write_bytes:-0} > 0 )); then
4180                         all_zeros=false
4181                         break
4182                 fi
4183         done
4184
4185         if $all_zeros; then
4186                 for ostnum in $(seq $OSTCOUNT); do
4187                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4188                         echo "Check write_bytes is in obdfilter.*.stats:"
4189                         do_facet ost$ostnum lctl get_param -n \
4190                                 obdfilter.$ostname.stats
4191                 done
4192                 error "OST not keeping write_bytes stats (b=22312)"
4193         fi
4194 }
4195 run_test 33c "test write_bytes stats"
4196
4197 test_33d() {
4198         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4200
4201         local MDTIDX=1
4202         local remote_dir=$DIR/$tdir/remote_dir
4203
4204         test_mkdir $DIR/$tdir
4205         $LFS mkdir -i $MDTIDX $remote_dir ||
4206                 error "create remote directory failed"
4207
4208         touch $remote_dir/$tfile
4209         chmod 444 $remote_dir/$tfile
4210         chown $RUNAS_ID $remote_dir/$tfile
4211
4212         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4213
4214         chown $RUNAS_ID $remote_dir
4215         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4216                                         error "create" || true
4217         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4218                                     error "open RDWR" || true
4219         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4220 }
4221 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4222
4223 test_33e() {
4224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4225
4226         mkdir $DIR/$tdir
4227
4228         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4229         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4230         mkdir $DIR/$tdir/local_dir
4231
4232         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4233         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4234         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4235
4236         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4237                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4238
4239         rmdir $DIR/$tdir/* || error "rmdir failed"
4240
4241         umask 777
4242         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4243         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4244         mkdir $DIR/$tdir/local_dir
4245
4246         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4247         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4248         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4249
4250         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4251                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4252
4253         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4254
4255         umask 000
4256         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4257         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4258         mkdir $DIR/$tdir/local_dir
4259
4260         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4261         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4262         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4263
4264         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4265                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4266 }
4267 run_test 33e "mkdir and striped directory should have same mode"
4268
4269 cleanup_33f() {
4270         trap 0
4271         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4272 }
4273
4274 test_33f() {
4275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4276         remote_mds_nodsh && skip "remote MDS with nodsh"
4277
4278         mkdir $DIR/$tdir
4279         chmod go+rwx $DIR/$tdir
4280         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4281         trap cleanup_33f EXIT
4282
4283         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4284                 error "cannot create striped directory"
4285
4286         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4287                 error "cannot create files in striped directory"
4288
4289         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4290                 error "cannot remove files in striped directory"
4291
4292         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4293                 error "cannot remove striped directory"
4294
4295         cleanup_33f
4296 }
4297 run_test 33f "nonroot user can create, access, and remove a striped directory"
4298
4299 test_33g() {
4300         mkdir -p $DIR/$tdir/dir2
4301
4302         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4303         echo $err
4304         [[ $err =~ "exists" ]] || error "Not exists error"
4305 }
4306 run_test 33g "nonroot user create already existing root created file"
4307
4308 sub_33h() {
4309         local hash_type=$1
4310         local count=250
4311
4312         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4313                 error "lfs mkdir -H $hash_type $tdir failed"
4314         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4315
4316         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4317         local index2
4318         local fname
4319
4320         for fname in $DIR/$tdir/$tfile.bak \
4321                      $DIR/$tdir/$tfile.SAV \
4322                      $DIR/$tdir/$tfile.orig \
4323                      $DIR/$tdir/$tfile~; do
4324                 touch $fname || error "touch $fname failed"
4325                 index2=$($LFS getstripe -m $fname)
4326                 (( $index == $index2 )) ||
4327                         error "$fname MDT index mismatch $index != $index2"
4328         done
4329
4330         local failed=0
4331         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4332         local pattern
4333
4334         for pattern in ${patterns[*]}; do
4335                 echo "pattern $pattern"
4336                 fname=$DIR/$tdir/$pattern
4337                 for (( i = 0; i < $count; i++ )); do
4338                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4339                                 error "mktemp $DIR/$tdir/$pattern failed"
4340                         index2=$($LFS getstripe -m $fname)
4341                         (( $index == $index2 )) && continue
4342
4343                         failed=$((failed + 1))
4344                         echo "$fname MDT index mismatch $index != $index2"
4345                 done
4346         done
4347
4348         echo "$failed/$count MDT index mismatches, expect ~2-4"
4349         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4350
4351         local same=0
4352         local expect
4353
4354         # verify that "crush" is still broken with all files on same MDT,
4355         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4356         [[ "$hash_type" == "crush" ]] && expect=$count ||
4357                 expect=$((count / MDSCOUNT))
4358
4359         # crush2 doesn't put all-numeric suffixes on the same MDT,
4360         # filename like $tfile.12345678 should *not* be considered temp
4361         for pattern in ${patterns[*]}; do
4362                 local base=${pattern%%X*}
4363                 local suff=${pattern#$base}
4364
4365                 echo "pattern $pattern"
4366                 for (( i = 0; i < $count; i++ )); do
4367                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4368                         touch $fname || error "touch $fname failed"
4369                         index2=$($LFS getstripe -m $fname)
4370                         (( $index != $index2 )) && continue
4371
4372                         same=$((same + 1))
4373                 done
4374         done
4375
4376         # the number of "bad" hashes is random, as it depends on the random
4377         # filenames generated by "mktemp".  Allow some margin in the results.
4378         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4379         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4380            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4381                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4382         same=0
4383
4384         # crush2 doesn't put suffixes with special characters on the same MDT
4385         # filename like $tfile.txt.1234 should *not* be considered temp
4386         for pattern in ${patterns[*]}; do
4387                 local base=${pattern%%X*}
4388                 local suff=${pattern#$base}
4389
4390                 pattern=$base...${suff/XXX}
4391                 echo "pattern=$pattern"
4392                 for (( i = 0; i < $count; i++ )); do
4393                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4394                                 error "touch $fname failed"
4395                         index2=$($LFS getstripe -m $fname)
4396                         (( $index != $index2 )) && continue
4397
4398                         same=$((same + 1))
4399                 done
4400         done
4401
4402         # the number of "bad" hashes is random, as it depends on the random
4403         # filenames generated by "mktemp".  Allow some margin in the results.
4404         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4405         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4406            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4407                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4408 }
4409
4410 test_33h() {
4411         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4412         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4413                 skip "Need MDS version at least 2.13.50"
4414
4415         sub_33h crush
4416 }
4417 run_test 33h "temp file is located on the same MDT as target (crush)"
4418
4419 test_33hh() {
4420         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4421         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4422         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4423                 skip "Need MDS version at least 2.15.0 for crush2"
4424
4425         sub_33h crush2
4426 }
4427 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4428
4429 test_33i()
4430 {
4431         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4432
4433         local FNAME=$(str_repeat 'f' 250)
4434
4435         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4436         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4437
4438         local count
4439         local total
4440
4441         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4442
4443         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4444
4445         lctl --device %$MDC deactivate
4446         stack_trap "lctl --device %$MDC activate"
4447         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4448         total=$(\ls -l $DIR/$tdir | wc -l)
4449         # "ls -l" will list total in the first line
4450         total=$((total - 1))
4451         (( total + count == 1000 )) ||
4452                 error "ls list $total files, $count files on MDT1"
4453 }
4454 run_test 33i "striped directory can be accessed when one MDT is down"
4455
4456 test_33j() {
4457         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4458
4459         mkdir -p $DIR/$tdir/
4460
4461         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4462                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4463
4464         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4465                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4466
4467         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4468                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4469
4470         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4471                 error "-D was not specified, but still failed"
4472 }
4473 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4474
4475 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4476 test_34a() {
4477         rm -f $DIR/f34
4478         $MCREATE $DIR/f34 || error "mcreate failed"
4479         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4480                 error "getstripe failed"
4481         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4482         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4483                 error "getstripe failed"
4484         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4485                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4486 }
4487 run_test 34a "truncate file that has not been opened ==========="
4488
4489 test_34b() {
4490         [ ! -f $DIR/f34 ] && test_34a
4491         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4492                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4493         $OPENFILE -f O_RDONLY $DIR/f34
4494         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4495                 error "getstripe failed"
4496         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4497                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4498 }
4499 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4500
4501 test_34c() {
4502         [ ! -f $DIR/f34 ] && test_34a
4503         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4504                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4505         $OPENFILE -f O_RDWR $DIR/f34
4506         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4507                 error "$LFS getstripe failed"
4508         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4509                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4510 }
4511 run_test 34c "O_RDWR opening file-with-size works =============="
4512
4513 test_34d() {
4514         [ ! -f $DIR/f34 ] && test_34a
4515         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4516                 error "dd failed"
4517         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4518                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4519         rm $DIR/f34
4520 }
4521 run_test 34d "write to sparse file ============================="
4522
4523 test_34e() {
4524         rm -f $DIR/f34e
4525         $MCREATE $DIR/f34e || error "mcreate failed"
4526         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4527         $CHECKSTAT -s 1000 $DIR/f34e ||
4528                 error "Size of $DIR/f34e not equal to 1000 bytes"
4529         $OPENFILE -f O_RDWR $DIR/f34e
4530         $CHECKSTAT -s 1000 $DIR/f34e ||
4531                 error "Size of $DIR/f34e not equal to 1000 bytes"
4532 }
4533 run_test 34e "create objects, some with size and some without =="
4534
4535 test_34f() { # bug 6242, 6243
4536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4537
4538         SIZE34F=48000
4539         rm -f $DIR/f34f
4540         $MCREATE $DIR/f34f || error "mcreate failed"
4541         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4542         dd if=$DIR/f34f of=$TMP/f34f
4543         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4544         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4545         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4546         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4547         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4548 }
4549 run_test 34f "read from a file with no objects until EOF ======="
4550
4551 test_34g() {
4552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4553
4554         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4555                 error "dd failed"
4556         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4557         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4558                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4559         cancel_lru_locks osc
4560         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4561                 error "wrong size after lock cancel"
4562
4563         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4564         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4565                 error "expanding truncate failed"
4566         cancel_lru_locks osc
4567         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4568                 error "wrong expanded size after lock cancel"
4569 }
4570 run_test 34g "truncate long file ==============================="
4571
4572 test_34h() {
4573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4574
4575         local gid=10
4576         local sz=1000
4577
4578         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4579         sync # Flush the cache so that multiop below does not block on cache
4580              # flush when getting the group lock
4581         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4582         MULTIPID=$!
4583
4584         # Since just timed wait is not good enough, let's do a sync write
4585         # that way we are sure enough time for a roundtrip + processing
4586         # passed + 2 seconds of extra margin.
4587         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4588         rm $DIR/${tfile}-1
4589         sleep 2
4590
4591         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4592                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4593                 kill -9 $MULTIPID
4594         fi
4595         wait $MULTIPID
4596         local nsz=`stat -c %s $DIR/$tfile`
4597         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4598 }
4599 run_test 34h "ftruncate file under grouplock should not block"
4600
4601 test_35a() {
4602         cp /bin/sh $DIR/f35a
4603         chmod 444 $DIR/f35a
4604         chown $RUNAS_ID $DIR/f35a
4605         $RUNAS $DIR/f35a && error || true
4606         rm $DIR/f35a
4607 }
4608 run_test 35a "exec file with mode 444 (should return and not leak)"
4609
4610 test_36a() {
4611         rm -f $DIR/f36
4612         utime $DIR/f36 || error "utime failed for MDS"
4613 }
4614 run_test 36a "MDS utime check (mknod, utime)"
4615
4616 test_36b() {
4617         echo "" > $DIR/f36
4618         utime $DIR/f36 || error "utime failed for OST"
4619 }
4620 run_test 36b "OST utime check (open, utime)"
4621
4622 test_36c() {
4623         rm -f $DIR/d36/f36
4624         test_mkdir $DIR/d36
4625         chown $RUNAS_ID $DIR/d36
4626         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4627 }
4628 run_test 36c "non-root MDS utime check (mknod, utime)"
4629
4630 test_36d() {
4631         [ ! -d $DIR/d36 ] && test_36c
4632         echo "" > $DIR/d36/f36
4633         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4634 }
4635 run_test 36d "non-root OST utime check (open, utime)"
4636
4637 test_36e() {
4638         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4639
4640         test_mkdir $DIR/$tdir
4641         touch $DIR/$tdir/$tfile
4642         $RUNAS utime $DIR/$tdir/$tfile &&
4643                 error "utime worked, expected failure" || true
4644 }
4645 run_test 36e "utime on non-owned file (should return error)"
4646
4647 subr_36fh() {
4648         local fl="$1"
4649         local LANG_SAVE=$LANG
4650         local LC_LANG_SAVE=$LC_LANG
4651         export LANG=C LC_LANG=C # for date language
4652
4653         DATESTR="Dec 20  2000"
4654         test_mkdir $DIR/$tdir
4655         lctl set_param fail_loc=$fl
4656         date; date +%s
4657         cp /etc/hosts $DIR/$tdir/$tfile
4658         sync & # write RPC generated with "current" inode timestamp, but delayed
4659         sleep 1
4660         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4661         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4662         cancel_lru_locks $OSC
4663         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4664         date; date +%s
4665         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4666                 echo "BEFORE: $LS_BEFORE" && \
4667                 echo "AFTER : $LS_AFTER" && \
4668                 echo "WANT  : $DATESTR" && \
4669                 error "$DIR/$tdir/$tfile timestamps changed" || true
4670
4671         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4672 }
4673
4674 test_36f() {
4675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4676
4677         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4678         subr_36fh "0x80000214"
4679 }
4680 run_test 36f "utime on file racing with OST BRW write =========="
4681
4682 test_36g() {
4683         remote_ost_nodsh && skip "remote OST with nodsh"
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4686                 skip "Need MDS version at least 2.12.51"
4687
4688         local fmd_max_age
4689         local fmd
4690         local facet="ost1"
4691         local tgt="obdfilter"
4692
4693         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4694
4695         test_mkdir $DIR/$tdir
4696         fmd_max_age=$(do_facet $facet \
4697                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4698                 head -n 1")
4699
4700         echo "FMD max age: ${fmd_max_age}s"
4701         touch $DIR/$tdir/$tfile
4702         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4703                 gawk '{cnt=cnt+$1}  END{print cnt}')
4704         echo "FMD before: $fmd"
4705         [[ $fmd == 0 ]] &&
4706                 error "FMD wasn't create by touch"
4707         sleep $((fmd_max_age + 12))
4708         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4709                 gawk '{cnt=cnt+$1}  END{print cnt}')
4710         echo "FMD after: $fmd"
4711         [[ $fmd == 0 ]] ||
4712                 error "FMD wasn't expired by ping"
4713 }
4714 run_test 36g "FMD cache expiry ====================="
4715
4716 test_36h() {
4717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4718
4719         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4720         subr_36fh "0x80000227"
4721 }
4722 run_test 36h "utime on file racing with OST BRW write =========="
4723
4724 test_36i() {
4725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4726
4727         test_mkdir $DIR/$tdir
4728         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4729
4730         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4731         local new_mtime=$((mtime + 200))
4732
4733         #change Modify time of striped dir
4734         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4735                         error "change mtime failed"
4736
4737         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4738
4739         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4740 }
4741 run_test 36i "change mtime on striped directory"
4742
4743 # test_37 - duplicate with tests 32q 32r
4744
4745 test_38() {
4746         local file=$DIR/$tfile
4747         touch $file
4748         openfile -f O_DIRECTORY $file
4749         local RC=$?
4750         local ENOTDIR=20
4751         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4752         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4753 }
4754 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4755
4756 test_39a() { # was test_39
4757         touch $DIR/$tfile
4758         touch $DIR/${tfile}2
4759 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4760 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4761 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4762         sleep 2
4763         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4764         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4765                 echo "mtime"
4766                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4767                 echo "atime"
4768                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4769                 echo "ctime"
4770                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4771                 error "O_TRUNC didn't change timestamps"
4772         fi
4773 }
4774 run_test 39a "mtime changed on create"
4775
4776 test_39b() {
4777         test_mkdir -c1 $DIR/$tdir
4778         cp -p /etc/passwd $DIR/$tdir/fopen
4779         cp -p /etc/passwd $DIR/$tdir/flink
4780         cp -p /etc/passwd $DIR/$tdir/funlink
4781         cp -p /etc/passwd $DIR/$tdir/frename
4782         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4783
4784         sleep 1
4785         echo "aaaaaa" >> $DIR/$tdir/fopen
4786         echo "aaaaaa" >> $DIR/$tdir/flink
4787         echo "aaaaaa" >> $DIR/$tdir/funlink
4788         echo "aaaaaa" >> $DIR/$tdir/frename
4789
4790         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4791         local link_new=`stat -c %Y $DIR/$tdir/flink`
4792         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4793         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4794
4795         cat $DIR/$tdir/fopen > /dev/null
4796         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4797         rm -f $DIR/$tdir/funlink2
4798         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4799
4800         for (( i=0; i < 2; i++ )) ; do
4801                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4802                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4803                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4804                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4805
4806                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4807                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4808                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4809                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4810
4811                 cancel_lru_locks $OSC
4812                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4813         done
4814 }
4815 run_test 39b "mtime change on open, link, unlink, rename  ======"
4816
4817 # this should be set to past
4818 TEST_39_MTIME=`date -d "1 year ago" +%s`
4819
4820 # bug 11063
4821 test_39c() {
4822         touch $DIR1/$tfile
4823         sleep 2
4824         local mtime0=`stat -c %Y $DIR1/$tfile`
4825
4826         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4827         local mtime1=`stat -c %Y $DIR1/$tfile`
4828         [ "$mtime1" = $TEST_39_MTIME ] || \
4829                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4830
4831         local d1=`date +%s`
4832         echo hello >> $DIR1/$tfile
4833         local d2=`date +%s`
4834         local mtime2=`stat -c %Y $DIR1/$tfile`
4835         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4836                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4837
4838         mv $DIR1/$tfile $DIR1/$tfile-1
4839
4840         for (( i=0; i < 2; i++ )) ; do
4841                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4842                 [ "$mtime2" = "$mtime3" ] || \
4843                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4844
4845                 cancel_lru_locks $OSC
4846                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4847         done
4848 }
4849 run_test 39c "mtime change on rename ==========================="
4850
4851 # bug 21114
4852 test_39d() {
4853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4854
4855         touch $DIR1/$tfile
4856         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4857
4858         for (( i=0; i < 2; i++ )) ; do
4859                 local mtime=`stat -c %Y $DIR1/$tfile`
4860                 [ $mtime = $TEST_39_MTIME ] || \
4861                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4862
4863                 cancel_lru_locks $OSC
4864                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4865         done
4866 }
4867 run_test 39d "create, utime, stat =============================="
4868
4869 # bug 21114
4870 test_39e() {
4871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4872
4873         touch $DIR1/$tfile
4874         local mtime1=`stat -c %Y $DIR1/$tfile`
4875
4876         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4877
4878         for (( i=0; i < 2; i++ )) ; do
4879                 local mtime2=`stat -c %Y $DIR1/$tfile`
4880                 [ $mtime2 = $TEST_39_MTIME ] || \
4881                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4882
4883                 cancel_lru_locks $OSC
4884                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4885         done
4886 }
4887 run_test 39e "create, stat, utime, stat ========================"
4888
4889 # bug 21114
4890 test_39f() {
4891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4892
4893         touch $DIR1/$tfile
4894         mtime1=`stat -c %Y $DIR1/$tfile`
4895
4896         sleep 2
4897         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4898
4899         for (( i=0; i < 2; i++ )) ; do
4900                 local mtime2=`stat -c %Y $DIR1/$tfile`
4901                 [ $mtime2 = $TEST_39_MTIME ] || \
4902                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4903
4904                 cancel_lru_locks $OSC
4905                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4906         done
4907 }
4908 run_test 39f "create, stat, sleep, utime, stat ================="
4909
4910 # bug 11063
4911 test_39g() {
4912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4913
4914         echo hello >> $DIR1/$tfile
4915         local mtime1=`stat -c %Y $DIR1/$tfile`
4916
4917         sleep 2
4918         chmod o+r $DIR1/$tfile
4919
4920         for (( i=0; i < 2; i++ )) ; do
4921                 local mtime2=`stat -c %Y $DIR1/$tfile`
4922                 [ "$mtime1" = "$mtime2" ] || \
4923                         error "lost mtime: $mtime2, should be $mtime1"
4924
4925                 cancel_lru_locks $OSC
4926                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4927         done
4928 }
4929 run_test 39g "write, chmod, stat ==============================="
4930
4931 # bug 11063
4932 test_39h() {
4933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4934
4935         touch $DIR1/$tfile
4936         sleep 1
4937
4938         local d1=`date`
4939         echo hello >> $DIR1/$tfile
4940         local mtime1=`stat -c %Y $DIR1/$tfile`
4941
4942         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4943         local d2=`date`
4944         if [ "$d1" != "$d2" ]; then
4945                 echo "write and touch not within one second"
4946         else
4947                 for (( i=0; i < 2; i++ )) ; do
4948                         local mtime2=`stat -c %Y $DIR1/$tfile`
4949                         [ "$mtime2" = $TEST_39_MTIME ] || \
4950                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4951
4952                         cancel_lru_locks $OSC
4953                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4954                 done
4955         fi
4956 }
4957 run_test 39h "write, utime within one second, stat ============="
4958
4959 test_39i() {
4960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4961
4962         touch $DIR1/$tfile
4963         sleep 1
4964
4965         echo hello >> $DIR1/$tfile
4966         local mtime1=`stat -c %Y $DIR1/$tfile`
4967
4968         mv $DIR1/$tfile $DIR1/$tfile-1
4969
4970         for (( i=0; i < 2; i++ )) ; do
4971                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4972
4973                 [ "$mtime1" = "$mtime2" ] || \
4974                         error "lost mtime: $mtime2, should be $mtime1"
4975
4976                 cancel_lru_locks $OSC
4977                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4978         done
4979 }
4980 run_test 39i "write, rename, stat =============================="
4981
4982 test_39j() {
4983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4984
4985         start_full_debug_logging
4986         touch $DIR1/$tfile
4987         sleep 1
4988
4989         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4990         lctl set_param fail_loc=0x80000412
4991         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4992                 error "multiop failed"
4993         local multipid=$!
4994         local mtime1=`stat -c %Y $DIR1/$tfile`
4995
4996         mv $DIR1/$tfile $DIR1/$tfile-1
4997
4998         kill -USR1 $multipid
4999         wait $multipid || error "multiop close failed"
5000
5001         for (( i=0; i < 2; i++ )) ; do
5002                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5003                 [ "$mtime1" = "$mtime2" ] ||
5004                         error "mtime is lost on close: $mtime2, " \
5005                               "should be $mtime1"
5006
5007                 cancel_lru_locks
5008                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5009         done
5010         lctl set_param fail_loc=0
5011         stop_full_debug_logging
5012 }
5013 run_test 39j "write, rename, close, stat ======================="
5014
5015 test_39k() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         touch $DIR1/$tfile
5019         sleep 1
5020
5021         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5022         local multipid=$!
5023         local mtime1=`stat -c %Y $DIR1/$tfile`
5024
5025         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5026
5027         kill -USR1 $multipid
5028         wait $multipid || error "multiop close failed"
5029
5030         for (( i=0; i < 2; i++ )) ; do
5031                 local mtime2=`stat -c %Y $DIR1/$tfile`
5032
5033                 [ "$mtime2" = $TEST_39_MTIME ] || \
5034                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5035
5036                 cancel_lru_locks
5037                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5038         done
5039 }
5040 run_test 39k "write, utime, close, stat ========================"
5041
5042 # this should be set to future
5043 TEST_39_ATIME=`date -d "1 year" +%s`
5044
5045 test_39l() {
5046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5047         remote_mds_nodsh && skip "remote MDS with nodsh"
5048
5049         local atime_diff=$(do_facet $SINGLEMDS \
5050                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5051         rm -rf $DIR/$tdir
5052         mkdir_on_mdt0 $DIR/$tdir
5053
5054         # test setting directory atime to future
5055         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5056         local atime=$(stat -c %X $DIR/$tdir)
5057         [ "$atime" = $TEST_39_ATIME ] ||
5058                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5059
5060         # test setting directory atime from future to now
5061         local now=$(date +%s)
5062         touch -a -d @$now $DIR/$tdir
5063
5064         atime=$(stat -c %X $DIR/$tdir)
5065         [ "$atime" -eq "$now"  ] ||
5066                 error "atime is not updated from future: $atime, $now"
5067
5068         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5069         sleep 3
5070
5071         # test setting directory atime when now > dir atime + atime_diff
5072         local d1=$(date +%s)
5073         ls $DIR/$tdir
5074         local d2=$(date +%s)
5075         cancel_lru_locks mdc
5076         atime=$(stat -c %X $DIR/$tdir)
5077         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5078                 error "atime is not updated  : $atime, should be $d2"
5079
5080         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5081         sleep 3
5082
5083         # test not setting directory atime when now < dir atime + atime_diff
5084         ls $DIR/$tdir
5085         cancel_lru_locks mdc
5086         atime=$(stat -c %X $DIR/$tdir)
5087         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5088                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5089
5090         do_facet $SINGLEMDS \
5091                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5092 }
5093 run_test 39l "directory atime update ==========================="
5094
5095 test_39m() {
5096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5097
5098         touch $DIR1/$tfile
5099         sleep 2
5100         local far_past_mtime=$(date -d "May 29 1953" +%s)
5101         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5102
5103         touch -m -d @$far_past_mtime $DIR1/$tfile
5104         touch -a -d @$far_past_atime $DIR1/$tfile
5105
5106         for (( i=0; i < 2; i++ )) ; do
5107                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5108                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5109                         error "atime or mtime set incorrectly"
5110
5111                 cancel_lru_locks $OSC
5112                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5113         done
5114 }
5115 run_test 39m "test atime and mtime before 1970"
5116
5117 test_39n() { # LU-3832
5118         remote_mds_nodsh && skip "remote MDS with nodsh"
5119
5120         local atime_diff=$(do_facet $SINGLEMDS \
5121                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5122         local atime0
5123         local atime1
5124         local atime2
5125
5126         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5127
5128         rm -rf $DIR/$tfile
5129         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5130         atime0=$(stat -c %X $DIR/$tfile)
5131
5132         sleep 5
5133         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5134         atime1=$(stat -c %X $DIR/$tfile)
5135
5136         sleep 5
5137         cancel_lru_locks mdc
5138         cancel_lru_locks osc
5139         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5140         atime2=$(stat -c %X $DIR/$tfile)
5141
5142         do_facet $SINGLEMDS \
5143                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5144
5145         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5146         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5147 }
5148 run_test 39n "check that O_NOATIME is honored"
5149
5150 test_39o() {
5151         TESTDIR=$DIR/$tdir/$tfile
5152         [ -e $TESTDIR ] && rm -rf $TESTDIR
5153         mkdir -p $TESTDIR
5154         cd $TESTDIR
5155         links1=2
5156         ls
5157         mkdir a b
5158         ls
5159         links2=$(stat -c %h .)
5160         [ $(($links1 + 2)) != $links2 ] &&
5161                 error "wrong links count $(($links1 + 2)) != $links2"
5162         rmdir b
5163         links3=$(stat -c %h .)
5164         [ $(($links1 + 1)) != $links3 ] &&
5165                 error "wrong links count $links1 != $links3"
5166         return 0
5167 }
5168 run_test 39o "directory cached attributes updated after create"
5169
5170 test_39p() {
5171         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5172
5173         local MDTIDX=1
5174         TESTDIR=$DIR/$tdir/$tdir
5175         [ -e $TESTDIR ] && rm -rf $TESTDIR
5176         test_mkdir -p $TESTDIR
5177         cd $TESTDIR
5178         links1=2
5179         ls
5180         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5181         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5182         ls
5183         links2=$(stat -c %h .)
5184         [ $(($links1 + 2)) != $links2 ] &&
5185                 error "wrong links count $(($links1 + 2)) != $links2"
5186         rmdir remote_dir2
5187         links3=$(stat -c %h .)
5188         [ $(($links1 + 1)) != $links3 ] &&
5189                 error "wrong links count $links1 != $links3"
5190         return 0
5191 }
5192 run_test 39p "remote directory cached attributes updated after create ========"
5193
5194 test_39r() {
5195         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5196                 skip "no atime update on old OST"
5197         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5198                 skip_env "ldiskfs only test"
5199         fi
5200
5201         local saved_adiff
5202         saved_adiff=$(do_facet ost1 \
5203                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5204         stack_trap "do_facet ost1 \
5205                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5206
5207         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5208
5209         $LFS setstripe -i 0 $DIR/$tfile
5210         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5211                 error "can't write initial file"
5212         cancel_lru_locks osc
5213
5214         # exceed atime_diff and access file
5215         sleep 10
5216         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5217                 error "can't udpate atime"
5218
5219         local atime_cli=$(stat -c %X $DIR/$tfile)
5220         echo "client atime: $atime_cli"
5221         # allow atime update to be written to device
5222         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5223         sleep 5
5224
5225         local ostdev=$(ostdevname 1)
5226         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5227         local seq=${fid[3]#0x}
5228         local oid=${fid[1]}
5229         local oid_hex
5230
5231         if [ $seq == 0 ]; then
5232                 oid_hex=${fid[1]}
5233         else
5234                 oid_hex=${fid[2]#0x}
5235         fi
5236         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5237         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5238
5239         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5240         local atime_ost=$(do_facet ost1 "$cmd" |&
5241                           awk -F'[: ]' '/atime:/ { print $4 }')
5242         (( atime_cli == atime_ost )) ||
5243                 error "atime on client $atime_cli != ost $atime_ost"
5244 }
5245 run_test 39r "lazy atime update on OST"
5246
5247 test_39q() { # LU-8041
5248         local testdir=$DIR/$tdir
5249         mkdir -p $testdir
5250         multiop_bg_pause $testdir D_c || error "multiop failed"
5251         local multipid=$!
5252         cancel_lru_locks mdc
5253         kill -USR1 $multipid
5254         local atime=$(stat -c %X $testdir)
5255         [ "$atime" -ne 0 ] || error "atime is zero"
5256 }
5257 run_test 39q "close won't zero out atime"
5258
5259 test_39s() {
5260         local atime0
5261         local atime1
5262         local atime2
5263         local atime3
5264         local atime4
5265
5266         umount_client $MOUNT
5267         mount_client $MOUNT relatime
5268
5269         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5270         atime0=$(stat -c %X $DIR/$tfile)
5271
5272         # First read updates atime
5273         sleep 1
5274         cat $DIR/$tfile >/dev/null
5275         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5276
5277         # Next reads do not update atime
5278         sleep 1
5279         cat $DIR/$tfile >/dev/null
5280         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5281
5282         # If mtime is greater than atime, atime is updated
5283         sleep 1
5284         touch -m $DIR/$tfile # (mtime = now)
5285         sleep 1
5286         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5287         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5288
5289         # Next reads do not update atime
5290         sleep 1
5291         cat $DIR/$tfile >/dev/null
5292         atime4=$(stat -c %X $DIR/$tfile)
5293
5294         # Remount the client to clear 'relatime' option
5295         remount_client $MOUNT
5296
5297         if (( MDS1_VERSION >= $(version_code 2.15.50) )); then
5298                 # The full test lasted less than default atime_diff
5299                 # Client was remounted to clear 'relatime' option for next tests
5300                 # and to confirm atime was written to disk
5301                 local atime5=$(stat -c %X $DIR/$tfile)
5302                 (( atime3 == atime5 )) ||
5303                         error "atime3 $atime3 != atime5 $atime5"
5304         fi
5305
5306         (( atime0 < atime1 )) ||
5307                 error "atime $atime0 should be smaller than $atime1"
5308         (( atime1 == atime2 )) ||
5309                 error "atime $atime1 was updated to $atime2"
5310         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5311         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5312 }
5313 run_test 39s "relatime is supported"
5314
5315 test_40() {
5316         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5317         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5318                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5319         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5320                 error "$tfile is not 4096 bytes in size"
5321 }
5322 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5323
5324 test_41() {
5325         # bug 1553
5326         small_write $DIR/f41 18
5327 }
5328 run_test 41 "test small file write + fstat ====================="
5329
5330 count_ost_writes() {
5331         lctl get_param -n ${OSC}.*.stats |
5332                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5333                         END { printf("%0.0f", writes) }'
5334 }
5335
5336 # decent default
5337 WRITEBACK_SAVE=500
5338 DIRTY_RATIO_SAVE=40
5339 MAX_DIRTY_RATIO=50
5340 BG_DIRTY_RATIO_SAVE=10
5341 MAX_BG_DIRTY_RATIO=25
5342
5343 start_writeback() {
5344         trap 0
5345         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5346         # dirty_ratio, dirty_background_ratio
5347         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5348                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5349                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5350                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5351         else
5352                 # if file not here, we are a 2.4 kernel
5353                 kill -CONT `pidof kupdated`
5354         fi
5355 }
5356
5357 stop_writeback() {
5358         # setup the trap first, so someone cannot exit the test at the
5359         # exact wrong time and mess up a machine
5360         trap start_writeback EXIT
5361         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5362         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5363                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5364                 sysctl -w vm.dirty_writeback_centisecs=0
5365                 sysctl -w vm.dirty_writeback_centisecs=0
5366                 # save and increase /proc/sys/vm/dirty_ratio
5367                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5368                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5369                 # save and increase /proc/sys/vm/dirty_background_ratio
5370                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5371                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5372         else
5373                 # if file not here, we are a 2.4 kernel
5374                 kill -STOP `pidof kupdated`
5375         fi
5376 }
5377
5378 # ensure that all stripes have some grant before we test client-side cache
5379 setup_test42() {
5380         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5381                 dd if=/dev/zero of=$i bs=4k count=1
5382                 rm $i
5383         done
5384 }
5385
5386 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5387 # file truncation, and file removal.
5388 test_42a() {
5389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5390
5391         setup_test42
5392         cancel_lru_locks $OSC
5393         stop_writeback
5394         sync; sleep 1; sync # just to be safe
5395         BEFOREWRITES=`count_ost_writes`
5396         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5397         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5398         AFTERWRITES=`count_ost_writes`
5399         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5400                 error "$BEFOREWRITES < $AFTERWRITES"
5401         start_writeback
5402 }
5403 run_test 42a "ensure that we don't flush on close"
5404
5405 test_42b() {
5406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5407
5408         setup_test42
5409         cancel_lru_locks $OSC
5410         stop_writeback
5411         sync
5412         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5413         BEFOREWRITES=$(count_ost_writes)
5414         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5415         AFTERWRITES=$(count_ost_writes)
5416         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5417                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5418         fi
5419         BEFOREWRITES=$(count_ost_writes)
5420         sync || error "sync: $?"
5421         AFTERWRITES=$(count_ost_writes)
5422         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5423                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5424         fi
5425         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5426         start_writeback
5427         return 0
5428 }
5429 run_test 42b "test destroy of file with cached dirty data ======"
5430
5431 # if these tests just want to test the effect of truncation,
5432 # they have to be very careful.  consider:
5433 # - the first open gets a {0,EOF}PR lock
5434 # - the first write conflicts and gets a {0, count-1}PW
5435 # - the rest of the writes are under {count,EOF}PW
5436 # - the open for truncate tries to match a {0,EOF}PR
5437 #   for the filesize and cancels the PWs.
5438 # any number of fixes (don't get {0,EOF} on open, match
5439 # composite locks, do smarter file size management) fix
5440 # this, but for now we want these tests to verify that
5441 # the cancellation with truncate intent works, so we
5442 # start the file with a full-file pw lock to match against
5443 # until the truncate.
5444 trunc_test() {
5445         test=$1
5446         file=$DIR/$test
5447         offset=$2
5448         cancel_lru_locks $OSC
5449         stop_writeback
5450         # prime the file with 0,EOF PW to match
5451         touch $file
5452         $TRUNCATE $file 0
5453         sync; sync
5454         # now the real test..
5455         dd if=/dev/zero of=$file bs=1024 count=100
5456         BEFOREWRITES=`count_ost_writes`
5457         $TRUNCATE $file $offset
5458         cancel_lru_locks $OSC
5459         AFTERWRITES=`count_ost_writes`
5460         start_writeback
5461 }
5462
5463 test_42c() {
5464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5465
5466         trunc_test 42c 1024
5467         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5468                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5469         rm $file
5470 }
5471 run_test 42c "test partial truncate of file with cached dirty data"
5472
5473 test_42d() {
5474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5475
5476         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5477         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5478         $LCTL set_param debug=+cache
5479
5480         trunc_test 42d 0
5481         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5482                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5483         rm $file
5484 }
5485 run_test 42d "test complete truncate of file with cached dirty data"
5486
5487 test_42e() { # bug22074
5488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5489
5490         local TDIR=$DIR/${tdir}e
5491         local pages=16 # hardcoded 16 pages, don't change it.
5492         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5493         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5494         local max_dirty_mb
5495         local warmup_files
5496
5497         test_mkdir $DIR/${tdir}e
5498         $LFS setstripe -c 1 $TDIR
5499         createmany -o $TDIR/f $files
5500
5501         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5502
5503         # we assume that with $OSTCOUNT files, at least one of them will
5504         # be allocated on OST0.
5505         warmup_files=$((OSTCOUNT * max_dirty_mb))
5506         createmany -o $TDIR/w $warmup_files
5507
5508         # write a large amount of data into one file and sync, to get good
5509         # avail_grant number from OST.
5510         for ((i=0; i<$warmup_files; i++)); do
5511                 idx=$($LFS getstripe -i $TDIR/w$i)
5512                 [ $idx -ne 0 ] && continue
5513                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5514                 break
5515         done
5516         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5517         sync
5518         $LCTL get_param $proc_osc0/cur_dirty_bytes
5519         $LCTL get_param $proc_osc0/cur_grant_bytes
5520
5521         # create as much dirty pages as we can while not to trigger the actual
5522         # RPCs directly. but depends on the env, VFS may trigger flush during this
5523         # period, hopefully we are good.
5524         for ((i=0; i<$warmup_files; i++)); do
5525                 idx=$($LFS getstripe -i $TDIR/w$i)
5526                 [ $idx -ne 0 ] && continue
5527                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5528         done
5529         $LCTL get_param $proc_osc0/cur_dirty_bytes
5530         $LCTL get_param $proc_osc0/cur_grant_bytes
5531
5532         # perform the real test
5533         $LCTL set_param $proc_osc0/rpc_stats 0
5534         for ((;i<$files; i++)); do
5535                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5536                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5537         done
5538         sync
5539         $LCTL get_param $proc_osc0/rpc_stats
5540
5541         local percent=0
5542         local have_ppr=false
5543         $LCTL get_param $proc_osc0/rpc_stats |
5544                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5545                         # skip lines until we are at the RPC histogram data
5546                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5547                         $have_ppr || continue
5548
5549                         # we only want the percent stat for < 16 pages
5550                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5551
5552                         percent=$((percent + WPCT))
5553                         if [[ $percent -gt 15 ]]; then
5554                                 error "less than 16-pages write RPCs" \
5555                                       "$percent% > 15%"
5556                                 break
5557                         fi
5558                 done
5559         rm -rf $TDIR
5560 }
5561 run_test 42e "verify sub-RPC writes are not done synchronously"
5562
5563 test_43A() { # was test_43
5564         test_mkdir $DIR/$tdir
5565         cp -p /bin/ls $DIR/$tdir/$tfile
5566         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5567         pid=$!
5568         # give multiop a chance to open
5569         sleep 1
5570
5571         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5572         kill -USR1 $pid
5573         # Wait for multiop to exit
5574         wait $pid
5575 }
5576 run_test 43A "execution of file opened for write should return -ETXTBSY"
5577
5578 test_43a() {
5579         test_mkdir $DIR/$tdir
5580         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5581         $DIR/$tdir/sleep 60 &
5582         SLEEP_PID=$!
5583         # Make sure exec of $tdir/sleep wins race with truncate
5584         sleep 1
5585         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5586         kill $SLEEP_PID
5587 }
5588 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5589
5590 test_43b() {
5591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5592
5593         test_mkdir $DIR/$tdir
5594         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5595         $DIR/$tdir/sleep 60 &
5596         SLEEP_PID=$!
5597         # Make sure exec of $tdir/sleep wins race with truncate
5598         sleep 1
5599         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5600         kill $SLEEP_PID
5601 }
5602 run_test 43b "truncate of file being executed should return -ETXTBSY"
5603
5604 test_43c() {
5605         local testdir="$DIR/$tdir"
5606         test_mkdir $testdir
5607         cp $SHELL $testdir/
5608         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5609                 ( cd $testdir && md5sum -c )
5610 }
5611 run_test 43c "md5sum of copy into lustre"
5612
5613 test_44A() { # was test_44
5614         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5615
5616         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5617         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5618 }
5619 run_test 44A "zero length read from a sparse stripe"
5620
5621 test_44a() {
5622         local nstripe=$($LFS getstripe -c -d $DIR)
5623         [ -z "$nstripe" ] && skip "can't get stripe info"
5624         [[ $nstripe -gt $OSTCOUNT ]] &&
5625                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5626
5627         local stride=$($LFS getstripe -S -d $DIR)
5628         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5629                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5630         fi
5631
5632         OFFSETS="0 $((stride/2)) $((stride-1))"
5633         for offset in $OFFSETS; do
5634                 for i in $(seq 0 $((nstripe-1))); do
5635                         local GLOBALOFFSETS=""
5636                         # size in Bytes
5637                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5638                         local myfn=$DIR/d44a-$size
5639                         echo "--------writing $myfn at $size"
5640                         ll_sparseness_write $myfn $size ||
5641                                 error "ll_sparseness_write"
5642                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5643                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5644                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5645
5646                         for j in $(seq 0 $((nstripe-1))); do
5647                                 # size in Bytes
5648                                 size=$((((j + $nstripe )*$stride + $offset)))
5649                                 ll_sparseness_write $myfn $size ||
5650                                         error "ll_sparseness_write"
5651                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5652                         done
5653                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5654                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5655                         rm -f $myfn
5656                 done
5657         done
5658 }
5659 run_test 44a "test sparse pwrite ==============================="
5660
5661 dirty_osc_total() {
5662         tot=0
5663         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5664                 tot=$(($tot + $d))
5665         done
5666         echo $tot
5667 }
5668 do_dirty_record() {
5669         before=`dirty_osc_total`
5670         echo executing "\"$*\""
5671         eval $*
5672         after=`dirty_osc_total`
5673         echo before $before, after $after
5674 }
5675 test_45() {
5676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5677
5678         f="$DIR/f45"
5679         # Obtain grants from OST if it supports it
5680         echo blah > ${f}_grant
5681         stop_writeback
5682         sync
5683         do_dirty_record "echo blah > $f"
5684         [[ $before -eq $after ]] && error "write wasn't cached"
5685         do_dirty_record "> $f"
5686         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5687         do_dirty_record "echo blah > $f"
5688         [[ $before -eq $after ]] && error "write wasn't cached"
5689         do_dirty_record "sync"
5690         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5691         do_dirty_record "echo blah > $f"
5692         [[ $before -eq $after ]] && error "write wasn't cached"
5693         do_dirty_record "cancel_lru_locks osc"
5694         [[ $before -gt $after ]] ||
5695                 error "lock cancellation didn't lower dirty count"
5696         start_writeback
5697 }
5698 run_test 45 "osc io page accounting ============================"
5699
5700 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5701 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5702 # objects offset and an assert hit when an rpc was built with 1023's mapped
5703 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5704 test_46() {
5705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5706
5707         f="$DIR/f46"
5708         stop_writeback
5709         sync
5710         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5711         sync
5712         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5713         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5714         sync
5715         start_writeback
5716 }
5717 run_test 46 "dirtying a previously written page ================"
5718
5719 # test_47 is removed "Device nodes check" is moved to test_28
5720
5721 test_48a() { # bug 2399
5722         [ "$mds1_FSTYPE" = "zfs" ] &&
5723         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5724                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5725
5726         test_mkdir $DIR/$tdir
5727         cd $DIR/$tdir
5728         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5729         test_mkdir $DIR/$tdir
5730         touch foo || error "'touch foo' failed after recreating cwd"
5731         test_mkdir bar
5732         touch .foo || error "'touch .foo' failed after recreating cwd"
5733         test_mkdir .bar
5734         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5735         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5736         cd . || error "'cd .' failed after recreating cwd"
5737         mkdir . && error "'mkdir .' worked after recreating cwd"
5738         rmdir . && error "'rmdir .' worked after recreating cwd"
5739         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5740         cd .. || error "'cd ..' failed after recreating cwd"
5741 }
5742 run_test 48a "Access renamed working dir (should return errors)="
5743
5744 test_48b() { # bug 2399
5745         rm -rf $DIR/$tdir
5746         test_mkdir $DIR/$tdir
5747         cd $DIR/$tdir
5748         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5749         touch foo && error "'touch foo' worked after removing cwd"
5750         mkdir foo && error "'mkdir foo' worked after removing cwd"
5751         touch .foo && error "'touch .foo' worked after removing cwd"
5752         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5753         ls . > /dev/null && error "'ls .' worked after removing cwd"
5754         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5755         mkdir . && error "'mkdir .' worked after removing cwd"
5756         rmdir . && error "'rmdir .' worked after removing cwd"
5757         ln -s . foo && error "'ln -s .' worked after removing cwd"
5758         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5759 }
5760 run_test 48b "Access removed working dir (should return errors)="
5761
5762 test_48c() { # bug 2350
5763         #lctl set_param debug=-1
5764         #set -vx
5765         rm -rf $DIR/$tdir
5766         test_mkdir -p $DIR/$tdir/dir
5767         cd $DIR/$tdir/dir
5768         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5769         $TRACE touch foo && error "touch foo worked after removing cwd"
5770         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5771         touch .foo && error "touch .foo worked after removing cwd"
5772         mkdir .foo && error "mkdir .foo worked after removing cwd"
5773         $TRACE ls . && error "'ls .' worked after removing cwd"
5774         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5775         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5776         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5777         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5778         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5779 }
5780 run_test 48c "Access removed working subdir (should return errors)"
5781
5782 test_48d() { # bug 2350
5783         #lctl set_param debug=-1
5784         #set -vx
5785         rm -rf $DIR/$tdir
5786         test_mkdir -p $DIR/$tdir/dir
5787         cd $DIR/$tdir/dir
5788         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5789         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5790         $TRACE touch foo && error "'touch foo' worked after removing parent"
5791         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5792         touch .foo && error "'touch .foo' worked after removing parent"
5793         mkdir .foo && error "mkdir .foo worked after removing parent"
5794         $TRACE ls . && error "'ls .' worked after removing parent"
5795         $TRACE ls .. && error "'ls ..' worked after removing parent"
5796         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5797         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5798         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5799         true
5800 }
5801 run_test 48d "Access removed parent subdir (should return errors)"
5802
5803 test_48e() { # bug 4134
5804         #lctl set_param debug=-1
5805         #set -vx
5806         rm -rf $DIR/$tdir
5807         test_mkdir -p $DIR/$tdir/dir
5808         cd $DIR/$tdir/dir
5809         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5810         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5811         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5812         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5813         # On a buggy kernel addition of "touch foo" after cd .. will
5814         # produce kernel oops in lookup_hash_it
5815         touch ../foo && error "'cd ..' worked after recreate parent"
5816         cd $DIR
5817         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5818 }
5819 run_test 48e "Access to recreated parent subdir (should return errors)"
5820
5821 test_48f() {
5822         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5823                 skip "need MDS >= 2.13.55"
5824         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5825         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5826                 skip "needs different host for mdt1 mdt2"
5827         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5828
5829         $LFS mkdir -i0 $DIR/$tdir
5830         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5831
5832         for d in sub1 sub2 sub3; do
5833                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5834                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5835                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5836         done
5837
5838         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5839 }
5840 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5841
5842 test_49() { # LU-1030
5843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5844         remote_ost_nodsh && skip "remote OST with nodsh"
5845
5846         # get ost1 size - $FSNAME-OST0000
5847         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5848                 awk '{ print $4 }')
5849         # write 800M at maximum
5850         [[ $ost1_size -lt 2 ]] && ost1_size=2
5851         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5852
5853         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5854         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5855         local dd_pid=$!
5856
5857         # change max_pages_per_rpc while writing the file
5858         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5859         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5860         # loop until dd process exits
5861         while ps ax -opid | grep -wq $dd_pid; do
5862                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5863                 sleep $((RANDOM % 5 + 1))
5864         done
5865         # restore original max_pages_per_rpc
5866         $LCTL set_param $osc1_mppc=$orig_mppc
5867         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5868 }
5869 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5870
5871 test_50() {
5872         # bug 1485
5873         test_mkdir $DIR/$tdir
5874         cd $DIR/$tdir
5875         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5876 }
5877 run_test 50 "special situations: /proc symlinks  ==============="
5878
5879 test_51a() {    # was test_51
5880         # bug 1516 - create an empty entry right after ".." then split dir
5881         test_mkdir -c1 $DIR/$tdir
5882         touch $DIR/$tdir/foo
5883         $MCREATE $DIR/$tdir/bar
5884         rm $DIR/$tdir/foo
5885         createmany -m $DIR/$tdir/longfile 201
5886         FNUM=202
5887         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5888                 $MCREATE $DIR/$tdir/longfile$FNUM
5889                 FNUM=$(($FNUM + 1))
5890                 echo -n "+"
5891         done
5892         echo
5893         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5894 }
5895 run_test 51a "special situations: split htree with empty entry =="
5896
5897 cleanup_print_lfs_df () {
5898         trap 0
5899         $LFS df
5900         $LFS df -i
5901 }
5902
5903 test_51b() {
5904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5905
5906         local dir=$DIR/$tdir
5907         local nrdirs=$((65536 + 100))
5908
5909         # cleanup the directory
5910         rm -fr $dir
5911
5912         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5913
5914         $LFS df
5915         $LFS df -i
5916         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5917         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5918         [[ $numfree -lt $nrdirs ]] &&
5919                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5920
5921         # need to check free space for the directories as well
5922         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5923         numfree=$(( blkfree / $(fs_inode_ksize) ))
5924         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5925
5926         trap cleanup_print_lfs_df EXIT
5927
5928         # create files
5929         createmany -d $dir/d $nrdirs || {
5930                 unlinkmany $dir/d $nrdirs
5931                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5932         }
5933
5934         # really created :
5935         nrdirs=$(ls -U $dir | wc -l)
5936
5937         # unlink all but 100 subdirectories, then check it still works
5938         local left=100
5939         local delete=$((nrdirs - left))
5940
5941         $LFS df
5942         $LFS df -i
5943
5944         # for ldiskfs the nlink count should be 1, but this is OSD specific
5945         # and so this is listed for informational purposes only
5946         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5947         unlinkmany -d $dir/d $delete ||
5948                 error "unlink of first $delete subdirs failed"
5949
5950         echo "nlink between: $(stat -c %h $dir)"
5951         local found=$(ls -U $dir | wc -l)
5952         [ $found -ne $left ] &&
5953                 error "can't find subdirs: found only $found, expected $left"
5954
5955         unlinkmany -d $dir/d $delete $left ||
5956                 error "unlink of second $left subdirs failed"
5957         # regardless of whether the backing filesystem tracks nlink accurately
5958         # or not, the nlink count shouldn't be more than "." and ".." here
5959         local after=$(stat -c %h $dir)
5960         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5961                 echo "nlink after: $after"
5962
5963         cleanup_print_lfs_df
5964 }
5965 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5966
5967 test_51d_sub() {
5968         local stripecount=$1
5969         local nfiles=$2
5970
5971         log "create files with stripecount=$stripecount"
5972         $LFS setstripe -C $stripecount $DIR/$tdir
5973         createmany -o $DIR/$tdir/t- $nfiles
5974         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5975         for ((n = 0; n < $OSTCOUNT; n++)); do
5976                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5977                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5978                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5979                             '($1 == '$n') { objs += 1 } \
5980                             END { printf("%0.0f", objs) }')
5981                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5982         done
5983         unlinkmany $DIR/$tdir/t- $nfiles
5984         rm  -f $TMP/$tfile
5985
5986         local nlast
5987         local min=4
5988         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5989
5990         # For some combinations of stripecount and OSTCOUNT current code
5991         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5992         # than others. Rather than skipping this test entirely, check that
5993         # and keep testing to ensure imbalance does not get worse. LU-15282
5994         (( (OSTCOUNT == 6 && stripecount == 4) ||
5995            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5996            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5997         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5998                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5999                         { $LFS df && $LFS df -i &&
6000                         error "stripecount=$stripecount: " \
6001                               "OST $n has fewer objects vs. OST $nlast " \
6002                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6003                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6004                         { $LFS df && $LFS df -i &&
6005                         error "stripecount=$stripecount: " \
6006                               "OST $n has more objects vs. OST $nlast " \
6007                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6008
6009                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6010                         { $LFS df && $LFS df -i &&
6011                         error "stripecount=$stripecount: " \
6012                               "OST $n has fewer #0 objects vs. OST $nlast " \
6013                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6014                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6015                         { $LFS df && $LFS df -i &&
6016                         error "stripecount=$stripecount: " \
6017                               "OST $n has more #0 objects vs. OST $nlast " \
6018                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6019         done
6020 }
6021
6022 test_51d() {
6023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6024         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6025
6026         local stripecount
6027         local per_ost=100
6028         local nfiles=$((per_ost * OSTCOUNT))
6029         local mdts=$(comma_list $(mdts_nodes))
6030         local param="osp.*.create_count"
6031         local qos_old=$(do_facet mds1 \
6032                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6033
6034         do_nodes $mdts \
6035                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6036         stack_trap "do_nodes $mdts \
6037                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6038
6039         test_mkdir $DIR/$tdir
6040         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6041         (( dirstripes > 0 )) || dirstripes=1
6042
6043         # Ensure enough OST objects precreated for tests to pass without
6044         # running out of objects.  This is an LOV r-r OST algorithm test,
6045         # not an OST object precreation test.
6046         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6047         (( old >= nfiles )) ||
6048         {
6049                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6050
6051                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6052                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6053
6054                 # trigger precreation from all MDTs for all OSTs
6055                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6056                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6057                 done
6058         }
6059
6060         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6061                 sleep 8  # allow object precreation to catch up
6062                 test_51d_sub $stripecount $nfiles
6063         done
6064 }
6065 run_test 51d "check LOV round-robin OST object distribution"
6066
6067 test_51e() {
6068         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6069                 skip_env "ldiskfs only test"
6070         fi
6071
6072         test_mkdir -c1 $DIR/$tdir
6073         test_mkdir -c1 $DIR/$tdir/d0
6074
6075         touch $DIR/$tdir/d0/foo
6076         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6077                 error "file exceed 65000 nlink limit!"
6078         unlinkmany $DIR/$tdir/d0/f- 65001
6079         return 0
6080 }
6081 run_test 51e "check file nlink limit"
6082
6083 test_51f() {
6084         test_mkdir $DIR/$tdir
6085
6086         local max=100000
6087         local ulimit_old=$(ulimit -n)
6088         local spare=20 # number of spare fd's for scripts/libraries, etc.
6089         local mdt=$($LFS getstripe -m $DIR/$tdir)
6090         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6091
6092         echo "MDT$mdt numfree=$numfree, max=$max"
6093         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6094         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6095                 while ! ulimit -n $((numfree + spare)); do
6096                         numfree=$((numfree * 3 / 4))
6097                 done
6098                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6099         else
6100                 echo "left ulimit at $ulimit_old"
6101         fi
6102
6103         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6104                 unlinkmany $DIR/$tdir/f $numfree
6105                 error "create+open $numfree files in $DIR/$tdir failed"
6106         }
6107         ulimit -n $ulimit_old
6108
6109         # if createmany exits at 120s there will be fewer than $numfree files
6110         unlinkmany $DIR/$tdir/f $numfree || true
6111 }
6112 run_test 51f "check many open files limit"
6113
6114 test_52a() {
6115         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6116         test_mkdir $DIR/$tdir
6117         touch $DIR/$tdir/foo
6118         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6119         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6120         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6121         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6122         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6123                                         error "link worked"
6124         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6125         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6126         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6127                                                      error "lsattr"
6128         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6129         cp -r $DIR/$tdir $TMP/
6130         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6131 }
6132 run_test 52a "append-only flag test (should return errors)"
6133
6134 test_52b() {
6135         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6136         test_mkdir $DIR/$tdir
6137         touch $DIR/$tdir/foo
6138         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6139         cat test > $DIR/$tdir/foo && error "cat test worked"
6140         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6141         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6142         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6143                                         error "link worked"
6144         echo foo >> $DIR/$tdir/foo && error "echo worked"
6145         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6146         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6147         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6148         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6149                                                         error "lsattr"
6150         chattr -i $DIR/$tdir/foo || error "chattr failed"
6151
6152         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6153 }
6154 run_test 52b "immutable flag test (should return errors) ======="
6155
6156 test_53() {
6157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6158         remote_mds_nodsh && skip "remote MDS with nodsh"
6159         remote_ost_nodsh && skip "remote OST with nodsh"
6160
6161         local param
6162         local param_seq
6163         local ostname
6164         local mds_last
6165         local mds_last_seq
6166         local ost_last
6167         local ost_last_seq
6168         local ost_last_id
6169         local ostnum
6170         local node
6171         local found=false
6172         local support_last_seq=true
6173
6174         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6175                 support_last_seq=false
6176
6177         # only test MDT0000
6178         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6179         local value
6180         for value in $(do_facet $SINGLEMDS \
6181                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6182                 param=$(echo ${value[0]} | cut -d "=" -f1)
6183                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6184
6185                 if $support_last_seq; then
6186                         param_seq=$(echo $param |
6187                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6188                         mds_last_seq=$(do_facet $SINGLEMDS \
6189                                        $LCTL get_param -n $param_seq)
6190                 fi
6191                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6192
6193                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6194                 node=$(facet_active_host ost$((ostnum+1)))
6195                 param="obdfilter.$ostname.last_id"
6196                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6197                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6198                         ost_last_id=$ost_last
6199
6200                         if $support_last_seq; then
6201                                 ost_last_id=$(echo $ost_last |
6202                                               awk -F':' '{print $2}' |
6203                                               sed -e "s/^0x//g")
6204                                 ost_last_seq=$(echo $ost_last |
6205                                                awk -F':' '{print $1}')
6206                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6207                         fi
6208
6209                         if [[ $ost_last_id != $mds_last ]]; then
6210                                 error "$ost_last_id != $mds_last"
6211                         else
6212                                 found=true
6213                                 break
6214                         fi
6215                 done
6216         done
6217         $found || error "can not match last_seq/last_id for $mdtosc"
6218         return 0
6219 }
6220 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6221
6222 test_54a() {
6223         perl -MSocket -e ';' || skip "no Socket perl module installed"
6224
6225         $SOCKETSERVER $DIR/socket ||
6226                 error "$SOCKETSERVER $DIR/socket failed: $?"
6227         $SOCKETCLIENT $DIR/socket ||
6228                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6229         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6230 }
6231 run_test 54a "unix domain socket test =========================="
6232
6233 test_54b() {
6234         f="$DIR/f54b"
6235         mknod $f c 1 3
6236         chmod 0666 $f
6237         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6238 }
6239 run_test 54b "char device works in lustre ======================"
6240
6241 find_loop_dev() {
6242         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6243         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6244         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6245
6246         for i in $(seq 3 7); do
6247                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6248                 LOOPDEV=$LOOPBASE$i
6249                 LOOPNUM=$i
6250                 break
6251         done
6252 }
6253
6254 cleanup_54c() {
6255         local rc=0
6256         loopdev="$DIR/loop54c"
6257
6258         trap 0
6259         $UMOUNT $DIR/$tdir || rc=$?
6260         losetup -d $loopdev || true
6261         losetup -d $LOOPDEV || true
6262         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6263         return $rc
6264 }
6265
6266 test_54c() {
6267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6268
6269         loopdev="$DIR/loop54c"
6270
6271         find_loop_dev
6272         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6273         trap cleanup_54c EXIT
6274         mknod $loopdev b 7 $LOOPNUM
6275         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6276         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6277         losetup $loopdev $DIR/$tfile ||
6278                 error "can't set up $loopdev for $DIR/$tfile"
6279         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6280         test_mkdir $DIR/$tdir
6281         mount -t ext2 $loopdev $DIR/$tdir ||
6282                 error "error mounting $loopdev on $DIR/$tdir"
6283         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6284                 error "dd write"
6285         df $DIR/$tdir
6286         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6287                 error "dd read"
6288         cleanup_54c
6289 }
6290 run_test 54c "block device works in lustre ====================="
6291
6292 test_54d() {
6293         local pipe="$DIR/$tfile.pipe"
6294         local string="aaaaaa"
6295
6296         mknod $pipe p
6297         echo -n "$string" > $pipe &
6298         local result=$(cat $pipe)
6299         [[ "$result" == "$string" ]] || error "$result != $string"
6300 }
6301 run_test 54d "fifo device works in lustre ======================"
6302
6303 test_54e() {
6304         f="$DIR/f54e"
6305         string="aaaaaa"
6306         cp -aL /dev/console $f
6307         echo $string > $f || error "echo $string to $f failed"
6308 }
6309 run_test 54e "console/tty device works in lustre ======================"
6310
6311 test_56a() {
6312         local numfiles=3
6313         local numdirs=2
6314         local dir=$DIR/$tdir
6315
6316         rm -rf $dir
6317         test_mkdir -p $dir/dir
6318         for i in $(seq $numfiles); do
6319                 touch $dir/file$i
6320                 touch $dir/dir/file$i
6321         done
6322
6323         local numcomp=$($LFS getstripe --component-count $dir)
6324
6325         [[ $numcomp == 0 ]] && numcomp=1
6326
6327         # test lfs getstripe with --recursive
6328         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6329
6330         [[ $filenum -eq $((numfiles * 2)) ]] ||
6331                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6332         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6333         [[ $filenum -eq $numfiles ]] ||
6334                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6335         echo "$LFS getstripe showed obdidx or l_ost_idx"
6336
6337         # test lfs getstripe with file instead of dir
6338         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6339         [[ $filenum -eq 1 ]] ||
6340                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6341         echo "$LFS getstripe file1 passed"
6342
6343         #test lfs getstripe with --verbose
6344         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6345         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6346                 error "$LFS getstripe --verbose $dir: "\
6347                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6348         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6349                 error "$LFS getstripe $dir: showed lmm_magic"
6350
6351         #test lfs getstripe with -v prints lmm_fid
6352         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6353         local countfids=$((numdirs + numfiles * numcomp))
6354         [[ $filenum -eq $countfids ]] ||
6355                 error "$LFS getstripe -v $dir: "\
6356                       "got $filenum want $countfids lmm_fid"
6357         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6358                 error "$LFS getstripe $dir: showed lmm_fid by default"
6359         echo "$LFS getstripe --verbose passed"
6360
6361         #check for FID information
6362         local fid1=$($LFS getstripe --fid $dir/file1)
6363         local fid2=$($LFS getstripe --verbose $dir/file1 |
6364                      awk '/lmm_fid: / { print $2; exit; }')
6365         local fid3=$($LFS path2fid $dir/file1)
6366
6367         [ "$fid1" != "$fid2" ] &&
6368                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6369         [ "$fid1" != "$fid3" ] &&
6370                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6371         echo "$LFS getstripe --fid passed"
6372
6373         #test lfs getstripe with --obd
6374         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6375                 error "$LFS getstripe --obd wrong_uuid: should return error"
6376
6377         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6378
6379         local ostidx=1
6380         local obduuid=$(ostuuid_from_index $ostidx)
6381         local found=$($LFS getstripe -r --obd $obduuid $dir |
6382                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6383
6384         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6385         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6386                 ((filenum--))
6387         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6388                 ((filenum--))
6389
6390         [[ $found -eq $filenum ]] ||
6391                 error "$LFS getstripe --obd: found $found expect $filenum"
6392         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6393                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6394                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6395                 error "$LFS getstripe --obd: should not show file on other obd"
6396         echo "$LFS getstripe --obd passed"
6397 }
6398 run_test 56a "check $LFS getstripe"
6399
6400 test_56b() {
6401         local dir=$DIR/$tdir
6402         local numdirs=3
6403
6404         test_mkdir $dir
6405         for i in $(seq $numdirs); do
6406                 test_mkdir $dir/dir$i
6407         done
6408
6409         # test lfs getdirstripe default mode is non-recursion, which is
6410         # different from lfs getstripe
6411         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6412
6413         [[ $dircnt -eq 1 ]] ||
6414                 error "$LFS getdirstripe: found $dircnt, not 1"
6415         dircnt=$($LFS getdirstripe --recursive $dir |
6416                 grep -c lmv_stripe_count)
6417         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6418                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6419 }
6420 run_test 56b "check $LFS getdirstripe"
6421
6422 test_56c() {
6423         remote_ost_nodsh && skip "remote OST with nodsh"
6424
6425         local ost_idx=0
6426         local ost_name=$(ostname_from_index $ost_idx)
6427         local old_status=$(ost_dev_status $ost_idx)
6428         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6429
6430         [[ -z "$old_status" ]] ||
6431                 skip_env "OST $ost_name is in $old_status status"
6432
6433         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6434         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6435                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6436         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6437                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6438                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6439         fi
6440
6441         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6442                 error "$LFS df -v showing inactive devices"
6443         sleep_maxage
6444
6445         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6446
6447         [[ "$new_status" =~ "D" ]] ||
6448                 error "$ost_name status is '$new_status', missing 'D'"
6449         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6450                 [[ "$new_status" =~ "N" ]] ||
6451                         error "$ost_name status is '$new_status', missing 'N'"
6452         fi
6453         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6454                 [[ "$new_status" =~ "f" ]] ||
6455                         error "$ost_name status is '$new_status', missing 'f'"
6456         fi
6457
6458         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6459         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6460                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6461         [[ -z "$p" ]] && restore_lustre_params < $p || true
6462         sleep_maxage
6463
6464         new_status=$(ost_dev_status $ost_idx)
6465         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6466                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6467         # can't check 'f' as devices may actually be on flash
6468 }
6469 run_test 56c "check 'lfs df' showing device status"
6470
6471 test_56d() {
6472         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6473         local osts=$($LFS df -v $MOUNT | grep -c OST)
6474
6475         $LFS df $MOUNT
6476
6477         (( mdts == MDSCOUNT )) ||
6478                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6479         (( osts == OSTCOUNT )) ||
6480                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6481 }
6482 run_test 56d "'lfs df -v' prints only configured devices"
6483
6484 test_56e() {
6485         err_enoent=2 # No such file or directory
6486         err_eopnotsupp=95 # Operation not supported
6487
6488         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6489         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6490
6491         # Check for handling of path not exists
6492         output=$($LFS df $enoent_mnt 2>&1)
6493         ret=$?
6494
6495         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6496         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6497                 error "expect failure $err_enoent, not $ret"
6498
6499         # Check for handling of non-Lustre FS
6500         output=$($LFS df $notsup_mnt)
6501         ret=$?
6502
6503         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6504         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6505                 error "expect success $err_eopnotsupp, not $ret"
6506
6507         # Check for multiple LustreFS argument
6508         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6509         ret=$?
6510
6511         [[ $output -eq 3 && $ret -eq 0 ]] ||
6512                 error "expect success 3, not $output, rc = $ret"
6513
6514         # Check for correct non-Lustre FS handling among multiple
6515         # LustreFS argument
6516         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6517                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6518         ret=$?
6519
6520         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6521                 error "expect success 2, not $output, rc = $ret"
6522 }
6523 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6524
6525 NUMFILES=3
6526 NUMDIRS=3
6527 setup_56() {
6528         local local_tdir="$1"
6529         local local_numfiles="$2"
6530         local local_numdirs="$3"
6531         local dir_params="$4"
6532         local dir_stripe_params="$5"
6533
6534         if [ ! -d "$local_tdir" ] ; then
6535                 test_mkdir -p $dir_stripe_params $local_tdir
6536                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6537                 for i in $(seq $local_numfiles) ; do
6538                         touch $local_tdir/file$i
6539                 done
6540                 for i in $(seq $local_numdirs) ; do
6541                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6542                         for j in $(seq $local_numfiles) ; do
6543                                 touch $local_tdir/dir$i/file$j
6544                         done
6545                 done
6546         fi
6547 }
6548
6549 setup_56_special() {
6550         local local_tdir=$1
6551         local local_numfiles=$2
6552         local local_numdirs=$3
6553
6554         setup_56 $local_tdir $local_numfiles $local_numdirs
6555
6556         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6557                 for i in $(seq $local_numfiles) ; do
6558                         mknod $local_tdir/loop${i}b b 7 $i
6559                         mknod $local_tdir/null${i}c c 1 3
6560                         ln -s $local_tdir/file1 $local_tdir/link${i}
6561                 done
6562                 for i in $(seq $local_numdirs) ; do
6563                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6564                         mknod $local_tdir/dir$i/null${i}c c 1 3
6565                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6566                 done
6567         fi
6568 }
6569
6570 test_56g() {
6571         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6572         local expected=$(($NUMDIRS + 2))
6573
6574         setup_56 $dir $NUMFILES $NUMDIRS
6575
6576         # test lfs find with -name
6577         for i in $(seq $NUMFILES) ; do
6578                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6579
6580                 [ $nums -eq $expected ] ||
6581                         error "lfs find -name '*$i' $dir wrong: "\
6582                               "found $nums, expected $expected"
6583         done
6584 }
6585 run_test 56g "check lfs find -name"
6586
6587 test_56h() {
6588         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6589         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6590
6591         setup_56 $dir $NUMFILES $NUMDIRS
6592
6593         # test lfs find with ! -name
6594         for i in $(seq $NUMFILES) ; do
6595                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6596
6597                 [ $nums -eq $expected ] ||
6598                         error "lfs find ! -name '*$i' $dir wrong: "\
6599                               "found $nums, expected $expected"
6600         done
6601 }
6602 run_test 56h "check lfs find ! -name"
6603
6604 test_56i() {
6605         local dir=$DIR/$tdir
6606
6607         test_mkdir $dir
6608
6609         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6610         local out=$($cmd)
6611
6612         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6613 }
6614 run_test 56i "check 'lfs find -ost UUID' skips directories"
6615
6616 test_56j() {
6617         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6618
6619         setup_56_special $dir $NUMFILES $NUMDIRS
6620
6621         local expected=$((NUMDIRS + 1))
6622         local cmd="$LFS find -type d $dir"
6623         local nums=$($cmd | wc -l)
6624
6625         [ $nums -eq $expected ] ||
6626                 error "'$cmd' wrong: found $nums, expected $expected"
6627 }
6628 run_test 56j "check lfs find -type d"
6629
6630 test_56k() {
6631         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6632
6633         setup_56_special $dir $NUMFILES $NUMDIRS
6634
6635         local expected=$(((NUMDIRS + 1) * NUMFILES))
6636         local cmd="$LFS find -type f $dir"
6637         local nums=$($cmd | wc -l)
6638
6639         [ $nums -eq $expected ] ||
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641 }
6642 run_test 56k "check lfs find -type f"
6643
6644 test_56l() {
6645         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6646
6647         setup_56_special $dir $NUMFILES $NUMDIRS
6648
6649         local expected=$((NUMDIRS + NUMFILES))
6650         local cmd="$LFS find -type b $dir"
6651         local nums=$($cmd | wc -l)
6652
6653         [ $nums -eq $expected ] ||
6654                 error "'$cmd' wrong: found $nums, expected $expected"
6655 }
6656 run_test 56l "check lfs find -type b"
6657
6658 test_56m() {
6659         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6660
6661         setup_56_special $dir $NUMFILES $NUMDIRS
6662
6663         local expected=$((NUMDIRS + NUMFILES))
6664         local cmd="$LFS find -type c $dir"
6665         local nums=$($cmd | wc -l)
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668 }
6669 run_test 56m "check lfs find -type c"
6670
6671 test_56n() {
6672         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6673         setup_56_special $dir $NUMFILES $NUMDIRS
6674
6675         local expected=$((NUMDIRS + NUMFILES))
6676         local cmd="$LFS find -type l $dir"
6677         local nums=$($cmd | wc -l)
6678
6679         [ $nums -eq $expected ] ||
6680                 error "'$cmd' wrong: found $nums, expected $expected"
6681 }
6682 run_test 56n "check lfs find -type l"
6683
6684 test_56o() {
6685         local dir=$DIR/$tdir
6686
6687         setup_56 $dir $NUMFILES $NUMDIRS
6688         utime $dir/file1 > /dev/null || error "utime (1)"
6689         utime $dir/file2 > /dev/null || error "utime (2)"
6690         utime $dir/dir1 > /dev/null || error "utime (3)"
6691         utime $dir/dir2 > /dev/null || error "utime (4)"
6692         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6693         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6694
6695         local expected=4
6696         local nums=$($LFS find -mtime +0 $dir | wc -l)
6697
6698         [ $nums -eq $expected ] ||
6699                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6700
6701         expected=12
6702         cmd="$LFS find -mtime 0 $dir"
6703         nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706 }
6707 run_test 56o "check lfs find -mtime for old files"
6708
6709 test_56ob() {
6710         local dir=$DIR/$tdir
6711         local expected=1
6712         local count=0
6713
6714         # just to make sure there is something that won't be found
6715         test_mkdir $dir
6716         touch $dir/$tfile.now
6717
6718         for age in year week day hour min; do
6719                 count=$((count + 1))
6720
6721                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6722                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6723                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6724
6725                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6726                 local nums=$($cmd | wc -l)
6727                 [ $nums -eq $expected ] ||
6728                         error "'$cmd' wrong: found $nums, expected $expected"
6729
6730                 cmd="$LFS find $dir -atime $count${age:0:1}"
6731                 nums=$($cmd | wc -l)
6732                 [ $nums -eq $expected ] ||
6733                         error "'$cmd' wrong: found $nums, expected $expected"
6734         done
6735
6736         sleep 2
6737         cmd="$LFS find $dir -ctime +1s -type f"
6738         nums=$($cmd | wc -l)
6739         (( $nums == $count * 2 + 1)) ||
6740                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6741 }
6742 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6743
6744 test_newerXY_base() {
6745         local x=$1
6746         local y=$2
6747         local dir=$DIR/$tdir
6748         local ref
6749         local negref
6750
6751         if [ $y == "t" ]; then
6752                 if [ $x == "b" ]; then
6753                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6754                 else
6755                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6756                 fi
6757         else
6758                 ref=$DIR/$tfile.newer.$x$y
6759                 touch $ref || error "touch $ref failed"
6760         fi
6761
6762         echo "before = $ref"
6763         sleep 2
6764         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6765         sleep 2
6766         if [ $y == "t" ]; then
6767                 if [ $x == "b" ]; then
6768                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6769                 else
6770                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6771                 fi
6772         else
6773                 negref=$DIR/$tfile.negnewer.$x$y
6774                 touch $negref || error "touch $negref failed"
6775         fi
6776
6777         echo "after = $negref"
6778         local cmd="$LFS find $dir -newer$x$y $ref"
6779         local nums=$(eval $cmd | wc -l)
6780         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6781
6782         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6783                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6784
6785         cmd="$LFS find $dir ! -newer$x$y $negref"
6786         nums=$(eval $cmd | wc -l)
6787         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6788                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6789
6790         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6791         nums=$(eval $cmd | wc -l)
6792         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6793                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6794
6795         rm -rf $DIR/*
6796 }
6797
6798 test_56oc() {
6799         test_newerXY_base "a" "a"
6800         test_newerXY_base "a" "m"
6801         test_newerXY_base "a" "c"
6802         test_newerXY_base "m" "a"
6803         test_newerXY_base "m" "m"
6804         test_newerXY_base "m" "c"
6805         test_newerXY_base "c" "a"
6806         test_newerXY_base "c" "m"
6807         test_newerXY_base "c" "c"
6808
6809         test_newerXY_base "a" "t"
6810         test_newerXY_base "m" "t"
6811         test_newerXY_base "c" "t"
6812
6813         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6814            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6815                 ! btime_supported && echo "btime unsupported" && return 0
6816
6817         test_newerXY_base "b" "b"
6818         test_newerXY_base "b" "t"
6819 }
6820 run_test 56oc "check lfs find -newerXY work"
6821
6822 btime_supported() {
6823         local dir=$DIR/$tdir
6824         local rc
6825
6826         mkdir -p $dir
6827         touch $dir/$tfile
6828         $LFS find $dir -btime -1d -type f
6829         rc=$?
6830         rm -rf $dir
6831         return $rc
6832 }
6833
6834 test_56od() {
6835         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6836                 ! btime_supported && skip "btime unsupported on MDS"
6837
6838         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6839                 ! btime_supported && skip "btime unsupported on clients"
6840
6841         local dir=$DIR/$tdir
6842         local ref=$DIR/$tfile.ref
6843         local negref=$DIR/$tfile.negref
6844
6845         mkdir $dir || error "mkdir $dir failed"
6846         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6847         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6848         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6849         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6850         touch $ref || error "touch $ref failed"
6851         # sleep 3 seconds at least
6852         sleep 3
6853
6854         local before=$(do_facet mds1 date +%s)
6855         local skew=$(($(date +%s) - before + 1))
6856
6857         if (( skew < 0 && skew > -5 )); then
6858                 sleep $((0 - skew + 1))
6859                 skew=0
6860         fi
6861
6862         # Set the dir stripe params to limit files all on MDT0,
6863         # otherwise we need to calc the max clock skew between
6864         # the client and MDTs.
6865         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6866         sleep 2
6867         touch $negref || error "touch $negref failed"
6868
6869         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6870         local nums=$($cmd | wc -l)
6871         local expected=$(((NUMFILES + 1) * NUMDIRS))
6872
6873         [ $nums -eq $expected ] ||
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875
6876         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6877         nums=$($cmd | wc -l)
6878         expected=$((NUMFILES + 1))
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881
6882         [ $skew -lt 0 ] && return
6883
6884         local after=$(do_facet mds1 date +%s)
6885         local age=$((after - before + 1 + skew))
6886
6887         cmd="$LFS find $dir -btime -${age}s -type f"
6888         nums=$($cmd | wc -l)
6889         expected=$(((NUMFILES + 1) * NUMDIRS))
6890
6891         echo "Clock skew between client and server: $skew, age:$age"
6892         [ $nums -eq $expected ] ||
6893                 error "'$cmd' wrong: found $nums, expected $expected"
6894
6895         expected=$(($NUMDIRS + 1))
6896         cmd="$LFS find $dir -btime -${age}s -type d"
6897         nums=$($cmd | wc -l)
6898         [ $nums -eq $expected ] ||
6899                 error "'$cmd' wrong: found $nums, expected $expected"
6900         rm -f $ref $negref || error "Failed to remove $ref $negref"
6901 }
6902 run_test 56od "check lfs find -btime with units"
6903
6904 test_56p() {
6905         [ $RUNAS_ID -eq $UID ] &&
6906                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6907
6908         local dir=$DIR/$tdir
6909
6910         setup_56 $dir $NUMFILES $NUMDIRS
6911         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6912
6913         local expected=$NUMFILES
6914         local cmd="$LFS find -uid $RUNAS_ID $dir"
6915         local nums=$($cmd | wc -l)
6916
6917         [ $nums -eq $expected ] ||
6918                 error "'$cmd' wrong: found $nums, expected $expected"
6919
6920         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6921         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6922         nums=$($cmd | wc -l)
6923         [ $nums -eq $expected ] ||
6924                 error "'$cmd' wrong: found $nums, expected $expected"
6925 }
6926 run_test 56p "check lfs find -uid and ! -uid"
6927
6928 test_56q() {
6929         [ $RUNAS_ID -eq $UID ] &&
6930                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6931
6932         local dir=$DIR/$tdir
6933
6934         setup_56 $dir $NUMFILES $NUMDIRS
6935         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6936
6937         local expected=$NUMFILES
6938         local cmd="$LFS find -gid $RUNAS_GID $dir"
6939         local nums=$($cmd | wc -l)
6940
6941         [ $nums -eq $expected ] ||
6942                 error "'$cmd' wrong: found $nums, expected $expected"
6943
6944         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6945         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6946         nums=$($cmd | wc -l)
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949 }
6950 run_test 56q "check lfs find -gid and ! -gid"
6951
6952 test_56r() {
6953         local dir=$DIR/$tdir
6954
6955         setup_56 $dir $NUMFILES $NUMDIRS
6956
6957         local expected=12
6958         local cmd="$LFS find -size 0 -type f -lazy $dir"
6959         local nums=$($cmd | wc -l)
6960
6961         [ $nums -eq $expected ] ||
6962                 error "'$cmd' wrong: found $nums, expected $expected"
6963         cmd="$LFS find -size 0 -type f $dir"
6964         nums=$($cmd | wc -l)
6965         [ $nums -eq $expected ] ||
6966                 error "'$cmd' wrong: found $nums, expected $expected"
6967
6968         expected=0
6969         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6970         nums=$($cmd | wc -l)
6971         [ $nums -eq $expected ] ||
6972                 error "'$cmd' wrong: found $nums, expected $expected"
6973         cmd="$LFS find ! -size 0 -type f $dir"
6974         nums=$($cmd | wc -l)
6975         [ $nums -eq $expected ] ||
6976                 error "'$cmd' wrong: found $nums, expected $expected"
6977
6978         echo "test" > $dir/$tfile
6979         echo "test2" > $dir/$tfile.2 && sync
6980         expected=1
6981         cmd="$LFS find -size 5 -type f -lazy $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985         cmd="$LFS find -size 5 -type f $dir"
6986         nums=$($cmd | wc -l)
6987         [ $nums -eq $expected ] ||
6988                 error "'$cmd' wrong: found $nums, expected $expected"
6989
6990         expected=1
6991         cmd="$LFS find -size +5 -type f -lazy $dir"
6992         nums=$($cmd | wc -l)
6993         [ $nums -eq $expected ] ||
6994                 error "'$cmd' wrong: found $nums, expected $expected"
6995         cmd="$LFS find -size +5 -type f $dir"
6996         nums=$($cmd | wc -l)
6997         [ $nums -eq $expected ] ||
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999
7000         expected=2
7001         cmd="$LFS find -size +0 -type f -lazy $dir"
7002         nums=$($cmd | wc -l)
7003         [ $nums -eq $expected ] ||
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005         cmd="$LFS find -size +0 -type f $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         expected=2
7011         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015         cmd="$LFS find ! -size -5 -type f $dir"
7016         nums=$($cmd | wc -l)
7017         [ $nums -eq $expected ] ||
7018                 error "'$cmd' wrong: found $nums, expected $expected"
7019
7020         expected=12
7021         cmd="$LFS find -size -5 -type f -lazy $dir"
7022         nums=$($cmd | wc -l)
7023         [ $nums -eq $expected ] ||
7024                 error "'$cmd' wrong: found $nums, expected $expected"
7025         cmd="$LFS find -size -5 -type f $dir"
7026         nums=$($cmd | wc -l)
7027         [ $nums -eq $expected ] ||
7028                 error "'$cmd' wrong: found $nums, expected $expected"
7029 }
7030 run_test 56r "check lfs find -size works"
7031
7032 test_56ra_sub() {
7033         local expected=$1
7034         local glimpses=$2
7035         local cmd="$3"
7036
7037         cancel_lru_locks $OSC
7038
7039         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7040         local nums=$($cmd | wc -l)
7041
7042         [ $nums -eq $expected ] ||
7043                 error "'$cmd' wrong: found $nums, expected $expected"
7044
7045         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7046
7047         if (( rpcs_before + glimpses != rpcs_after )); then
7048                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7049                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7050
7051                 if [[ $glimpses == 0 ]]; then
7052                         error "'$cmd' should not send glimpse RPCs to OST"
7053                 else
7054                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7055                 fi
7056         fi
7057 }
7058
7059 test_56ra() {
7060         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7061                 skip "MDS < 2.12.58 doesn't return LSOM data"
7062         local dir=$DIR/$tdir
7063         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7064
7065         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7066
7067         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7068         $LCTL set_param -n llite.*.statahead_agl=0
7069         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7070
7071         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7072         # open and close all files to ensure LSOM is updated
7073         cancel_lru_locks $OSC
7074         find $dir -type f | xargs cat > /dev/null
7075
7076         #   expect_found  glimpse_rpcs  command_to_run
7077         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7078         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7079         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7080         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7081
7082         echo "test" > $dir/$tfile
7083         echo "test2" > $dir/$tfile.2 && sync
7084         cancel_lru_locks $OSC
7085         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7086
7087         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7088         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7089         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7090         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7091
7092         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7093         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7094         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7095         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7096         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7097         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7098 }
7099 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7100
7101 test_56rb() {
7102         local dir=$DIR/$tdir
7103         local tmp=$TMP/$tfile.log
7104         local mdt_idx;
7105
7106         test_mkdir -p $dir || error "failed to mkdir $dir"
7107         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7108                 error "failed to setstripe $dir/$tfile"
7109         mdt_idx=$($LFS getdirstripe -i $dir)
7110         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7111
7112         stack_trap "rm -f $tmp" EXIT
7113         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7114         ! grep -q obd_uuid $tmp ||
7115                 error "failed to find --size +100K --ost 0 $dir"
7116         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7117         ! grep -q obd_uuid $tmp ||
7118                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7119 }
7120 run_test 56rb "check lfs find --size --ost/--mdt works"
7121
7122 test_56rc() {
7123         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7124         local dir=$DIR/$tdir
7125         local found
7126
7127         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7128         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7129         (( $MDSCOUNT > 2 )) &&
7130                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7131         mkdir $dir/$tdir-{1..10}
7132         touch $dir/$tfile-{1..10}
7133
7134         found=$($LFS find $dir --mdt-count 2 | wc -l)
7135         expect=11
7136         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7137
7138         found=$($LFS find $dir -T +1 | wc -l)
7139         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7140         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7141
7142         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7143         expect=11
7144         (( $found == $expect )) || error "found $found all_char, expect $expect"
7145
7146         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7147         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7148         (( $found == $expect )) || error "found $found all_char, expect $expect"
7149 }
7150 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7151
7152 test_56s() { # LU-611 #LU-9369
7153         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7154
7155         local dir=$DIR/$tdir
7156         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7157
7158         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7159         for i in $(seq $NUMDIRS); do
7160                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7161         done
7162
7163         local expected=$NUMDIRS
7164         local cmd="$LFS find -c $OSTCOUNT $dir"
7165         local nums=$($cmd | wc -l)
7166
7167         [ $nums -eq $expected ] || {
7168                 $LFS getstripe -R $dir
7169                 error "'$cmd' wrong: found $nums, expected $expected"
7170         }
7171
7172         expected=$((NUMDIRS + onestripe))
7173         cmd="$LFS find -stripe-count +0 -type f $dir"
7174         nums=$($cmd | wc -l)
7175         [ $nums -eq $expected ] || {
7176                 $LFS getstripe -R $dir
7177                 error "'$cmd' wrong: found $nums, expected $expected"
7178         }
7179
7180         expected=$onestripe
7181         cmd="$LFS find -stripe-count 1 -type f $dir"
7182         nums=$($cmd | wc -l)
7183         [ $nums -eq $expected ] || {
7184                 $LFS getstripe -R $dir
7185                 error "'$cmd' wrong: found $nums, expected $expected"
7186         }
7187
7188         cmd="$LFS find -stripe-count -2 -type f $dir"
7189         nums=$($cmd | wc -l)
7190         [ $nums -eq $expected ] || {
7191                 $LFS getstripe -R $dir
7192                 error "'$cmd' wrong: found $nums, expected $expected"
7193         }
7194
7195         expected=0
7196         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7197         nums=$($cmd | wc -l)
7198         [ $nums -eq $expected ] || {
7199                 $LFS getstripe -R $dir
7200                 error "'$cmd' wrong: found $nums, expected $expected"
7201         }
7202 }
7203 run_test 56s "check lfs find -stripe-count works"
7204
7205 test_56t() { # LU-611 #LU-9369
7206         local dir=$DIR/$tdir
7207
7208         setup_56 $dir 0 $NUMDIRS
7209         for i in $(seq $NUMDIRS); do
7210                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7211         done
7212
7213         local expected=$NUMDIRS
7214         local cmd="$LFS find -S 8M $dir"
7215         local nums=$($cmd | wc -l)
7216
7217         [ $nums -eq $expected ] || {
7218                 $LFS getstripe -R $dir
7219                 error "'$cmd' wrong: found $nums, expected $expected"
7220         }
7221         rm -rf $dir
7222
7223         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7224
7225         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7226
7227         expected=$(((NUMDIRS + 1) * NUMFILES))
7228         cmd="$LFS find -stripe-size 512k -type f $dir"
7229         nums=$($cmd | wc -l)
7230         [ $nums -eq $expected ] ||
7231                 error "'$cmd' wrong: found $nums, expected $expected"
7232
7233         cmd="$LFS find -stripe-size +320k -type f $dir"
7234         nums=$($cmd | wc -l)
7235         [ $nums -eq $expected ] ||
7236                 error "'$cmd' wrong: found $nums, expected $expected"
7237
7238         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7239         cmd="$LFS find -stripe-size +200k -type f $dir"
7240         nums=$($cmd | wc -l)
7241         [ $nums -eq $expected ] ||
7242                 error "'$cmd' wrong: found $nums, expected $expected"
7243
7244         cmd="$LFS find -stripe-size -640k -type f $dir"
7245         nums=$($cmd | wc -l)
7246         [ $nums -eq $expected ] ||
7247                 error "'$cmd' wrong: found $nums, expected $expected"
7248
7249         expected=4
7250         cmd="$LFS find -stripe-size 256k -type f $dir"
7251         nums=$($cmd | wc -l)
7252         [ $nums -eq $expected ] ||
7253                 error "'$cmd' wrong: found $nums, expected $expected"
7254
7255         cmd="$LFS find -stripe-size -320k -type f $dir"
7256         nums=$($cmd | wc -l)
7257         [ $nums -eq $expected ] ||
7258                 error "'$cmd' wrong: found $nums, expected $expected"
7259
7260         expected=0
7261         cmd="$LFS find -stripe-size 1024k -type f $dir"
7262         nums=$($cmd | wc -l)
7263         [ $nums -eq $expected ] ||
7264                 error "'$cmd' wrong: found $nums, expected $expected"
7265 }
7266 run_test 56t "check lfs find -stripe-size works"
7267
7268 test_56u() { # LU-611
7269         local dir=$DIR/$tdir
7270
7271         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7272
7273         if [[ $OSTCOUNT -gt 1 ]]; then
7274                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7275                 onestripe=4
7276         else
7277                 onestripe=0
7278         fi
7279
7280         local expected=$(((NUMDIRS + 1) * NUMFILES))
7281         local cmd="$LFS find -stripe-index 0 -type f $dir"
7282         local nums=$($cmd | wc -l)
7283
7284         [ $nums -eq $expected ] ||
7285                 error "'$cmd' wrong: found $nums, expected $expected"
7286
7287         expected=$onestripe
7288         cmd="$LFS find -stripe-index 1 -type f $dir"
7289         nums=$($cmd | wc -l)
7290         [ $nums -eq $expected ] ||
7291                 error "'$cmd' wrong: found $nums, expected $expected"
7292
7293         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7294         nums=$($cmd | wc -l)
7295         [ $nums -eq $expected ] ||
7296                 error "'$cmd' wrong: found $nums, expected $expected"
7297
7298         expected=0
7299         # This should produce an error and not return any files
7300         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7301         nums=$($cmd 2>/dev/null | wc -l)
7302         [ $nums -eq $expected ] ||
7303                 error "'$cmd' wrong: found $nums, expected $expected"
7304
7305         if [[ $OSTCOUNT -gt 1 ]]; then
7306                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7307                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7308                 nums=$($cmd | wc -l)
7309                 [ $nums -eq $expected ] ||
7310                         error "'$cmd' wrong: found $nums, expected $expected"
7311         fi
7312 }
7313 run_test 56u "check lfs find -stripe-index works"
7314
7315 test_56v() {
7316         local mdt_idx=0
7317         local dir=$DIR/$tdir
7318
7319         setup_56 $dir $NUMFILES $NUMDIRS
7320
7321         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7322         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7323
7324         for file in $($LFS find -m $UUID $dir); do
7325                 file_midx=$($LFS getstripe -m $file)
7326                 [ $file_midx -eq $mdt_idx ] ||
7327                         error "lfs find -m $UUID != getstripe -m $file_midx"
7328         done
7329 }
7330 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7331
7332 test_56wa() {
7333         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7335
7336         local dir=$DIR/$tdir
7337
7338         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7339
7340         local stripe_size=$($LFS getstripe -S -d $dir) ||
7341                 error "$LFS getstripe -S -d $dir failed"
7342         stripe_size=${stripe_size%% *}
7343
7344         local file_size=$((stripe_size * OSTCOUNT))
7345         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7346         local required_space=$((file_num * file_size))
7347         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7348                            head -n1)
7349         (( free_space >= required_space / 1024 )) ||
7350                 skip_env "need $required_space, have $free_space kbytes"
7351
7352         local dd_bs=65536
7353         local dd_count=$((file_size / dd_bs))
7354
7355         # write data into the files
7356         local i
7357         local j
7358         local file
7359
7360         for ((i = 1; i <= NUMFILES; i++ )); do
7361                 file=$dir/file$i
7362                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7363                         error "write data into $file failed"
7364         done
7365         for ((i = 1; i <= NUMDIRS; i++ )); do
7366                 for ((j = 1; j <= NUMFILES; j++ )); do
7367                         file=$dir/dir$i/file$j
7368                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7369                                 error "write data into $file failed"
7370                 done
7371         done
7372
7373         # $LFS_MIGRATE will fail if hard link migration is unsupported
7374         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7375                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7376                         error "creating links to $dir/dir1/file1 failed"
7377         fi
7378
7379         local expected=-1
7380
7381         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7382
7383         # lfs_migrate file
7384         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7385
7386         echo "$cmd"
7387         eval $cmd || error "$cmd failed"
7388
7389         check_stripe_count $dir/file1 $expected
7390
7391         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7392                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7393                 # OST 1 if it is on OST 0. This file is small enough to
7394                 # be on only one stripe.
7395                 file=$dir/migr_1_ost
7396                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7397                         error "write data into $file failed"
7398                 local obdidx=$($LFS getstripe -i $file)
7399                 local oldmd5=$(md5sum $file)
7400                 local newobdidx=0
7401
7402                 (( obdidx != 0 )) || newobdidx=1
7403                 cmd="$LFS migrate -i $newobdidx $file"
7404                 echo $cmd
7405                 eval $cmd || error "$cmd failed"
7406
7407                 local realobdix=$($LFS getstripe -i $file)
7408                 local newmd5=$(md5sum $file)
7409
7410                 (( $newobdidx == $realobdix )) ||
7411                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7412                 [[ "$oldmd5" == "$newmd5" ]] ||
7413                         error "md5sum differ: $oldmd5, $newmd5"
7414         fi
7415
7416         # lfs_migrate dir
7417         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7418         echo "$cmd"
7419         eval $cmd || error "$cmd failed"
7420
7421         for (( j = 1; j <= NUMFILES; j++ )); do
7422                 check_stripe_count $dir/dir1/file$j $expected
7423         done
7424
7425         # lfs_migrate works with lfs find
7426         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7427              $LFS_MIGRATE -y -c $expected"
7428         echo "$cmd"
7429         eval $cmd || error "$cmd failed"
7430
7431         for (( i = 2; i <= NUMFILES; i++ )); do
7432                 check_stripe_count $dir/file$i $expected
7433         done
7434         for (( i = 2; i <= NUMDIRS; i++ )); do
7435                 for (( j = 1; j <= NUMFILES; j++ )); do
7436                         check_stripe_count $dir/dir$i/file$j $expected
7437                 done
7438         done
7439 }
7440 run_test 56wa "check lfs_migrate -c stripe_count works"
7441
7442 test_56wb() {
7443         local file1=$DIR/$tdir/file1
7444         local create_pool=false
7445         local initial_pool=$($LFS getstripe -p $DIR)
7446         local pool_list=()
7447         local pool=""
7448
7449         echo -n "Creating test dir..."
7450         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7451         echo "done."
7452
7453         echo -n "Creating test file..."
7454         touch $file1 || error "cannot create file"
7455         echo "done."
7456
7457         echo -n "Detecting existing pools..."
7458         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7459
7460         if [ ${#pool_list[@]} -gt 0 ]; then
7461                 echo "${pool_list[@]}"
7462                 for thispool in "${pool_list[@]}"; do
7463                         if [[ -z "$initial_pool" ||
7464                               "$initial_pool" != "$thispool" ]]; then
7465                                 pool="$thispool"
7466                                 echo "Using existing pool '$pool'"
7467                                 break
7468                         fi
7469                 done
7470         else
7471                 echo "none detected."
7472         fi
7473         if [ -z "$pool" ]; then
7474                 pool=${POOL:-testpool}
7475                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7476                 echo -n "Creating pool '$pool'..."
7477                 create_pool=true
7478                 pool_add $pool &> /dev/null ||
7479                         error "pool_add failed"
7480                 echo "done."
7481
7482                 echo -n "Adding target to pool..."
7483                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7484                         error "pool_add_targets failed"
7485                 echo "done."
7486         fi
7487
7488         echo -n "Setting pool using -p option..."
7489         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7490                 error "migrate failed rc = $?"
7491         echo "done."
7492
7493         echo -n "Verifying test file is in pool after migrating..."
7494         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7495                 error "file was not migrated to pool $pool"
7496         echo "done."
7497
7498         echo -n "Removing test file from pool '$pool'..."
7499         # "lfs migrate $file" won't remove the file from the pool
7500         # until some striping information is changed.
7501         $LFS migrate -c 1 $file1 &> /dev/null ||
7502                 error "cannot remove from pool"
7503         [ "$($LFS getstripe -p $file1)" ] &&
7504                 error "pool still set"
7505         echo "done."
7506
7507         echo -n "Setting pool using --pool option..."
7508         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7509                 error "migrate failed rc = $?"
7510         echo "done."
7511
7512         # Clean up
7513         rm -f $file1
7514         if $create_pool; then
7515                 destroy_test_pools 2> /dev/null ||
7516                         error "destroy test pools failed"
7517         fi
7518 }
7519 run_test 56wb "check lfs_migrate pool support"
7520
7521 test_56wc() {
7522         local file1="$DIR/$tdir/$tfile"
7523         local md5
7524         local parent_ssize
7525         local parent_scount
7526         local cur_ssize
7527         local cur_scount
7528         local orig_ssize
7529         local new_scount
7530         local cur_comp
7531
7532         echo -n "Creating test dir..."
7533         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7534         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7535                 error "cannot set stripe by '-S 1M -c 1'"
7536         echo "done"
7537
7538         echo -n "Setting initial stripe for test file..."
7539         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7540                 error "cannot set stripe"
7541         cur_ssize=$($LFS getstripe -S "$file1")
7542         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7543         echo "done."
7544
7545         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7546         stack_trap "rm -f $file1"
7547         md5="$(md5sum $file1)"
7548
7549         # File currently set to -S 512K -c 1
7550
7551         # Ensure -c and -S options are rejected when -R is set
7552         echo -n "Verifying incompatible options are detected..."
7553         $LFS_MIGRATE -R -c 1 "$file1" &&
7554                 error "incompatible -R and -c options not detected"
7555         $LFS_MIGRATE -R -S 1M "$file1" &&
7556                 error "incompatible -R and -S options not detected"
7557         $LFS_MIGRATE -R -p pool "$file1" &&
7558                 error "incompatible -R and -p options not detected"
7559         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7560                 error "incompatible -R and -E options not detected"
7561         $LFS_MIGRATE -R -A "$file1" &&
7562                 error "incompatible -R and -A options not detected"
7563         $LFS_MIGRATE -A -c 1 "$file1" &&
7564                 error "incompatible -A and -c options not detected"
7565         $LFS_MIGRATE -A -S 1M "$file1" &&
7566                 error "incompatible -A and -S options not detected"
7567         $LFS_MIGRATE -A -p pool "$file1" &&
7568                 error "incompatible -A and -p options not detected"
7569         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7570                 error "incompatible -A and -E options not detected"
7571         echo "done."
7572
7573         # Ensure unrecognized options are passed through to 'lfs migrate'
7574         echo -n "Verifying -S option is passed through to lfs migrate..."
7575         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7576         cur_ssize=$($LFS getstripe -S "$file1")
7577         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7578         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7579         echo "done."
7580
7581         # File currently set to -S 1M -c 1
7582
7583         # Ensure long options are supported
7584         echo -n "Verifying long options supported..."
7585         $LFS_MIGRATE --non-block "$file1" ||
7586                 error "long option without argument not supported"
7587         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7588                 error "long option with argument not supported"
7589         cur_ssize=$($LFS getstripe -S "$file1")
7590         (( cur_ssize == 524288 )) ||
7591                 error "migrate --stripe-size $cur_ssize != 524288"
7592         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7593         echo "done."
7594
7595         # File currently set to -S 512K -c 1
7596
7597         if (( OSTCOUNT > 1 )); then
7598                 echo -n "Verifying explicit stripe count can be set..."
7599                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7600                 cur_scount=$($LFS getstripe -c "$file1")
7601                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7602                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7603                         error "file data has changed (3)"
7604                 echo "done."
7605         fi
7606
7607         # File currently set to -S 512K -c 1 or -S 512K -c 2
7608
7609         # Ensure parent striping is used if -R is set, and no stripe
7610         # count or size is specified
7611         echo -n "Setting stripe for parent directory..."
7612         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7613                 error "cannot set stripe '-S 2M -c 1'"
7614         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7615         echo "done."
7616
7617         echo -n "Verifying restripe option uses parent stripe settings..."
7618         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7619         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7620         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7621         cur_ssize=$($LFS getstripe -S "$file1")
7622         (( cur_ssize == parent_ssize )) ||
7623                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7624         cur_scount=$($LFS getstripe -c "$file1")
7625         (( cur_scount == parent_scount )) ||
7626                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7627         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7628         echo "done."
7629
7630         # File currently set to -S 1M -c 1
7631
7632         # Ensure striping is preserved if -R is not set, and no stripe
7633         # count or size is specified
7634         echo -n "Verifying striping size preserved when not specified..."
7635         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7636         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7637                 error "cannot set stripe on parent directory"
7638         $LFS_MIGRATE "$file1" || error "migrate failed"
7639         cur_ssize=$($LFS getstripe -S "$file1")
7640         (( cur_ssize == orig_ssize )) ||
7641                 error "migrate by default $cur_ssize != $orig_ssize"
7642         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7643         echo "done."
7644
7645         # Ensure file name properly detected when final option has no argument
7646         echo -n "Verifying file name properly detected..."
7647         $LFS_MIGRATE "$file1" ||
7648                 error "file name interpreted as option argument"
7649         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7650         echo "done."
7651
7652         # Ensure PFL arguments are passed through properly
7653         echo -n "Verifying PFL options passed through..."
7654         new_scount=$(((OSTCOUNT + 1) / 2))
7655         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7656                 error "migrate PFL arguments failed"
7657         cur_comp=$($LFS getstripe --comp-count $file1)
7658         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7659         cur_scount=$($LFS getstripe --stripe-count $file1)
7660         (( cur_scount == new_scount)) ||
7661                 error "PFL stripe count $cur_scount != $new_scount"
7662         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7663         echo "done."
7664 }
7665 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7666
7667 test_56wd() {
7668         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7669
7670         local file1=$DIR/$tdir/$tfile
7671
7672         echo -n "Creating test dir..."
7673         test_mkdir $DIR/$tdir || error "cannot create dir"
7674         echo "done."
7675
7676         echo -n "Creating test file..."
7677         echo "$tfile" > $file1
7678         echo "done."
7679
7680         # Ensure 'lfs migrate' will fail by using a non-existent option,
7681         # and make sure rsync is not called to recover
7682         echo -n "Make sure --no-rsync option works..."
7683         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7684                 grep -q 'refusing to fall back to rsync' ||
7685                 error "rsync was called with --no-rsync set"
7686         echo "done."
7687
7688         # Ensure rsync is called without trying 'lfs migrate' first
7689         echo -n "Make sure --rsync option works..."
7690         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7691                 grep -q 'falling back to rsync' &&
7692                 error "lfs migrate was called with --rsync set"
7693         echo "done."
7694 }
7695 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7696
7697 test_56we() {
7698         local td=$DIR/$tdir
7699         local tf=$td/$tfile
7700
7701         test_mkdir $td || error "cannot create $td"
7702         touch $tf || error "cannot touch $tf"
7703
7704         echo -n "Make sure --non-direct|-D works..."
7705         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7706                 grep -q "lfs migrate --non-direct" ||
7707                 error "--non-direct option cannot work correctly"
7708         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7709                 grep -q "lfs migrate -D" ||
7710                 error "-D option cannot work correctly"
7711         echo "done."
7712 }
7713 run_test 56we "check lfs_migrate --non-direct|-D support"
7714
7715 test_56x() {
7716         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7717         check_swap_layouts_support
7718
7719         local dir=$DIR/$tdir
7720         local ref1=/etc/passwd
7721         local file1=$dir/file1
7722
7723         test_mkdir $dir || error "creating dir $dir"
7724         $LFS setstripe -c 2 $file1
7725         cp $ref1 $file1
7726         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7727         stripe=$($LFS getstripe -c $file1)
7728         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7729         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7730
7731         # clean up
7732         rm -f $file1
7733 }
7734 run_test 56x "lfs migration support"
7735
7736 test_56xa() {
7737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7738         check_swap_layouts_support
7739
7740         local dir=$DIR/$tdir/$testnum
7741
7742         test_mkdir -p $dir
7743
7744         local ref1=/etc/passwd
7745         local file1=$dir/file1
7746
7747         $LFS setstripe -c 2 $file1
7748         cp $ref1 $file1
7749         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7750
7751         local stripe=$($LFS getstripe -c $file1)
7752
7753         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7754         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7755
7756         # clean up
7757         rm -f $file1
7758 }
7759 run_test 56xa "lfs migration --block support"
7760
7761 check_migrate_links() {
7762         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7763         local dir="$1"
7764         local file1="$dir/file1"
7765         local begin="$2"
7766         local count="$3"
7767         local runas="$4"
7768         local total_count=$(($begin + $count - 1))
7769         local symlink_count=10
7770         local uniq_count=10
7771
7772         if [ ! -f "$file1" ]; then
7773                 echo -n "creating initial file..."
7774                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7775                         error "cannot setstripe initial file"
7776                 echo "done"
7777
7778                 echo -n "creating symlinks..."
7779                 for s in $(seq 1 $symlink_count); do
7780                         ln -s "$file1" "$dir/slink$s" ||
7781                                 error "cannot create symlinks"
7782                 done
7783                 echo "done"
7784
7785                 echo -n "creating nonlinked files..."
7786                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7787                         error "cannot create nonlinked files"
7788                 echo "done"
7789         fi
7790
7791         # create hard links
7792         if [ ! -f "$dir/file$total_count" ]; then
7793                 echo -n "creating hard links $begin:$total_count..."
7794                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7795                         /dev/null || error "cannot create hard links"
7796                 echo "done"
7797         fi
7798
7799         echo -n "checking number of hard links listed in xattrs..."
7800         local fid=$($LFS getstripe -F "$file1")
7801         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7802
7803         echo "${#paths[*]}"
7804         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7805                         skip "hard link list has unexpected size, skipping test"
7806         fi
7807         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7808                         error "link names should exceed xattrs size"
7809         fi
7810
7811         echo -n "migrating files..."
7812         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7813         local rc=$?
7814         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7815         echo "done"
7816
7817         # make sure all links have been properly migrated
7818         echo -n "verifying files..."
7819         fid=$($LFS getstripe -F "$file1") ||
7820                 error "cannot get fid for file $file1"
7821         for i in $(seq 2 $total_count); do
7822                 local fid2=$($LFS getstripe -F $dir/file$i)
7823
7824                 [ "$fid2" == "$fid" ] ||
7825                         error "migrated hard link has mismatched FID"
7826         done
7827
7828         # make sure hard links were properly detected, and migration was
7829         # performed only once for the entire link set; nonlinked files should
7830         # also be migrated
7831         local actual=$(grep -c 'done' <<< "$migrate_out")
7832         local expected=$(($uniq_count + 1))
7833
7834         [ "$actual" -eq  "$expected" ] ||
7835                 error "hard links individually migrated ($actual != $expected)"
7836
7837         # make sure the correct number of hard links are present
7838         local hardlinks=$(stat -c '%h' "$file1")
7839
7840         [ $hardlinks -eq $total_count ] ||
7841                 error "num hard links $hardlinks != $total_count"
7842         echo "done"
7843
7844         return 0
7845 }
7846
7847 test_56xb() {
7848         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7849                 skip "Need MDS version at least 2.10.55"
7850
7851         local dir="$DIR/$tdir"
7852
7853         test_mkdir "$dir" || error "cannot create dir $dir"
7854
7855         echo "testing lfs migrate mode when all links fit within xattrs"
7856         check_migrate_links "$dir" 2 99
7857
7858         echo "testing rsync mode when all links fit within xattrs"
7859         check_migrate_links --rsync "$dir" 2 99
7860
7861         echo "testing lfs migrate mode when all links do not fit within xattrs"
7862         check_migrate_links "$dir" 101 100
7863
7864         echo "testing rsync mode when all links do not fit within xattrs"
7865         check_migrate_links --rsync "$dir" 101 100
7866
7867         chown -R $RUNAS_ID $dir
7868         echo "testing non-root lfs migrate mode when not all links are in xattr"
7869         check_migrate_links "$dir" 101 100 "$RUNAS"
7870
7871         # clean up
7872         rm -rf $dir
7873 }
7874 run_test 56xb "lfs migration hard link support"
7875
7876 test_56xc() {
7877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7878
7879         local dir="$DIR/$tdir"
7880
7881         test_mkdir "$dir" || error "cannot create dir $dir"
7882
7883         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7884         echo -n "Setting initial stripe for 20MB test file..."
7885         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7886                 error "cannot setstripe 20MB file"
7887         echo "done"
7888         echo -n "Sizing 20MB test file..."
7889         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7890         echo "done"
7891         echo -n "Verifying small file autostripe count is 1..."
7892         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7893                 error "cannot migrate 20MB file"
7894         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7895                 error "cannot get stripe for $dir/20mb"
7896         [ $stripe_count -eq 1 ] ||
7897                 error "unexpected stripe count $stripe_count for 20MB file"
7898         rm -f "$dir/20mb"
7899         echo "done"
7900
7901         # Test 2: File is small enough to fit within the available space on
7902         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7903         # have at least an additional 1KB for each desired stripe for test 3
7904         echo -n "Setting stripe for 1GB test file..."
7905         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7906         echo "done"
7907         echo -n "Sizing 1GB test file..."
7908         # File size is 1GB + 3KB
7909         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7910         echo "done"
7911
7912         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7913         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7914         if (( avail > 524288 * OSTCOUNT )); then
7915                 echo -n "Migrating 1GB file..."
7916                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7917                         error "cannot migrate 1GB file"
7918                 echo "done"
7919                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7920                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7921                         error "cannot getstripe for 1GB file"
7922                 [ $stripe_count -eq 2 ] ||
7923                         error "unexpected stripe count $stripe_count != 2"
7924                 echo "done"
7925         fi
7926
7927         # Test 3: File is too large to fit within the available space on
7928         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7929         if [ $OSTCOUNT -ge 3 ]; then
7930                 # The required available space is calculated as
7931                 # file size (1GB + 3KB) / OST count (3).
7932                 local kb_per_ost=349526
7933
7934                 echo -n "Migrating 1GB file with limit..."
7935                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7936                         error "cannot migrate 1GB file with limit"
7937                 echo "done"
7938
7939                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7940                 echo -n "Verifying 1GB autostripe count with limited space..."
7941                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7942                         error "unexpected stripe count $stripe_count (min 3)"
7943                 echo "done"
7944         fi
7945
7946         # clean up
7947         rm -rf $dir
7948 }
7949 run_test 56xc "lfs migration autostripe"
7950
7951 test_56xd() {
7952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7953
7954         local dir=$DIR/$tdir
7955         local f_mgrt=$dir/$tfile.mgrt
7956         local f_yaml=$dir/$tfile.yaml
7957         local f_copy=$dir/$tfile.copy
7958         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7959         local layout_copy="-c 2 -S 2M -i 1"
7960         local yamlfile=$dir/yamlfile
7961         local layout_before;
7962         local layout_after;
7963
7964         test_mkdir "$dir" || error "cannot create dir $dir"
7965         $LFS setstripe $layout_yaml $f_yaml ||
7966                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7967         $LFS getstripe --yaml $f_yaml > $yamlfile
7968         $LFS setstripe $layout_copy $f_copy ||
7969                 error "cannot setstripe $f_copy with layout $layout_copy"
7970         touch $f_mgrt
7971         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7972
7973         # 1. test option --yaml
7974         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7975                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7976         layout_before=$(get_layout_param $f_yaml)
7977         layout_after=$(get_layout_param $f_mgrt)
7978         [ "$layout_after" == "$layout_before" ] ||
7979                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7980
7981         # 2. test option --copy
7982         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7983                 error "cannot migrate $f_mgrt with --copy $f_copy"
7984         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
7985         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
7986         [ "$layout_after" == "$layout_before" ] ||
7987                 error "lfs_migrate --copy: $layout_after != $layout_before"
7988 }
7989 run_test 56xd "check lfs_migrate --yaml and --copy support"
7990
7991 test_56xe() {
7992         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7993
7994         local dir=$DIR/$tdir
7995         local f_comp=$dir/$tfile
7996         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7997         local layout_before=""
7998         local layout_after=""
7999
8000         test_mkdir "$dir" || error "cannot create dir $dir"
8001         $LFS setstripe $layout $f_comp ||
8002                 error "cannot setstripe $f_comp with layout $layout"
8003         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8004         dd if=/dev/zero of=$f_comp bs=1M count=4
8005
8006         # 1. migrate a comp layout file by lfs_migrate
8007         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8008         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8009         [ "$layout_before" == "$layout_after" ] ||
8010                 error "lfs_migrate: $layout_before != $layout_after"
8011
8012         # 2. migrate a comp layout file by lfs migrate
8013         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8014         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8015         [ "$layout_before" == "$layout_after" ] ||
8016                 error "lfs migrate: $layout_before != $layout_after"
8017 }
8018 run_test 56xe "migrate a composite layout file"
8019
8020 test_56xf() {
8021         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8022
8023         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8024                 skip "Need server version at least 2.13.53"
8025
8026         local dir=$DIR/$tdir
8027         local f_comp=$dir/$tfile
8028         local layout="-E 1M -c1 -E -1 -c2"
8029         local fid_before=""
8030         local fid_after=""
8031
8032         test_mkdir "$dir" || error "cannot create dir $dir"
8033         $LFS setstripe $layout $f_comp ||
8034                 error "cannot setstripe $f_comp with layout $layout"
8035         fid_before=$($LFS getstripe --fid $f_comp)
8036         dd if=/dev/zero of=$f_comp bs=1M count=4
8037
8038         # 1. migrate a comp layout file to a comp layout
8039         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8040         fid_after=$($LFS getstripe --fid $f_comp)
8041         [ "$fid_before" == "$fid_after" ] ||
8042                 error "comp-to-comp migrate: $fid_before != $fid_after"
8043
8044         # 2. migrate a comp layout file to a plain layout
8045         $LFS migrate -c2 $f_comp ||
8046                 error "cannot migrate $f_comp by lfs migrate"
8047         fid_after=$($LFS getstripe --fid $f_comp)
8048         [ "$fid_before" == "$fid_after" ] ||
8049                 error "comp-to-plain migrate: $fid_before != $fid_after"
8050
8051         # 3. migrate a plain layout file to a comp layout
8052         $LFS migrate $layout $f_comp ||
8053                 error "cannot migrate $f_comp by lfs migrate"
8054         fid_after=$($LFS getstripe --fid $f_comp)
8055         [ "$fid_before" == "$fid_after" ] ||
8056                 error "plain-to-comp migrate: $fid_before != $fid_after"
8057 }
8058 run_test 56xf "FID is not lost during migration of a composite layout file"
8059
8060 check_file_ost_range() {
8061         local file="$1"
8062         shift
8063         local range="$*"
8064         local -a file_range
8065         local idx
8066
8067         file_range=($($LFS getstripe -y "$file" |
8068                 awk '/l_ost_idx:/ { print $NF }'))
8069
8070         if [[ "${#file_range[@]}" = 0 ]]; then
8071                 echo "No osts found for $file"
8072                 return 1
8073         fi
8074
8075         for idx in "${file_range[@]}"; do
8076                 [[ " $range " =~ " $idx " ]] ||
8077                         return 1
8078         done
8079
8080         return 0
8081 }
8082
8083 sub_test_56xg() {
8084         local stripe_opt="$1"
8085         local pool="$2"
8086         shift 2
8087         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8088
8089         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8090                 error "Fail to migrate $tfile on $pool"
8091         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8092                 error "$tfile is not in pool $pool"
8093         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8094                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8095 }
8096
8097 test_56xg() {
8098         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8099         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8100         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8101                 skip "Need MDS version newer than 2.14.52"
8102
8103         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8104         local -a pool_ranges=("0 0" "1 1" "0 1")
8105
8106         # init pools
8107         for i in "${!pool_names[@]}"; do
8108                 pool_add ${pool_names[$i]} ||
8109                         error "pool_add failed (pool: ${pool_names[$i]})"
8110                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8111                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8112         done
8113
8114         # init the file to migrate
8115         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8116                 error "Unable to create $tfile on OST1"
8117         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8118                 error "Unable to write on $tfile"
8119
8120         echo "1. migrate $tfile on pool ${pool_names[0]}"
8121         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8122
8123         echo "2. migrate $tfile on pool ${pool_names[2]}"
8124         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8125
8126         echo "3. migrate $tfile on pool ${pool_names[1]}"
8127         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8128
8129         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8130         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8131         echo
8132
8133         # Clean pools
8134         destroy_test_pools ||
8135                 error "pool_destroy failed"
8136 }
8137 run_test 56xg "lfs migrate pool support"
8138
8139 test_56xh() {
8140         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8141
8142         local size_mb=25
8143         local file1=$DIR/$tfile
8144         local tmp1=$TMP/$tfile.tmp
8145
8146         $LFS setstripe -c 2 $file1
8147
8148         stack_trap "rm -f $file1 $tmp1"
8149         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8150                         error "error creating $tmp1"
8151         ls -lsh $tmp1
8152         cp $tmp1 $file1
8153
8154         local start=$SECONDS
8155
8156         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8157                 error "migrate failed rc = $?"
8158
8159         local elapsed=$((SECONDS - start))
8160
8161         # with 1MB/s, elapsed should equal size_mb
8162         (( elapsed >= size_mb * 95 / 100 )) ||
8163                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8164
8165         (( elapsed <= size_mb * 120 / 100 )) ||
8166                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8167
8168         (( elapsed <= size_mb * 150 / 100 )) ||
8169                 error "'lfs migrate -W' too slow in VM ($elapsed > 2 * $size_mb 2)"
8170
8171         stripe=$($LFS getstripe -c $file1)
8172         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8173         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8174
8175         # Clean up file (since it is multiple MB)
8176         rm -f $file1 $tmp1
8177 }
8178 run_test 56xh "lfs migrate bandwidth limitation support"
8179
8180 test_56xi() {
8181         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8182         verify_yaml_available || skip_env "YAML verification not installed"
8183
8184         local size_mb=5
8185         local file1=$DIR/$tfile.1
8186         local file2=$DIR/$tfile.2
8187         local file3=$DIR/$tfile.3
8188         local output_file=$DIR/$tfile.out
8189         local tmp1=$TMP/$tfile.tmp
8190
8191         $LFS setstripe -c 2 $file1
8192         $LFS setstripe -c 2 $file2
8193         $LFS setstripe -c 2 $file3
8194
8195         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8196         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8197                         error "error creating $tmp1"
8198         ls -lsh $tmp1
8199         cp $tmp1 $file1
8200         cp $tmp1 $file2
8201         cp $tmp1 $file3
8202
8203         $LFS migrate --stats --stats-interval=1 \
8204                 -c 1 $file1 $file2 $file3 1> $output_file ||
8205                 error "migrate failed rc = $?"
8206
8207         cat $output_file
8208         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8209
8210         # Clean up file (since it is multiple MB)
8211         rm -f $file1 $file2 $file3 $tmp1 $output_file
8212 }
8213 run_test 56xi "lfs migrate stats support"
8214
8215 test_56y() {
8216         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8217                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8218
8219         local res=""
8220         local dir=$DIR/$tdir
8221         local f1=$dir/file1
8222         local f2=$dir/file2
8223
8224         test_mkdir -p $dir || error "creating dir $dir"
8225         touch $f1 || error "creating std file $f1"
8226         $MULTIOP $f2 H2c || error "creating released file $f2"
8227
8228         # a directory can be raid0, so ask only for files
8229         res=$($LFS find $dir -L raid0 -type f | wc -l)
8230         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8231
8232         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8233         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8234
8235         # only files can be released, so no need to force file search
8236         res=$($LFS find $dir -L released)
8237         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8238
8239         res=$($LFS find $dir -type f \! -L released)
8240         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8241 }
8242 run_test 56y "lfs find -L raid0|released"
8243
8244 test_56z() { # LU-4824
8245         # This checks to make sure 'lfs find' continues after errors
8246         # There are two classes of errors that should be caught:
8247         # - If multiple paths are provided, all should be searched even if one
8248         #   errors out
8249         # - If errors are encountered during the search, it should not terminate
8250         #   early
8251         local dir=$DIR/$tdir
8252         local i
8253
8254         test_mkdir $dir
8255         for i in d{0..9}; do
8256                 test_mkdir $dir/$i
8257                 touch $dir/$i/$tfile
8258         done
8259         $LFS find $DIR/non_existent_dir $dir &&
8260                 error "$LFS find did not return an error"
8261         # Make a directory unsearchable. This should NOT be the last entry in
8262         # directory order.  Arbitrarily pick the 6th entry
8263         chmod 700 $($LFS find $dir -type d | sed '6!d')
8264
8265         $RUNAS $LFS find $DIR/non_existent $dir
8266         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8267
8268         # The user should be able to see 10 directories and 9 files
8269         (( count == 19 )) ||
8270                 error "$LFS find found $count != 19 entries after error"
8271 }
8272 run_test 56z "lfs find should continue after an error"
8273
8274 test_56aa() { # LU-5937
8275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8276
8277         local dir=$DIR/$tdir
8278
8279         mkdir $dir
8280         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8281
8282         createmany -o $dir/striped_dir/${tfile}- 1024
8283         local dirs=$($LFS find --size +8k $dir/)
8284
8285         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8286 }
8287 run_test 56aa "lfs find --size under striped dir"
8288
8289 test_56ab() { # LU-10705
8290         test_mkdir $DIR/$tdir
8291         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8292         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8293         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8294         # Flush writes to ensure valid blocks.  Need to be more thorough for
8295         # ZFS, since blocks are not allocated/returned to client immediately.
8296         sync_all_data
8297         wait_zfs_commit ost1 2
8298         cancel_lru_locks osc
8299         ls -ls $DIR/$tdir
8300
8301         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8302
8303         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8304
8305         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8306         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8307
8308         rm -f $DIR/$tdir/$tfile.[123]
8309 }
8310 run_test 56ab "lfs find --blocks"
8311
8312 # LU-11188
8313 test_56aca() {
8314         local dir="$DIR/$tdir"
8315         local perms=(001 002 003 004 005 006 007
8316                      010 020 030 040 050 060 070
8317                      100 200 300 400 500 600 700
8318                      111 222 333 444 555 666 777)
8319         local perm_minus=(8 8 4 8 4 4 2
8320                           8 8 4 8 4 4 2
8321                           8 8 4 8 4 4 2
8322                           4 4 2 4 2 2 1)
8323         local perm_slash=(8  8 12  8 12 12 14
8324                           8  8 12  8 12 12 14
8325                           8  8 12  8 12 12 14
8326                          16 16 24 16 24 24 28)
8327
8328         test_mkdir "$dir"
8329         for perm in ${perms[*]}; do
8330                 touch "$dir/$tfile.$perm"
8331                 chmod $perm "$dir/$tfile.$perm"
8332         done
8333
8334         for ((i = 0; i < ${#perms[*]}; i++)); do
8335                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8336                 (( $num == 1 )) ||
8337                         error "lfs find -perm ${perms[i]}:"\
8338                               "$num != 1"
8339
8340                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8341                 (( $num == ${perm_minus[i]} )) ||
8342                         error "lfs find -perm -${perms[i]}:"\
8343                               "$num != ${perm_minus[i]}"
8344
8345                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8346                 (( $num == ${perm_slash[i]} )) ||
8347                         error "lfs find -perm /${perms[i]}:"\
8348                               "$num != ${perm_slash[i]}"
8349         done
8350 }
8351 run_test 56aca "check lfs find -perm with octal representation"
8352
8353 test_56acb() {
8354         local dir=$DIR/$tdir
8355         # p is the permission of write and execute for user, group and other
8356         # without the umask. It is used to test +wx.
8357         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8358         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8359         local symbolic=(+t  a+t u+t g+t o+t
8360                         g+s u+s o+s +s o+sr
8361                         o=r,ug+o,u+w
8362                         u+ g+ o+ a+ ugo+
8363                         u- g- o- a- ugo-
8364                         u= g= o= a= ugo=
8365                         o=r,ug+o,u+w u=r,a+u,u+w
8366                         g=r,ugo=g,u+w u+x,+X +X
8367                         u+x,u+X u+X u+x,g+X o+r,+X
8368                         u+x,go+X +wx +rwx)
8369
8370         test_mkdir $dir
8371         for perm in ${perms[*]}; do
8372                 touch "$dir/$tfile.$perm"
8373                 chmod $perm "$dir/$tfile.$perm"
8374         done
8375
8376         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8377                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8378
8379                 (( $num == 1 )) ||
8380                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8381         done
8382 }
8383 run_test 56acb "check lfs find -perm with symbolic representation"
8384
8385 test_56acc() {
8386         local dir=$DIR/$tdir
8387         local tests="17777 787 789 abcd
8388                 ug=uu ug=a ug=gu uo=ou urw
8389                 u+xg+x a=r,u+x,"
8390
8391         test_mkdir $dir
8392         for err in $tests; do
8393                 if $LFS find $dir -perm $err 2>/dev/null; then
8394                         error "lfs find -perm $err: parsing should have failed"
8395                 fi
8396         done
8397 }
8398 run_test 56acc "check parsing error for lfs find -perm"
8399
8400 test_56ba() {
8401         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8402                 skip "Need MDS version at least 2.10.50"
8403
8404         # Create composite files with one component
8405         local dir=$DIR/$tdir
8406
8407         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8408         # Create composite files with three components
8409         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8410         # Create non-composite files
8411         createmany -o $dir/${tfile}- 10
8412
8413         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8414
8415         [[ $nfiles == 10 ]] ||
8416                 error "lfs find -E 1M found $nfiles != 10 files"
8417
8418         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8419         [[ $nfiles == 25 ]] ||
8420                 error "lfs find ! -E 1M found $nfiles != 25 files"
8421
8422         # All files have a component that starts at 0
8423         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8424         [[ $nfiles == 35 ]] ||
8425                 error "lfs find --component-start 0 - $nfiles != 35 files"
8426
8427         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8428         [[ $nfiles == 15 ]] ||
8429                 error "lfs find --component-start 2M - $nfiles != 15 files"
8430
8431         # All files created here have a componenet that does not starts at 2M
8432         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8433         [[ $nfiles == 35 ]] ||
8434                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8435
8436         # Find files with a specified number of components
8437         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8438         [[ $nfiles == 15 ]] ||
8439                 error "lfs find --component-count 3 - $nfiles != 15 files"
8440
8441         # Remember non-composite files have a component count of zero
8442         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8443         [[ $nfiles == 10 ]] ||
8444                 error "lfs find --component-count 0 - $nfiles != 10 files"
8445
8446         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8447         [[ $nfiles == 20 ]] ||
8448                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8449
8450         # All files have a flag called "init"
8451         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8452         [[ $nfiles == 35 ]] ||
8453                 error "lfs find --component-flags init - $nfiles != 35 files"
8454
8455         # Multi-component files will have a component not initialized
8456         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8457         [[ $nfiles == 15 ]] ||
8458                 error "lfs find !--component-flags init - $nfiles != 15 files"
8459
8460         rm -rf $dir
8461
8462 }
8463 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8464
8465 test_56ca() {
8466         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8467                 skip "Need MDS version at least 2.10.57"
8468
8469         local td=$DIR/$tdir
8470         local tf=$td/$tfile
8471         local dir
8472         local nfiles
8473         local cmd
8474         local i
8475         local j
8476
8477         # create mirrored directories and mirrored files
8478         mkdir $td || error "mkdir $td failed"
8479         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8480         createmany -o $tf- 10 || error "create $tf- failed"
8481
8482         for i in $(seq 2); do
8483                 dir=$td/dir$i
8484                 mkdir $dir || error "mkdir $dir failed"
8485                 $LFS mirror create -N$((3 + i)) $dir ||
8486                         error "create mirrored dir $dir failed"
8487                 createmany -o $dir/$tfile- 10 ||
8488                         error "create $dir/$tfile- failed"
8489         done
8490
8491         # change the states of some mirrored files
8492         echo foo > $tf-6
8493         for i in $(seq 2); do
8494                 dir=$td/dir$i
8495                 for j in $(seq 4 9); do
8496                         echo foo > $dir/$tfile-$j
8497                 done
8498         done
8499
8500         # find mirrored files with specific mirror count
8501         cmd="$LFS find --mirror-count 3 --type f $td"
8502         nfiles=$($cmd | wc -l)
8503         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8504
8505         cmd="$LFS find ! --mirror-count 3 --type f $td"
8506         nfiles=$($cmd | wc -l)
8507         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8508
8509         cmd="$LFS find --mirror-count +2 --type f $td"
8510         nfiles=$($cmd | wc -l)
8511         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8512
8513         cmd="$LFS find --mirror-count -6 --type f $td"
8514         nfiles=$($cmd | wc -l)
8515         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8516
8517         # find mirrored files with specific file state
8518         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8519         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8520
8521         cmd="$LFS find --mirror-state=ro --type f $td"
8522         nfiles=$($cmd | wc -l)
8523         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8524
8525         cmd="$LFS find ! --mirror-state=ro --type f $td"
8526         nfiles=$($cmd | wc -l)
8527         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8528
8529         cmd="$LFS find --mirror-state=wp --type f $td"
8530         nfiles=$($cmd | wc -l)
8531         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8532
8533         cmd="$LFS find ! --mirror-state=sp --type f $td"
8534         nfiles=$($cmd | wc -l)
8535         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8536 }
8537 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8538
8539 test_56da() { # LU-14179
8540         local path=$DIR/$tdir
8541
8542         test_mkdir $path
8543         cd $path
8544
8545         local longdir=$(str_repeat 'a' 255)
8546
8547         for i in {1..15}; do
8548                 path=$path/$longdir
8549                 test_mkdir $longdir
8550                 cd $longdir
8551         done
8552
8553         local len=${#path}
8554         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8555
8556         test_mkdir $lastdir
8557         cd $lastdir
8558         # PATH_MAX-1
8559         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8560
8561         # NAME_MAX
8562         touch $(str_repeat 'f' 255)
8563
8564         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8565                 error "lfs find reported an error"
8566
8567         rm -rf $DIR/$tdir
8568 }
8569 run_test 56da "test lfs find with long paths"
8570
8571 test_56ea() { #LU-10378
8572         local path=$DIR/$tdir
8573         local pool=$TESTNAME
8574
8575         # Create ost pool
8576         pool_add $pool || error "pool_add $pool failed"
8577         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8578                 error "adding targets to $pool failed"
8579
8580         # Set default pool on directory before creating file
8581         mkdir $path || error "mkdir $path failed"
8582         $LFS setstripe -p $pool $path ||
8583                 error "set OST pool on $pool failed"
8584         touch $path/$tfile || error "touch $path/$tfile failed"
8585
8586         # Compare basic file attributes from -printf and stat
8587         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8588         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8589
8590         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8591                 error "Attrs from lfs find and stat don't match"
8592
8593         # Compare Lustre attributes from lfs find and lfs getstripe
8594         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8595         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8596         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8597         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8598         local fpool=$($LFS getstripe --pool $path/$tfile)
8599         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8600
8601         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8602                 error "Attrs from lfs find and lfs getstripe don't match"
8603
8604         # Verify behavior for unknown escape/format sequences
8605         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8606
8607         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8608                 error "Escape/format codes don't match"
8609 }
8610 run_test 56ea "test lfs find -printf option"
8611
8612 test_56eb() {
8613         local dir=$DIR/$tdir
8614         local subdir_1=$dir/subdir_1
8615
8616         test_mkdir -p $subdir_1
8617         ln -s subdir_1 $dir/link_1
8618
8619         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8620                 error "symlink is not followed"
8621
8622         $LFS getstripe --no-follow $dir |
8623                 grep "^$dir/link_1 has no stripe info$" ||
8624                 error "symlink should not have stripe info"
8625
8626         touch $dir/testfile
8627         ln -s testfile $dir/file_link_2
8628
8629         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8630                 error "symlink is not followed"
8631
8632         $LFS getstripe --no-follow $dir |
8633                 grep "^$dir/file_link_2 has no stripe info$" ||
8634                 error "symlink should not have stripe info"
8635 }
8636 run_test 56eb "check lfs getstripe on symlink"
8637
8638 test_57a() {
8639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8640         # note test will not do anything if MDS is not local
8641         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8642                 skip_env "ldiskfs only test"
8643         fi
8644         remote_mds_nodsh && skip "remote MDS with nodsh"
8645
8646         local MNTDEV="osd*.*MDT*.mntdev"
8647         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8648         [ -z "$DEV" ] && error "can't access $MNTDEV"
8649         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8650                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8651                         error "can't access $DEV"
8652                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8653                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8654                 rm $TMP/t57a.dump
8655         done
8656 }
8657 run_test 57a "verify MDS filesystem created with large inodes =="
8658
8659 test_57b() {
8660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8661         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8662                 skip_env "ldiskfs only test"
8663         fi
8664         remote_mds_nodsh && skip "remote MDS with nodsh"
8665
8666         local dir=$DIR/$tdir
8667         local filecount=100
8668         local file1=$dir/f1
8669         local fileN=$dir/f$filecount
8670
8671         rm -rf $dir || error "removing $dir"
8672         test_mkdir -c1 $dir
8673         local mdtidx=$($LFS getstripe -m $dir)
8674         local mdtname=MDT$(printf %04x $mdtidx)
8675         local facet=mds$((mdtidx + 1))
8676
8677         echo "mcreating $filecount files"
8678         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8679
8680         # verify that files do not have EAs yet
8681         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8682                 error "$file1 has an EA"
8683         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8684                 error "$fileN has an EA"
8685
8686         sync
8687         sleep 1
8688         df $dir  #make sure we get new statfs data
8689         local mdsfree=$(do_facet $facet \
8690                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8691         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8692         local file
8693
8694         echo "opening files to create objects/EAs"
8695         for file in $(seq -f $dir/f%g 1 $filecount); do
8696                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8697                         error "opening $file"
8698         done
8699
8700         # verify that files have EAs now
8701         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8702         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8703
8704         sleep 1  #make sure we get new statfs data
8705         df $dir
8706         local mdsfree2=$(do_facet $facet \
8707                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8708         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8709
8710         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8711                 if [ "$mdsfree" != "$mdsfree2" ]; then
8712                         error "MDC before $mdcfree != after $mdcfree2"
8713                 else
8714                         echo "MDC before $mdcfree != after $mdcfree2"
8715                         echo "unable to confirm if MDS has large inodes"
8716                 fi
8717         fi
8718         rm -rf $dir
8719 }
8720 run_test 57b "default LOV EAs are stored inside large inodes ==="
8721
8722 test_58() {
8723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8724         [ -z "$(which wiretest 2>/dev/null)" ] &&
8725                         skip_env "could not find wiretest"
8726
8727         wiretest
8728 }
8729 run_test 58 "verify cross-platform wire constants =============="
8730
8731 test_59() {
8732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8733
8734         echo "touch 130 files"
8735         createmany -o $DIR/f59- 130
8736         echo "rm 130 files"
8737         unlinkmany $DIR/f59- 130
8738         sync
8739         # wait for commitment of removal
8740         wait_delete_completed
8741 }
8742 run_test 59 "verify cancellation of llog records async ========="
8743
8744 TEST60_HEAD="test_60 run $RANDOM"
8745 test_60a() {
8746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8747         remote_mgs_nodsh && skip "remote MGS with nodsh"
8748         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8749                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8750                         skip_env "missing subtest run-llog.sh"
8751
8752         log "$TEST60_HEAD - from kernel mode"
8753         do_facet mgs "$LCTL dk > /dev/null"
8754         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8755         do_facet mgs $LCTL dk > $TMP/$tfile
8756
8757         # LU-6388: test llog_reader
8758         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8759         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8760         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8761                         skip_env "missing llog_reader"
8762         local fstype=$(facet_fstype mgs)
8763         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8764                 skip_env "Only for ldiskfs or zfs type mgs"
8765
8766         local mntpt=$(facet_mntpt mgs)
8767         local mgsdev=$(mgsdevname 1)
8768         local fid_list
8769         local fid
8770         local rec_list
8771         local rec
8772         local rec_type
8773         local obj_file
8774         local path
8775         local seq
8776         local oid
8777         local pass=true
8778
8779         #get fid and record list
8780         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8781                 tail -n 4))
8782         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8783                 tail -n 4))
8784         #remount mgs as ldiskfs or zfs type
8785         stop mgs || error "stop mgs failed"
8786         mount_fstype mgs || error "remount mgs failed"
8787         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8788                 fid=${fid_list[i]}
8789                 rec=${rec_list[i]}
8790                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8791                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8792                 oid=$((16#$oid))
8793
8794                 case $fstype in
8795                         ldiskfs )
8796                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8797                         zfs )
8798                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8799                 esac
8800                 echo "obj_file is $obj_file"
8801                 do_facet mgs $llog_reader $obj_file
8802
8803                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8804                         awk '{ print $3 }' | sed -e "s/^type=//g")
8805                 if [ $rec_type != $rec ]; then
8806                         echo "FAILED test_60a wrong record type $rec_type," \
8807                               "should be $rec"
8808                         pass=false
8809                         break
8810                 fi
8811
8812                 #check obj path if record type is LLOG_LOGID_MAGIC
8813                 if [ "$rec" == "1064553b" ]; then
8814                         path=$(do_facet mgs $llog_reader $obj_file |
8815                                 grep "path=" | awk '{ print $NF }' |
8816                                 sed -e "s/^path=//g")
8817                         if [ $obj_file != $mntpt/$path ]; then
8818                                 echo "FAILED test_60a wrong obj path" \
8819                                       "$montpt/$path, should be $obj_file"
8820                                 pass=false
8821                                 break
8822                         fi
8823                 fi
8824         done
8825         rm -f $TMP/$tfile
8826         #restart mgs before "error", otherwise it will block the next test
8827         stop mgs || error "stop mgs failed"
8828         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8829         $pass || error "test failed, see FAILED test_60a messages for specifics"
8830 }
8831 run_test 60a "llog_test run from kernel module and test llog_reader"
8832
8833 test_60b() { # bug 6411
8834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8835
8836         dmesg > $DIR/$tfile
8837         LLOG_COUNT=$(do_facet mgs dmesg |
8838                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8839                           /llog_[a-z]*.c:[0-9]/ {
8840                                 if (marker)
8841                                         from_marker++
8842                                 from_begin++
8843                           }
8844                           END {
8845                                 if (marker)
8846                                         print from_marker
8847                                 else
8848                                         print from_begin
8849                           }")
8850
8851         [[ $LLOG_COUNT -gt 120 ]] &&
8852                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8853 }
8854 run_test 60b "limit repeated messages from CERROR/CWARN"
8855
8856 test_60c() {
8857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8858
8859         echo "create 5000 files"
8860         createmany -o $DIR/f60c- 5000
8861 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8862         lctl set_param fail_loc=0x80000137
8863         unlinkmany $DIR/f60c- 5000
8864         lctl set_param fail_loc=0
8865 }
8866 run_test 60c "unlink file when mds full"
8867
8868 test_60d() {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870
8871         SAVEPRINTK=$(lctl get_param -n printk)
8872         # verify "lctl mark" is even working"
8873         MESSAGE="test message ID $RANDOM $$"
8874         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8875         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8876
8877         lctl set_param printk=0 || error "set lnet.printk failed"
8878         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8879         MESSAGE="new test message ID $RANDOM $$"
8880         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8881         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8882         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8883
8884         lctl set_param -n printk="$SAVEPRINTK"
8885 }
8886 run_test 60d "test printk console message masking"
8887
8888 test_60e() {
8889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8890         remote_mds_nodsh && skip "remote MDS with nodsh"
8891
8892         touch $DIR/$tfile
8893 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8894         do_facet mds1 lctl set_param fail_loc=0x15b
8895         rm $DIR/$tfile
8896 }
8897 run_test 60e "no space while new llog is being created"
8898
8899 test_60f() {
8900         local old_path=$($LCTL get_param -n debug_path)
8901
8902         stack_trap "$LCTL set_param debug_path=$old_path"
8903         stack_trap "rm -f $TMP/$tfile*"
8904         rm -f $TMP/$tfile* 2> /dev/null
8905         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8906         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8907         test_mkdir $DIR/$tdir
8908         # retry in case the open is cached and not released
8909         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8910                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8911                 sleep 0.1
8912         done
8913         ls $TMP/$tfile*
8914         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8915 }
8916 run_test 60f "change debug_path works"
8917
8918 test_60g() {
8919         local pid
8920         local i
8921
8922         test_mkdir -c $MDSCOUNT $DIR/$tdir
8923
8924         (
8925                 local index=0
8926                 while true; do
8927                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8928                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8929                                 2>/dev/null
8930                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8931                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8932                         index=$((index + 1))
8933                 done
8934         ) &
8935
8936         pid=$!
8937
8938         for i in {0..100}; do
8939                 # define OBD_FAIL_OSD_TXN_START    0x19a
8940                 local index=$((i % MDSCOUNT + 1))
8941
8942                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8943                         > /dev/null
8944                 sleep 0.01
8945         done
8946
8947         kill -9 $pid
8948
8949         for i in $(seq $MDSCOUNT); do
8950                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8951         done
8952
8953         mkdir $DIR/$tdir/new || error "mkdir failed"
8954         rmdir $DIR/$tdir/new || error "rmdir failed"
8955
8956         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8957                 -t namespace
8958         for i in $(seq $MDSCOUNT); do
8959                 wait_update_facet mds$i "$LCTL get_param -n \
8960                         mdd.$(facet_svc mds$i).lfsck_namespace |
8961                         awk '/^status/ { print \\\$2 }'" "completed"
8962         done
8963
8964         ls -R $DIR/$tdir
8965         rm -rf $DIR/$tdir || error "rmdir failed"
8966 }
8967 run_test 60g "transaction abort won't cause MDT hung"
8968
8969 test_60h() {
8970         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8971                 skip "Need MDS version at least 2.12.52"
8972         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8973
8974         local f
8975
8976         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8977         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8978         for fail_loc in 0x80000188 0x80000189; do
8979                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8980                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8981                         error "mkdir $dir-$fail_loc failed"
8982                 for i in {0..10}; do
8983                         # create may fail on missing stripe
8984                         echo $i > $DIR/$tdir-$fail_loc/$i
8985                 done
8986                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8987                         error "getdirstripe $tdir-$fail_loc failed"
8988                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8989                         error "migrate $tdir-$fail_loc failed"
8990                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8991                         error "getdirstripe $tdir-$fail_loc failed"
8992                 pushd $DIR/$tdir-$fail_loc
8993                 for f in *; do
8994                         echo $f | cmp $f - || error "$f data mismatch"
8995                 done
8996                 popd
8997                 rm -rf $DIR/$tdir-$fail_loc
8998         done
8999 }
9000 run_test 60h "striped directory with missing stripes can be accessed"
9001
9002 function t60i_load() {
9003         mkdir $DIR/$tdir
9004         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9005         $LCTL set_param fail_loc=0x131c fail_val=1
9006         for ((i=0; i<5000; i++)); do
9007                 touch $DIR/$tdir/f$i
9008         done
9009 }
9010
9011 test_60i() {
9012         changelog_register || error "changelog_register failed"
9013         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9014         changelog_users $SINGLEMDS | grep -q $cl_user ||
9015                 error "User $cl_user not found in changelog_users"
9016         changelog_chmask "ALL"
9017         t60i_load &
9018         local PID=$!
9019         for((i=0; i<100; i++)); do
9020                 changelog_dump >/dev/null ||
9021                         error "can't read changelog"
9022         done
9023         kill $PID
9024         wait $PID
9025         changelog_deregister || error "changelog_deregister failed"
9026         $LCTL set_param fail_loc=0
9027 }
9028 run_test 60i "llog: new record vs reader race"
9029
9030 test_60j() {
9031         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9032                 skip "need MDS version at least 2.15.50"
9033         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9034         remote_mds_nodsh && skip "remote MDS with nodsh"
9035         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9036
9037         changelog_users $SINGLEMDS | grep "^cl" &&
9038                 skip "active changelog user"
9039
9040         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9041
9042         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9043                 skip_env "missing llog_reader"
9044
9045         mkdir_on_mdt0 $DIR/$tdir
9046
9047         local f=$DIR/$tdir/$tfile
9048         local mdt_dev
9049         local tmpfile
9050         local plain
9051
9052         changelog_register || error "cannot register changelog user"
9053
9054         # set changelog_mask to ALL
9055         changelog_chmask "ALL"
9056         changelog_clear
9057
9058         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9059         unlinkmany ${f}- 100 || error "unlinkmany failed"
9060
9061         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9062         mdt_dev=$(facet_device $SINGLEMDS)
9063
9064         do_facet $SINGLEMDS sync
9065         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9066                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9067                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9068
9069         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9070
9071         # if $tmpfile is not on EXT3 filesystem for some reason
9072         [[ ${plain:0:1} == 'O' ]] ||
9073                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9074
9075         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9076                 $mdt_dev; stat -c %s $tmpfile")
9077         echo "Truncate llog from $size to $((size - size % 8192))"
9078         size=$((size - size % 8192))
9079         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9080         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9081                 grep -c 'in bitmap only')
9082         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9083
9084         size=$((size - 9000))
9085         echo "Corrupt llog in the middle at $size"
9086         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9087                 count=333 conv=notrunc
9088         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9089                 grep -c 'next chunk')
9090         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9091 }
9092 run_test 60j "llog_reader reports corruptions"
9093
9094 test_61a() {
9095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9096
9097         f="$DIR/f61"
9098         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9099         cancel_lru_locks osc
9100         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9101         sync
9102 }
9103 run_test 61a "mmap() writes don't make sync hang ================"
9104
9105 test_61b() {
9106         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9107 }
9108 run_test 61b "mmap() of unstriped file is successful"
9109
9110 # bug 2330 - insufficient obd_match error checking causes LBUG
9111 test_62() {
9112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9113
9114         f="$DIR/f62"
9115         echo foo > $f
9116         cancel_lru_locks osc
9117         lctl set_param fail_loc=0x405
9118         cat $f && error "cat succeeded, expect -EIO"
9119         lctl set_param fail_loc=0
9120 }
9121 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9122 # match every page all of the time.
9123 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9124
9125 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9126 # Though this test is irrelevant anymore, it helped to reveal some
9127 # other grant bugs (LU-4482), let's keep it.
9128 test_63a() {   # was test_63
9129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9130
9131         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9132
9133         for i in `seq 10` ; do
9134                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9135                 sleep 5
9136                 kill $!
9137                 sleep 1
9138         done
9139
9140         rm -f $DIR/f63 || true
9141 }
9142 run_test 63a "Verify oig_wait interruption does not crash ======="
9143
9144 # bug 2248 - async write errors didn't return to application on sync
9145 # bug 3677 - async write errors left page locked
9146 test_63b() {
9147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9148
9149         debugsave
9150         lctl set_param debug=-1
9151
9152         # ensure we have a grant to do async writes
9153         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9154         rm $DIR/$tfile
9155
9156         sync    # sync lest earlier test intercept the fail_loc
9157
9158         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9159         lctl set_param fail_loc=0x80000406
9160         $MULTIOP $DIR/$tfile Owy && \
9161                 error "sync didn't return ENOMEM"
9162         sync; sleep 2; sync     # do a real sync this time to flush page
9163         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9164                 error "locked page left in cache after async error" || true
9165         debugrestore
9166 }
9167 run_test 63b "async write errors should be returned to fsync ==="
9168
9169 test_64a () {
9170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9171
9172         lfs df $DIR
9173         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9174 }
9175 run_test 64a "verify filter grant calculations (in kernel) ====="
9176
9177 test_64b () {
9178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9179
9180         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9181 }
9182 run_test 64b "check out-of-space detection on client"
9183
9184 test_64c() {
9185         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9186 }
9187 run_test 64c "verify grant shrink"
9188
9189 import_param() {
9190         local tgt=$1
9191         local param=$2
9192
9193         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9194 }
9195
9196 # this does exactly what osc_request.c:osc_announce_cached() does in
9197 # order to calculate max amount of grants to ask from server
9198 want_grant() {
9199         local tgt=$1
9200
9201         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9202         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9203
9204         ((rpc_in_flight++));
9205         nrpages=$((nrpages * rpc_in_flight))
9206
9207         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9208
9209         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9210
9211         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9212         local undirty=$((nrpages * PAGE_SIZE))
9213
9214         local max_extent_pages
9215         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9216         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9217         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9218         local grant_extent_tax
9219         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9220
9221         undirty=$((undirty + nrextents * grant_extent_tax))
9222
9223         echo $undirty
9224 }
9225
9226 # this is size of unit for grant allocation. It should be equal to
9227 # what tgt_grant.c:tgt_grant_chunk() calculates
9228 grant_chunk() {
9229         local tgt=$1
9230         local max_brw_size
9231         local grant_extent_tax
9232
9233         max_brw_size=$(import_param $tgt max_brw_size)
9234
9235         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9236
9237         echo $(((max_brw_size + grant_extent_tax) * 2))
9238 }
9239
9240 test_64d() {
9241         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9242                 skip "OST < 2.10.55 doesn't limit grants enough"
9243
9244         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9245
9246         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9247                 skip "no grant_param connect flag"
9248
9249         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9250
9251         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9252         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9253
9254
9255         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9256         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9257
9258         $LFS setstripe $DIR/$tfile -i 0 -c 1
9259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9260         ddpid=$!
9261
9262         while kill -0 $ddpid; do
9263                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9264
9265                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9266                         kill $ddpid
9267                         error "cur_grant $cur_grant > $max_cur_granted"
9268                 fi
9269
9270                 sleep 1
9271         done
9272 }
9273 run_test 64d "check grant limit exceed"
9274
9275 check_grants() {
9276         local tgt=$1
9277         local expected=$2
9278         local msg=$3
9279         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9280
9281         ((cur_grants == expected)) ||
9282                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9283 }
9284
9285 round_up_p2() {
9286         echo $((($1 + $2 - 1) & ~($2 - 1)))
9287 }
9288
9289 test_64e() {
9290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9291         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9292                 skip "Need OSS version at least 2.11.56"
9293
9294         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9295         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9296         $LCTL set_param debug=+cache
9297
9298         # Remount client to reset grant
9299         remount_client $MOUNT || error "failed to remount client"
9300         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9301
9302         local init_grants=$(import_param $osc_tgt initial_grant)
9303
9304         check_grants $osc_tgt $init_grants "init grants"
9305
9306         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9307         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9308         local gbs=$(import_param $osc_tgt grant_block_size)
9309
9310         # write random number of bytes from max_brw_size / 4 to max_brw_size
9311         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9312         # align for direct io
9313         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9314         # round to grant consumption unit
9315         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9316
9317         local grants=$((wb_round_up + extent_tax))
9318
9319         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9320
9321         # define OBD_FAIL_TGT_NO_GRANT 0x725
9322         # make the server not grant more back
9323         do_facet ost1 $LCTL set_param fail_loc=0x725
9324         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9325
9326         do_facet ost1 $LCTL set_param fail_loc=0
9327
9328         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9329
9330         rm -f $DIR/$tfile || error "rm failed"
9331
9332         # Remount client to reset grant
9333         remount_client $MOUNT || error "failed to remount client"
9334         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9335
9336         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9337
9338         # define OBD_FAIL_TGT_NO_GRANT 0x725
9339         # make the server not grant more back
9340         do_facet ost1 $LCTL set_param fail_loc=0x725
9341         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9342         do_facet ost1 $LCTL set_param fail_loc=0
9343
9344         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9345 }
9346 run_test 64e "check grant consumption (no grant allocation)"
9347
9348 test_64f() {
9349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9350
9351         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9352         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9353         $LCTL set_param debug=+cache
9354
9355         # Remount client to reset grant
9356         remount_client $MOUNT || error "failed to remount client"
9357         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9358
9359         local init_grants=$(import_param $osc_tgt initial_grant)
9360         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9361         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9362         local gbs=$(import_param $osc_tgt grant_block_size)
9363         local chunk=$(grant_chunk $osc_tgt)
9364
9365         # write random number of bytes from max_brw_size / 4 to max_brw_size
9366         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9367         # align for direct io
9368         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9369         # round to grant consumption unit
9370         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9371
9372         local grants=$((wb_round_up + extent_tax))
9373
9374         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9375         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9376                 error "error writing to $DIR/$tfile"
9377
9378         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9379                 "direct io with grant allocation"
9380
9381         rm -f $DIR/$tfile || error "rm failed"
9382
9383         # Remount client to reset grant
9384         remount_client $MOUNT || error "failed to remount client"
9385         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9386
9387         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9388
9389         local cmd="oO_WRONLY:w${write_bytes}_yc"
9390
9391         $MULTIOP $DIR/$tfile $cmd &
9392         MULTIPID=$!
9393         sleep 1
9394
9395         check_grants $osc_tgt $((init_grants - grants)) \
9396                 "buffered io, not write rpc"
9397
9398         kill -USR1 $MULTIPID
9399         wait
9400
9401         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9402                 "buffered io, one RPC"
9403 }
9404 run_test 64f "check grant consumption (with grant allocation)"
9405
9406 test_64g() {
9407         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9408                 skip "Need MDS version at least 2.14.56"
9409
9410         local mdts=$(comma_list $(mdts_nodes))
9411
9412         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9413                         tr '\n' ' ')
9414         stack_trap "$LCTL set_param $old"
9415
9416         # generate dirty pages and increase dirty granted on MDT
9417         stack_trap "rm -f $DIR/$tfile-*"
9418         for (( i = 0; i < 10; i++)); do
9419                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9420                         error "can't set stripe"
9421                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9422                         error "can't dd"
9423                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9424                         $LFS getstripe $DIR/$tfile-$i
9425                         error "not DoM file"
9426                 }
9427         done
9428
9429         # flush dirty pages
9430         sync
9431
9432         # wait until grant shrink reset grant dirty on MDTs
9433         for ((i = 0; i < 120; i++)); do
9434                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9435                         awk '{sum=sum+$1} END {print sum}')
9436                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9437                 echo "$grant_dirty grants, $vm_dirty pages"
9438                 (( grant_dirty + vm_dirty == 0 )) && break
9439                 (( i == 3 )) && sync &&
9440                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9441                 sleep 1
9442         done
9443
9444         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9445                 awk '{sum=sum+$1} END {print sum}')
9446         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9447 }
9448 run_test 64g "grant shrink on MDT"
9449
9450 test_64h() {
9451         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9452                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9453
9454         local instance=$($LFS getname -i $DIR)
9455         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9456         local num_exps=$(do_facet ost1 \
9457             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9458         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9459         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9460         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9461
9462         # 10MiB is for file to be written, max_brw_size * 16 *
9463         # num_exps is space reserve so that tgt_grant_shrink() decided
9464         # to not shrink
9465         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9466         (( avail * 1024 < expect )) &&
9467                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9468
9469         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9470         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9471         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9472         $LCTL set_param osc.*OST0000*.grant_shrink=1
9473         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9474
9475         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9476         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9477
9478         # drop cache so that coming read would do rpc
9479         cancel_lru_locks osc
9480
9481         # shrink interval is set to 10, pause for 7 seconds so that
9482         # grant thread did not wake up yet but coming read entered
9483         # shrink mode for rpc (osc_should_shrink_grant())
9484         sleep 7
9485
9486         declare -a cur_grant_bytes
9487         declare -a tot_granted
9488         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9489         tot_granted[0]=$(do_facet ost1 \
9490             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9491
9492         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9493
9494         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9495         tot_granted[1]=$(do_facet ost1 \
9496             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9497
9498         # grant change should be equal on both sides
9499         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9500                 tot_granted[0] - tot_granted[1])) ||
9501                 error "grant change mismatch, "                                \
9502                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9503                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9504 }
9505 run_test 64h "grant shrink on read"
9506
9507 test_64i() {
9508         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9509                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9510
9511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9512         remote_ost_nodsh && skip "remote OSTs with nodsh"
9513
9514         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9515
9516         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9517
9518         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9519         local instance=$($LFS getname -i $DIR)
9520
9521         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9522         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9523
9524         # shrink grants and simulate rpc loss
9525         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9526         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9527         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9528
9529         fail ost1
9530
9531         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9532
9533         local testid=$(echo $TESTNAME | tr '_' ' ')
9534
9535         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9536                 grep "GRANT, real grant" &&
9537                 error "client has more grants then it owns" || true
9538 }
9539 run_test 64i "shrink on reconnect"
9540
9541 # bug 1414 - set/get directories' stripe info
9542 test_65a() {
9543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9544
9545         test_mkdir $DIR/$tdir
9546         touch $DIR/$tdir/f1
9547         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9548 }
9549 run_test 65a "directory with no stripe info"
9550
9551 test_65b() {
9552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9553
9554         test_mkdir $DIR/$tdir
9555         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9556
9557         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9558                                                 error "setstripe"
9559         touch $DIR/$tdir/f2
9560         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9561 }
9562 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9563
9564 test_65c() {
9565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9566         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9567
9568         test_mkdir $DIR/$tdir
9569         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9570
9571         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9572                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9573         touch $DIR/$tdir/f3
9574         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9575 }
9576 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9577
9578 test_65d() {
9579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9580
9581         test_mkdir $DIR/$tdir
9582         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9583         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9584
9585         if [[ $STRIPECOUNT -le 0 ]]; then
9586                 sc=1
9587         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9588                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9589                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9590         else
9591                 sc=$(($STRIPECOUNT - 1))
9592         fi
9593         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9594         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9595         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9596                 error "lverify failed"
9597 }
9598 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9599
9600 test_65e() {
9601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9602
9603         test_mkdir $DIR/$tdir
9604
9605         $LFS setstripe $DIR/$tdir || error "setstripe"
9606         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9607                                         error "no stripe info failed"
9608         touch $DIR/$tdir/f6
9609         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9610 }
9611 run_test 65e "directory setstripe defaults"
9612
9613 test_65f() {
9614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9615
9616         test_mkdir $DIR/${tdir}f
9617         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9618                 error "setstripe succeeded" || true
9619 }
9620 run_test 65f "dir setstripe permission (should return error) ==="
9621
9622 test_65g() {
9623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9624
9625         test_mkdir $DIR/$tdir
9626         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9627
9628         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9629                 error "setstripe -S failed"
9630         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9631         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9632                 error "delete default stripe failed"
9633 }
9634 run_test 65g "directory setstripe -d"
9635
9636 test_65h() {
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638
9639         test_mkdir $DIR/$tdir
9640         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9641
9642         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9643                 error "setstripe -S failed"
9644         test_mkdir $DIR/$tdir/dd1
9645         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9646                 error "stripe info inherit failed"
9647 }
9648 run_test 65h "directory stripe info inherit ===================="
9649
9650 test_65i() {
9651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9652
9653         save_layout_restore_at_exit $MOUNT
9654
9655         # bug6367: set non-default striping on root directory
9656         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9657
9658         # bug12836: getstripe on -1 default directory striping
9659         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9660
9661         # bug12836: getstripe -v on -1 default directory striping
9662         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9663
9664         # bug12836: new find on -1 default directory striping
9665         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9666 }
9667 run_test 65i "various tests to set root directory striping"
9668
9669 test_65j() { # bug6367
9670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9671
9672         sync; sleep 1
9673
9674         # if we aren't already remounting for each test, do so for this test
9675         if [ "$I_MOUNTED" = "yes" ]; then
9676                 cleanup || error "failed to unmount"
9677                 setup
9678         fi
9679
9680         save_layout_restore_at_exit $MOUNT
9681
9682         $LFS setstripe -d $MOUNT || error "setstripe failed"
9683 }
9684 run_test 65j "set default striping on root directory (bug 6367)="
9685
9686 cleanup_65k() {
9687         rm -rf $DIR/$tdir
9688         wait_delete_completed
9689         do_facet $SINGLEMDS "lctl set_param -n \
9690                 osp.$ost*MDT0000.max_create_count=$max_count"
9691         do_facet $SINGLEMDS "lctl set_param -n \
9692                 osp.$ost*MDT0000.create_count=$count"
9693         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9694         echo $INACTIVE_OSC "is Activate"
9695
9696         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9697 }
9698
9699 test_65k() { # bug11679
9700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9701         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9702         remote_mds_nodsh && skip "remote MDS with nodsh"
9703
9704         local disable_precreate=true
9705         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9706                 disable_precreate=false
9707
9708         echo "Check OST status: "
9709         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9710                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9711
9712         for OSC in $MDS_OSCS; do
9713                 echo $OSC "is active"
9714                 do_facet $SINGLEMDS lctl --device %$OSC activate
9715         done
9716
9717         for INACTIVE_OSC in $MDS_OSCS; do
9718                 local ost=$(osc_to_ost $INACTIVE_OSC)
9719                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9720                                lov.*md*.target_obd |
9721                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9722
9723                 mkdir -p $DIR/$tdir
9724                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9725                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9726
9727                 echo "Deactivate: " $INACTIVE_OSC
9728                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9729
9730                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9731                               osp.$ost*MDT0000.create_count")
9732                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9733                                   osp.$ost*MDT0000.max_create_count")
9734                 $disable_precreate &&
9735                         do_facet $SINGLEMDS "lctl set_param -n \
9736                                 osp.$ost*MDT0000.max_create_count=0"
9737
9738                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9739                         [ -f $DIR/$tdir/$idx ] && continue
9740                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9741                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9742                                 { cleanup_65k;
9743                                   error "setstripe $idx should succeed"; }
9744                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9745                 done
9746                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9747                 rmdir $DIR/$tdir
9748
9749                 do_facet $SINGLEMDS "lctl set_param -n \
9750                         osp.$ost*MDT0000.max_create_count=$max_count"
9751                 do_facet $SINGLEMDS "lctl set_param -n \
9752                         osp.$ost*MDT0000.create_count=$count"
9753                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9754                 echo $INACTIVE_OSC "is Activate"
9755
9756                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9757         done
9758 }
9759 run_test 65k "validate manual striping works properly with deactivated OSCs"
9760
9761 test_65l() { # bug 12836
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         test_mkdir -p $DIR/$tdir/test_dir
9765         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9766         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9767 }
9768 run_test 65l "lfs find on -1 stripe dir ========================"
9769
9770 test_65m() {
9771         local layout=$(save_layout $MOUNT)
9772         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9773                 restore_layout $MOUNT $layout
9774                 error "setstripe should fail by non-root users"
9775         }
9776         true
9777 }
9778 run_test 65m "normal user can't set filesystem default stripe"
9779
9780 test_65n() {
9781         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9782         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9783                 skip "Need MDS version at least 2.12.50"
9784         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9785
9786         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9787         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9788         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9789
9790         save_layout_restore_at_exit $MOUNT
9791
9792         # new subdirectory under root directory should not inherit
9793         # the default layout from root
9794         local dir1=$MOUNT/$tdir-1
9795         mkdir $dir1 || error "mkdir $dir1 failed"
9796         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9797                 error "$dir1 shouldn't have LOV EA"
9798
9799         # delete the default layout on root directory
9800         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9801
9802         local dir2=$MOUNT/$tdir-2
9803         mkdir $dir2 || error "mkdir $dir2 failed"
9804         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9805                 error "$dir2 shouldn't have LOV EA"
9806
9807         # set a new striping pattern on root directory
9808         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9809         local new_def_stripe_size=$((def_stripe_size * 2))
9810         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9811                 error "set stripe size on $MOUNT failed"
9812
9813         # new file created in $dir2 should inherit the new stripe size from
9814         # the filesystem default
9815         local file2=$dir2/$tfile-2
9816         touch $file2 || error "touch $file2 failed"
9817
9818         local file2_stripe_size=$($LFS getstripe -S $file2)
9819         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9820         {
9821                 echo "file2_stripe_size: '$file2_stripe_size'"
9822                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9823                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9824         }
9825
9826         local dir3=$MOUNT/$tdir-3
9827         mkdir $dir3 || error "mkdir $dir3 failed"
9828         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9829         # the root layout, which is the actual default layout that will be used
9830         # when new files are created in $dir3.
9831         local dir3_layout=$(get_layout_param $dir3)
9832         local root_dir_layout=$(get_layout_param $MOUNT)
9833         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9834         {
9835                 echo "dir3_layout: '$dir3_layout'"
9836                 echo "root_dir_layout: '$root_dir_layout'"
9837                 error "$dir3 should show the default layout from $MOUNT"
9838         }
9839
9840         # set OST pool on root directory
9841         local pool=$TESTNAME
9842         pool_add $pool || error "add $pool failed"
9843         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9844                 error "add targets to $pool failed"
9845
9846         $LFS setstripe -p $pool $MOUNT ||
9847                 error "set OST pool on $MOUNT failed"
9848
9849         # new file created in $dir3 should inherit the pool from
9850         # the filesystem default
9851         local file3=$dir3/$tfile-3
9852         touch $file3 || error "touch $file3 failed"
9853
9854         local file3_pool=$($LFS getstripe -p $file3)
9855         [[ "$file3_pool" = "$pool" ]] ||
9856                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9857
9858         local dir4=$MOUNT/$tdir-4
9859         mkdir $dir4 || error "mkdir $dir4 failed"
9860         local dir4_layout=$(get_layout_param $dir4)
9861         root_dir_layout=$(get_layout_param $MOUNT)
9862         echo "$LFS getstripe -d $dir4"
9863         $LFS getstripe -d $dir4
9864         echo "$LFS getstripe -d $MOUNT"
9865         $LFS getstripe -d $MOUNT
9866         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9867         {
9868                 echo "dir4_layout: '$dir4_layout'"
9869                 echo "root_dir_layout: '$root_dir_layout'"
9870                 error "$dir4 should show the default layout from $MOUNT"
9871         }
9872
9873         # new file created in $dir4 should inherit the pool from
9874         # the filesystem default
9875         local file4=$dir4/$tfile-4
9876         touch $file4 || error "touch $file4 failed"
9877
9878         local file4_pool=$($LFS getstripe -p $file4)
9879         [[ "$file4_pool" = "$pool" ]] ||
9880                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9881
9882         # new subdirectory under non-root directory should inherit
9883         # the default layout from its parent directory
9884         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9885                 error "set directory layout on $dir4 failed"
9886
9887         local dir5=$dir4/$tdir-5
9888         mkdir $dir5 || error "mkdir $dir5 failed"
9889
9890         dir4_layout=$(get_layout_param $dir4)
9891         local dir5_layout=$(get_layout_param $dir5)
9892         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9893         {
9894                 echo "dir4_layout: '$dir4_layout'"
9895                 echo "dir5_layout: '$dir5_layout'"
9896                 error "$dir5 should inherit the default layout from $dir4"
9897         }
9898
9899         # though subdir under ROOT doesn't inherit default layout, but
9900         # its sub dir/file should be created with default layout.
9901         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9902         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9903                 skip "Need MDS version at least 2.12.59"
9904
9905         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9906         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9907         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9908
9909         if [ $default_lmv_hash == "none" ]; then
9910                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9911         else
9912                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9913                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9914         fi
9915
9916         $LFS setdirstripe -D -c 2 $MOUNT ||
9917                 error "setdirstripe -D -c 2 failed"
9918         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9919         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9920         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9921
9922         # $dir4 layout includes pool
9923         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9924         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9925                 error "pool lost on setstripe"
9926         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9927         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9928                 error "pool lost on compound layout setstripe"
9929 }
9930 run_test 65n "don't inherit default layout from root for new subdirectories"
9931
9932 test_65o() {
9933         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9934                 skip "need MDS version at least 2.14.57"
9935
9936         # set OST pool on root directory
9937         local pool=$TESTNAME
9938
9939         pool_add $pool || error "add $pool failed"
9940         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9941                 error "add targets to $pool failed"
9942
9943         local dir1=$MOUNT/$tdir
9944
9945         mkdir $dir1 || error "mkdir $dir1 failed"
9946
9947         # set a new striping pattern on root directory
9948         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9949
9950         $LFS setstripe -p $pool $dir1 ||
9951                 error "set directory layout on $dir1 failed"
9952
9953         # $dir1 layout includes pool
9954         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9955         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9956                 error "pool lost on setstripe"
9957         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9958         $LFS getstripe $dir1
9959         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9960                 error "pool lost on compound layout setstripe"
9961
9962         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9963                 error "setdirstripe failed on sub-dir with inherited pool"
9964         $LFS getstripe $dir1/dir2
9965         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9966                 error "pool lost on compound layout setdirstripe"
9967
9968         $LFS setstripe -E -1 -c 1 $dir1
9969         $LFS getstripe -d $dir1
9970         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9971                 error "pool lost on setstripe"
9972 }
9973 run_test 65o "pool inheritance for mdt component"
9974
9975 test_65p () { # LU-16152
9976         local src_dir=$DIR/$tdir/src_dir
9977         local dst_dir=$DIR/$tdir/dst_dir
9978         local yaml_file=$DIR/$tdir/layout.yaml
9979         local border
9980
9981         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9982                 skip "Need at least version 2.15.51"
9983
9984         test_mkdir -p $src_dir
9985         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9986                 error "failed to setstripe"
9987         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9988                 error "failed to getstripe"
9989
9990         test_mkdir -p $dst_dir
9991         $LFS setstripe --yaml $yaml_file $dst_dir ||
9992                 error "failed to setstripe with yaml file"
9993         border=$($LFS getstripe -d $dst_dir |
9994                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9995                 error "failed to getstripe"
9996
9997         # 2048M is 0x80000000, or 2147483648
9998         (( $border == 2147483648 )) ||
9999                 error "failed to handle huge number in yaml layout"
10000 }
10001 run_test 65p "setstripe with yaml file and huge number"
10002
10003 # bug 2543 - update blocks count on client
10004 test_66() {
10005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10006
10007         local COUNT=${COUNT:-8}
10008         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10009         sync; sync_all_data; sync; sync_all_data
10010         cancel_lru_locks osc
10011         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10012         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10013 }
10014 run_test 66 "update inode blocks count on client ==============="
10015
10016 meminfo() {
10017         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10018 }
10019
10020 swap_used() {
10021         swapon -s | awk '($1 == "'$1'") { print $4 }'
10022 }
10023
10024 # bug5265, obdfilter oa2dentry return -ENOENT
10025 # #define OBD_FAIL_SRV_ENOENT 0x217
10026 test_69() {
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028         remote_ost_nodsh && skip "remote OST with nodsh"
10029
10030         f="$DIR/$tfile"
10031         $LFS setstripe -c 1 -i 0 $f
10032
10033         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10034
10035         do_facet ost1 lctl set_param fail_loc=0x217
10036         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10037         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10038
10039         do_facet ost1 lctl set_param fail_loc=0
10040         $DIRECTIO write $f 0 2 || error "write error"
10041
10042         cancel_lru_locks osc
10043         $DIRECTIO read $f 0 1 || error "read error"
10044
10045         do_facet ost1 lctl set_param fail_loc=0x217
10046         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10047
10048         do_facet ost1 lctl set_param fail_loc=0
10049         rm -f $f
10050 }
10051 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10052
10053 test_71() {
10054         test_mkdir $DIR/$tdir
10055         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10056         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10057 }
10058 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10059
10060 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10062         [ "$RUNAS_ID" = "$UID" ] &&
10063                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10064         # Check that testing environment is properly set up. Skip if not
10065         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10066                 skip_env "User $RUNAS_ID does not exist - skipping"
10067
10068         touch $DIR/$tfile
10069         chmod 777 $DIR/$tfile
10070         chmod ug+s $DIR/$tfile
10071         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10072                 error "$RUNAS dd $DIR/$tfile failed"
10073         # See if we are still setuid/sgid
10074         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10075                 error "S/gid is not dropped on write"
10076         # Now test that MDS is updated too
10077         cancel_lru_locks mdc
10078         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10079                 error "S/gid is not dropped on MDS"
10080         rm -f $DIR/$tfile
10081 }
10082 run_test 72a "Test that remove suid works properly (bug5695) ===="
10083
10084 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10085         local perm
10086
10087         [ "$RUNAS_ID" = "$UID" ] &&
10088                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10089         [ "$RUNAS_ID" -eq 0 ] &&
10090                 skip_env "RUNAS_ID = 0 -- skipping"
10091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10092         # Check that testing environment is properly set up. Skip if not
10093         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10094                 skip_env "User $RUNAS_ID does not exist - skipping"
10095
10096         touch $DIR/${tfile}-f{g,u}
10097         test_mkdir $DIR/${tfile}-dg
10098         test_mkdir $DIR/${tfile}-du
10099         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10100         chmod g+s $DIR/${tfile}-{f,d}g
10101         chmod u+s $DIR/${tfile}-{f,d}u
10102         for perm in 777 2777 4777; do
10103                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10104                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10105                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10106                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10107         done
10108         true
10109 }
10110 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10111
10112 # bug 3462 - multiple simultaneous MDC requests
10113 test_73() {
10114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10115
10116         test_mkdir $DIR/d73-1
10117         test_mkdir $DIR/d73-2
10118         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10119         pid1=$!
10120
10121         lctl set_param fail_loc=0x80000129
10122         $MULTIOP $DIR/d73-1/f73-2 Oc &
10123         sleep 1
10124         lctl set_param fail_loc=0
10125
10126         $MULTIOP $DIR/d73-2/f73-3 Oc &
10127         pid3=$!
10128
10129         kill -USR1 $pid1
10130         wait $pid1 || return 1
10131
10132         sleep 25
10133
10134         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10135         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10136         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10137
10138         rm -rf $DIR/d73-*
10139 }
10140 run_test 73 "multiple MDC requests (should not deadlock)"
10141
10142 test_74a() { # bug 6149, 6184
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144
10145         touch $DIR/f74a
10146         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10147         #
10148         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10149         # will spin in a tight reconnection loop
10150         $LCTL set_param fail_loc=0x8000030e
10151         # get any lock that won't be difficult - lookup works.
10152         ls $DIR/f74a
10153         $LCTL set_param fail_loc=0
10154         rm -f $DIR/f74a
10155         true
10156 }
10157 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10158
10159 test_74b() { # bug 13310
10160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10161
10162         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10163         #
10164         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10165         # will spin in a tight reconnection loop
10166         $LCTL set_param fail_loc=0x8000030e
10167         # get a "difficult" lock
10168         touch $DIR/f74b
10169         $LCTL set_param fail_loc=0
10170         rm -f $DIR/f74b
10171         true
10172 }
10173 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10174
10175 test_74c() {
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177
10178         #define OBD_FAIL_LDLM_NEW_LOCK
10179         $LCTL set_param fail_loc=0x319
10180         touch $DIR/$tfile && error "touch successful"
10181         $LCTL set_param fail_loc=0
10182         true
10183 }
10184 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10185
10186 slab_lic=/sys/kernel/slab/lustre_inode_cache
10187 num_objects() {
10188         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10189         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10190                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10191 }
10192
10193 test_76a() { # Now for b=20433, added originally in b=1443
10194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10195
10196         cancel_lru_locks osc
10197         # there may be some slab objects cached per core
10198         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10199         local before=$(num_objects)
10200         local count=$((512 * cpus))
10201         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10202         local margin=$((count / 10))
10203         if [[ -f $slab_lic/aliases ]]; then
10204                 local aliases=$(cat $slab_lic/aliases)
10205                 (( aliases > 0 )) && margin=$((margin * aliases))
10206         fi
10207
10208         echo "before slab objects: $before"
10209         for i in $(seq $count); do
10210                 touch $DIR/$tfile
10211                 rm -f $DIR/$tfile
10212         done
10213         cancel_lru_locks osc
10214         local after=$(num_objects)
10215         echo "created: $count, after slab objects: $after"
10216         # shared slab counts are not very accurate, allow significant margin
10217         # the main goal is that the cache growth is not permanently > $count
10218         while (( after > before + margin )); do
10219                 sleep 1
10220                 after=$(num_objects)
10221                 wait=$((wait + 1))
10222                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10223                 if (( wait > 60 )); then
10224                         error "inode slab grew from $before+$margin to $after"
10225                 fi
10226         done
10227 }
10228 run_test 76a "confirm clients recycle inodes properly ===="
10229
10230 test_76b() {
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10233
10234         local count=512
10235         local before=$(num_objects)
10236
10237         for i in $(seq $count); do
10238                 mkdir $DIR/$tdir
10239                 rmdir $DIR/$tdir
10240         done
10241
10242         local after=$(num_objects)
10243         local wait=0
10244
10245         while (( after > before )); do
10246                 sleep 1
10247                 after=$(num_objects)
10248                 wait=$((wait + 1))
10249                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10250                 if (( wait > 60 )); then
10251                         error "inode slab grew from $before to $after"
10252                 fi
10253         done
10254
10255         echo "slab objects before: $before, after: $after"
10256 }
10257 run_test 76b "confirm clients recycle directory inodes properly ===="
10258
10259 export ORIG_CSUM=""
10260 set_checksums()
10261 {
10262         # Note: in sptlrpc modes which enable its own bulk checksum, the
10263         # original crc32_le bulk checksum will be automatically disabled,
10264         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10265         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10266         # In this case set_checksums() will not be no-op, because sptlrpc
10267         # bulk checksum will be enabled all through the test.
10268
10269         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10270         lctl set_param -n osc.*.checksums $1
10271         return 0
10272 }
10273
10274 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10275                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10276 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10277                              tr -d [] | head -n1)}
10278 set_checksum_type()
10279 {
10280         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10281         rc=$?
10282         log "set checksum type to $1, rc = $rc"
10283         return $rc
10284 }
10285
10286 get_osc_checksum_type()
10287 {
10288         # arugment 1: OST name, like OST0000
10289         ost=$1
10290         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10291                         sed 's/.*\[\(.*\)\].*/\1/g')
10292         rc=$?
10293         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10294         echo $checksum_type
10295 }
10296
10297 F77_TMP=$TMP/f77-temp
10298 F77SZ=8
10299 setup_f77() {
10300         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10301                 error "error writing to $F77_TMP"
10302 }
10303
10304 test_77a() { # bug 10889
10305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10306         $GSS && skip_env "could not run with gss"
10307
10308         [ ! -f $F77_TMP ] && setup_f77
10309         set_checksums 1
10310         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10311         set_checksums 0
10312         rm -f $DIR/$tfile
10313 }
10314 run_test 77a "normal checksum read/write operation"
10315
10316 test_77b() { # bug 10889
10317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10318         $GSS && skip_env "could not run with gss"
10319
10320         [ ! -f $F77_TMP ] && setup_f77
10321         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10322         $LCTL set_param fail_loc=0x80000409
10323         set_checksums 1
10324
10325         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10326                 error "dd error: $?"
10327         $LCTL set_param fail_loc=0
10328
10329         for algo in $CKSUM_TYPES; do
10330                 cancel_lru_locks osc
10331                 set_checksum_type $algo
10332                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10333                 $LCTL set_param fail_loc=0x80000408
10334                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10335                 $LCTL set_param fail_loc=0
10336         done
10337         set_checksums 0
10338         set_checksum_type $ORIG_CSUM_TYPE
10339         rm -f $DIR/$tfile
10340 }
10341 run_test 77b "checksum error on client write, read"
10342
10343 cleanup_77c() {
10344         trap 0
10345         set_checksums 0
10346         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10347         $check_ost &&
10348                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10349         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10350         $check_ost && [ -n "$ost_file_prefix" ] &&
10351                 do_facet ost1 rm -f ${ost_file_prefix}\*
10352 }
10353
10354 test_77c() {
10355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10356         $GSS && skip_env "could not run with gss"
10357         remote_ost_nodsh && skip "remote OST with nodsh"
10358
10359         local bad1
10360         local osc_file_prefix
10361         local osc_file
10362         local check_ost=false
10363         local ost_file_prefix
10364         local ost_file
10365         local orig_cksum
10366         local dump_cksum
10367         local fid
10368
10369         # ensure corruption will occur on first OSS/OST
10370         $LFS setstripe -i 0 $DIR/$tfile
10371
10372         [ ! -f $F77_TMP ] && setup_f77
10373         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10374                 error "dd write error: $?"
10375         fid=$($LFS path2fid $DIR/$tfile)
10376
10377         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10378         then
10379                 check_ost=true
10380                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10381                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10382         else
10383                 echo "OSS do not support bulk pages dump upon error"
10384         fi
10385
10386         osc_file_prefix=$($LCTL get_param -n debug_path)
10387         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10388
10389         trap cleanup_77c EXIT
10390
10391         set_checksums 1
10392         # enable bulk pages dump upon error on Client
10393         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10394         # enable bulk pages dump upon error on OSS
10395         $check_ost &&
10396                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10397
10398         # flush Client cache to allow next read to reach OSS
10399         cancel_lru_locks osc
10400
10401         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10402         $LCTL set_param fail_loc=0x80000408
10403         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10404         $LCTL set_param fail_loc=0
10405
10406         rm -f $DIR/$tfile
10407
10408         # check cksum dump on Client
10409         osc_file=$(ls ${osc_file_prefix}*)
10410         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10411         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10412         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10413         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10414         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10415                      cksum)
10416         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10417         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10418                 error "dump content does not match on Client"
10419
10420         $check_ost || skip "No need to check cksum dump on OSS"
10421
10422         # check cksum dump on OSS
10423         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10424         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10425         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10426         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10427         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10428                 error "dump content does not match on OSS"
10429
10430         cleanup_77c
10431 }
10432 run_test 77c "checksum error on client read with debug"
10433
10434 test_77d() { # bug 10889
10435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10436         $GSS && skip_env "could not run with gss"
10437
10438         stack_trap "rm -f $DIR/$tfile"
10439         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10440         $LCTL set_param fail_loc=0x80000409
10441         set_checksums 1
10442         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10443                 error "direct write: rc=$?"
10444         $LCTL set_param fail_loc=0
10445         set_checksums 0
10446
10447         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10448         $LCTL set_param fail_loc=0x80000408
10449         set_checksums 1
10450         cancel_lru_locks osc
10451         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10452                 error "direct read: rc=$?"
10453         $LCTL set_param fail_loc=0
10454         set_checksums 0
10455 }
10456 run_test 77d "checksum error on OST direct write, read"
10457
10458 test_77f() { # bug 10889
10459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10460         $GSS && skip_env "could not run with gss"
10461
10462         set_checksums 1
10463         stack_trap "rm -f $DIR/$tfile"
10464         for algo in $CKSUM_TYPES; do
10465                 cancel_lru_locks osc
10466                 set_checksum_type $algo
10467                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10468                 $LCTL set_param fail_loc=0x409
10469                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10470                         error "direct write succeeded"
10471                 $LCTL set_param fail_loc=0
10472         done
10473         set_checksum_type $ORIG_CSUM_TYPE
10474         set_checksums 0
10475 }
10476 run_test 77f "repeat checksum error on write (expect error)"
10477
10478 test_77g() { # bug 10889
10479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10480         $GSS && skip_env "could not run with gss"
10481         remote_ost_nodsh && skip "remote OST with nodsh"
10482
10483         [ ! -f $F77_TMP ] && setup_f77
10484
10485         local file=$DIR/$tfile
10486         stack_trap "rm -f $file" EXIT
10487
10488         $LFS setstripe -c 1 -i 0 $file
10489         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10490         do_facet ost1 lctl set_param fail_loc=0x8000021a
10491         set_checksums 1
10492         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10493                 error "write error: rc=$?"
10494         do_facet ost1 lctl set_param fail_loc=0
10495         set_checksums 0
10496
10497         cancel_lru_locks osc
10498         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10499         do_facet ost1 lctl set_param fail_loc=0x8000021b
10500         set_checksums 1
10501         cmp $F77_TMP $file || error "file compare failed"
10502         do_facet ost1 lctl set_param fail_loc=0
10503         set_checksums 0
10504 }
10505 run_test 77g "checksum error on OST write, read"
10506
10507 test_77k() { # LU-10906
10508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10509         $GSS && skip_env "could not run with gss"
10510
10511         local cksum_param="osc.$FSNAME*.checksums"
10512         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10513         local checksum
10514         local i
10515
10516         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10517         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10518         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10519
10520         for i in 0 1; do
10521                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10522                         error "failed to set checksum=$i on MGS"
10523                 wait_update $HOSTNAME "$get_checksum" $i
10524                 #remount
10525                 echo "remount client, checksum should be $i"
10526                 remount_client $MOUNT || error "failed to remount client"
10527                 checksum=$(eval $get_checksum)
10528                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10529         done
10530         # remove persistent param to avoid races with checksum mountopt below
10531         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10532                 error "failed to delete checksum on MGS"
10533
10534         for opt in "checksum" "nochecksum"; do
10535                 #remount with mount option
10536                 echo "remount client with option $opt, checksum should be $i"
10537                 umount_client $MOUNT || error "failed to umount client"
10538                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10539                         error "failed to mount client with option '$opt'"
10540                 checksum=$(eval $get_checksum)
10541                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10542                 i=$((i - 1))
10543         done
10544
10545         remount_client $MOUNT || error "failed to remount client"
10546 }
10547 run_test 77k "enable/disable checksum correctly"
10548
10549 test_77l() {
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551         $GSS && skip_env "could not run with gss"
10552
10553         set_checksums 1
10554         stack_trap "set_checksums $ORIG_CSUM" EXIT
10555         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10556
10557         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10558
10559         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10560         for algo in $CKSUM_TYPES; do
10561                 set_checksum_type $algo || error "fail to set checksum type $algo"
10562                 osc_algo=$(get_osc_checksum_type OST0000)
10563                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10564
10565                 # no locks, no reqs to let the connection idle
10566                 cancel_lru_locks osc
10567                 lru_resize_disable osc
10568                 wait_osc_import_state client ost1 IDLE
10569
10570                 # ensure ost1 is connected
10571                 stat $DIR/$tfile >/dev/null || error "can't stat"
10572                 wait_osc_import_state client ost1 FULL
10573
10574                 osc_algo=$(get_osc_checksum_type OST0000)
10575                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10576         done
10577         return 0
10578 }
10579 run_test 77l "preferred checksum type is remembered after reconnected"
10580
10581 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10582 rm -f $F77_TMP
10583 unset F77_TMP
10584
10585 test_77m() {
10586         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10587                 skip "Need at least version 2.14.52"
10588         local param=checksum_speed
10589
10590         $LCTL get_param $param || error "reading $param failed"
10591
10592         csum_speeds=$($LCTL get_param -n $param)
10593
10594         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10595                 error "known checksum types are missing"
10596 }
10597 run_test 77m "Verify checksum_speed is correctly read"
10598
10599 check_filefrag_77n() {
10600         local nr_ext=0
10601         local starts=()
10602         local ends=()
10603
10604         while read extidx a b start end rest; do
10605                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10606                         nr_ext=$(( $nr_ext + 1 ))
10607                         starts+=( ${start%..} )
10608                         ends+=( ${end%:} )
10609                 fi
10610         done < <( filefrag -sv $1 )
10611
10612         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10613         return 1
10614 }
10615
10616 test_77n() {
10617         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10618
10619         touch $DIR/$tfile
10620         $TRUNCATE $DIR/$tfile 0
10621         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10622         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10623         check_filefrag_77n $DIR/$tfile ||
10624                 skip "$tfile blocks not contiguous around hole"
10625
10626         set_checksums 1
10627         stack_trap "set_checksums $ORIG_CSUM" EXIT
10628         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10629         stack_trap "rm -f $DIR/$tfile"
10630
10631         for algo in $CKSUM_TYPES; do
10632                 if [[ "$algo" =~ ^t10 ]]; then
10633                         set_checksum_type $algo ||
10634                                 error "fail to set checksum type $algo"
10635                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10636                                 error "fail to read $tfile with $algo"
10637                 fi
10638         done
10639         rm -f $DIR/$tfile
10640         return 0
10641 }
10642 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10643
10644 test_77o() {
10645         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10646                 skip "Need MDS version at least 2.14.55"
10647         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10648                 skip "Need OST version at least 2.14.55"
10649         local ofd=obdfilter
10650         local mdt=mdt
10651
10652         # print OST checksum_type
10653         echo "$ofd.$FSNAME-*.checksum_type:"
10654         do_nodes $(comma_list $(osts_nodes)) \
10655                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10656
10657         # print MDT checksum_type
10658         echo "$mdt.$FSNAME-*.checksum_type:"
10659         do_nodes $(comma_list $(mdts_nodes)) \
10660                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10661
10662         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10663                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10664
10665         (( $o_count == $OSTCOUNT )) ||
10666                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10667
10668         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10669                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10670
10671         (( $m_count == $MDSCOUNT )) ||
10672                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10673 }
10674 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10675
10676 cleanup_test_78() {
10677         trap 0
10678         rm -f $DIR/$tfile
10679 }
10680
10681 test_78() { # bug 10901
10682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10683         remote_ost || skip_env "local OST"
10684
10685         NSEQ=5
10686         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10687         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10688         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10689         echo "MemTotal: $MEMTOTAL"
10690
10691         # reserve 256MB of memory for the kernel and other running processes,
10692         # and then take 1/2 of the remaining memory for the read/write buffers.
10693         if [ $MEMTOTAL -gt 512 ] ;then
10694                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10695         else
10696                 # for those poor memory-starved high-end clusters...
10697                 MEMTOTAL=$((MEMTOTAL / 2))
10698         fi
10699         echo "Mem to use for directio: $MEMTOTAL"
10700
10701         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10702         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10703         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10704         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10705                 head -n1)
10706         echo "Smallest OST: $SMALLESTOST"
10707         [[ $SMALLESTOST -lt 10240 ]] &&
10708                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10709
10710         trap cleanup_test_78 EXIT
10711
10712         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10713                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10714
10715         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10716         echo "File size: $F78SIZE"
10717         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10718         for i in $(seq 1 $NSEQ); do
10719                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10720                 echo directIO rdwr round $i of $NSEQ
10721                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10722         done
10723
10724         cleanup_test_78
10725 }
10726 run_test 78 "handle large O_DIRECT writes correctly ============"
10727
10728 test_79() { # bug 12743
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730
10731         wait_delete_completed
10732
10733         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10734         BKFREE=$(calc_osc_kbytes kbytesfree)
10735         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10736
10737         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10738         DFTOTAL=`echo $STRING | cut -d, -f1`
10739         DFUSED=`echo $STRING  | cut -d, -f2`
10740         DFAVAIL=`echo $STRING | cut -d, -f3`
10741         DFFREE=$(($DFTOTAL - $DFUSED))
10742
10743         ALLOWANCE=$((64 * $OSTCOUNT))
10744
10745         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10746            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10747                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10748         fi
10749         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10750            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10751                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10752         fi
10753         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10754            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10755                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10756         fi
10757 }
10758 run_test 79 "df report consistency check ======================="
10759
10760 test_80() { # bug 10718
10761         remote_ost_nodsh && skip "remote OST with nodsh"
10762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10763
10764         # relax strong synchronous semantics for slow backends like ZFS
10765         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10766                 local soc="obdfilter.*.sync_lock_cancel"
10767                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10768
10769                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10770                 if [ -z "$save" ]; then
10771                         soc="obdfilter.*.sync_on_lock_cancel"
10772                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10773                 fi
10774
10775                 if [ "$save" != "never" ]; then
10776                         local hosts=$(comma_list $(osts_nodes))
10777
10778                         do_nodes $hosts $LCTL set_param $soc=never
10779                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10780                 fi
10781         fi
10782
10783         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10784         sync; sleep 1; sync
10785         local before=$(date +%s)
10786         cancel_lru_locks osc
10787         local after=$(date +%s)
10788         local diff=$((after - before))
10789         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10790
10791         rm -f $DIR/$tfile
10792 }
10793 run_test 80 "Page eviction is equally fast at high offsets too"
10794
10795 test_81a() { # LU-456
10796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10797         remote_ost_nodsh && skip "remote OST with nodsh"
10798
10799         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10800         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10801         do_facet ost1 lctl set_param fail_loc=0x80000228
10802
10803         # write should trigger a retry and success
10804         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10805         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10806         RC=$?
10807         if [ $RC -ne 0 ] ; then
10808                 error "write should success, but failed for $RC"
10809         fi
10810 }
10811 run_test 81a "OST should retry write when get -ENOSPC ==============="
10812
10813 test_81b() { # LU-456
10814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10815         remote_ost_nodsh && skip "remote OST with nodsh"
10816
10817         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10818         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10819         do_facet ost1 lctl set_param fail_loc=0x228
10820
10821         # write should retry several times and return -ENOSPC finally
10822         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10823         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10824         RC=$?
10825         ENOSPC=28
10826         if [ $RC -ne $ENOSPC ] ; then
10827                 error "dd should fail for -ENOSPC, but succeed."
10828         fi
10829 }
10830 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10831
10832 test_99() {
10833         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10834
10835         test_mkdir $DIR/$tdir.cvsroot
10836         chown $RUNAS_ID $DIR/$tdir.cvsroot
10837
10838         cd $TMP
10839         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10840
10841         cd /etc/init.d
10842         # some versions of cvs import exit(1) when asked to import links or
10843         # files they can't read.  ignore those files.
10844         local toignore=$(find . -type l -printf '-I %f\n' -o \
10845                          ! -perm /4 -printf '-I %f\n')
10846         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10847                 $tdir.reposname vtag rtag
10848
10849         cd $DIR
10850         test_mkdir $DIR/$tdir.reposname
10851         chown $RUNAS_ID $DIR/$tdir.reposname
10852         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10853
10854         cd $DIR/$tdir.reposname
10855         $RUNAS touch foo99
10856         $RUNAS cvs add -m 'addmsg' foo99
10857         $RUNAS cvs update
10858         $RUNAS cvs commit -m 'nomsg' foo99
10859         rm -fr $DIR/$tdir.cvsroot
10860 }
10861 run_test 99 "cvs strange file/directory operations"
10862
10863 test_100() {
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865         [[ "$NETTYPE" =~ tcp ]] ||
10866                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10867         remote_ost_nodsh && skip "remote OST with nodsh"
10868         remote_mds_nodsh && skip "remote MDS with nodsh"
10869         remote_servers ||
10870                 skip "useless for local single node setup"
10871
10872         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10873                 [ "$PROT" != "tcp" ] && continue
10874                 RPORT=$(echo $REMOTE | cut -d: -f2)
10875                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10876
10877                 rc=0
10878                 LPORT=`echo $LOCAL | cut -d: -f2`
10879                 if [ $LPORT -ge 1024 ]; then
10880                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10881                         netstat -tna
10882                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10883                 fi
10884         done
10885         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10886 }
10887 run_test 100 "check local port using privileged port ==========="
10888
10889 function get_named_value()
10890 {
10891     local tag=$1
10892
10893     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10894 }
10895
10896 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10897                    awk '/^max_cached_mb/ { print $2 }')
10898
10899 cleanup_101a() {
10900         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10901         trap 0
10902 }
10903
10904 test_101a() {
10905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10906
10907         local s
10908         local discard
10909         local nreads=10000
10910         local cache_limit=32
10911
10912         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10913         trap cleanup_101a EXIT
10914         $LCTL set_param -n llite.*.read_ahead_stats=0
10915         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10916
10917         #
10918         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10919         #
10920         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10921         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10922
10923         discard=0
10924         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10925                    get_named_value 'read.but.discarded'); do
10926                         discard=$(($discard + $s))
10927         done
10928         cleanup_101a
10929
10930         $LCTL get_param osc.*-osc*.rpc_stats
10931         $LCTL get_param llite.*.read_ahead_stats
10932
10933         # Discard is generally zero, but sometimes a few random reads line up
10934         # and trigger larger readahead, which is wasted & leads to discards.
10935         if [[ $(($discard)) -gt $nreads ]]; then
10936                 error "too many ($discard) discarded pages"
10937         fi
10938         rm -f $DIR/$tfile || true
10939 }
10940 run_test 101a "check read-ahead for random reads"
10941
10942 setup_test101bc() {
10943         test_mkdir $DIR/$tdir
10944         local ssize=$1
10945         local FILE_LENGTH=$2
10946         STRIPE_OFFSET=0
10947
10948         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10949
10950         local list=$(comma_list $(osts_nodes))
10951         set_osd_param $list '' read_cache_enable 0
10952         set_osd_param $list '' writethrough_cache_enable 0
10953
10954         trap cleanup_test101bc EXIT
10955         # prepare the read-ahead file
10956         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10957
10958         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10959                                 count=$FILE_SIZE_MB 2> /dev/null
10960
10961 }
10962
10963 cleanup_test101bc() {
10964         trap 0
10965         rm -rf $DIR/$tdir
10966         rm -f $DIR/$tfile
10967
10968         local list=$(comma_list $(osts_nodes))
10969         set_osd_param $list '' read_cache_enable 1
10970         set_osd_param $list '' writethrough_cache_enable 1
10971 }
10972
10973 calc_total() {
10974         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10975 }
10976
10977 ra_check_101() {
10978         local read_size=$1
10979         local stripe_size=$2
10980         local stride_length=$((stripe_size / read_size))
10981         local stride_width=$((stride_length * OSTCOUNT))
10982         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10983                                 (stride_width - stride_length) ))
10984         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10985                   get_named_value 'read.but.discarded' | calc_total)
10986
10987         if [[ $discard -gt $discard_limit ]]; then
10988                 $LCTL get_param llite.*.read_ahead_stats
10989                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10990         else
10991                 echo "Read-ahead success for size ${read_size}"
10992         fi
10993 }
10994
10995 test_101b() {
10996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10997         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10998
10999         local STRIPE_SIZE=1048576
11000         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11001
11002         if [ $SLOW == "yes" ]; then
11003                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11004         else
11005                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11006         fi
11007
11008         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11009
11010         # prepare the read-ahead file
11011         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11012         cancel_lru_locks osc
11013         for BIDX in 2 4 8 16 32 64 128 256
11014         do
11015                 local BSIZE=$((BIDX*4096))
11016                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11017                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11018                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11019                 $LCTL set_param -n llite.*.read_ahead_stats=0
11020                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11021                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11022                 cancel_lru_locks osc
11023                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11024         done
11025         cleanup_test101bc
11026         true
11027 }
11028 run_test 101b "check stride-io mode read-ahead ================="
11029
11030 test_101c() {
11031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11032
11033         local STRIPE_SIZE=1048576
11034         local FILE_LENGTH=$((STRIPE_SIZE*100))
11035         local nreads=10000
11036         local rsize=65536
11037         local osc_rpc_stats
11038
11039         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11040
11041         cancel_lru_locks osc
11042         $LCTL set_param osc.*.rpc_stats=0
11043         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11044         $LCTL get_param osc.*.rpc_stats
11045         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11046                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11047                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11048                 local size
11049
11050                 if [ $lines -le 20 ]; then
11051                         echo "continue debug"
11052                         continue
11053                 fi
11054                 for size in 1 2 4 8; do
11055                         local rpc=$(echo "$stats" |
11056                                     awk '($1 == "'$size':") {print $2; exit; }')
11057                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11058                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11059                 done
11060                 echo "$osc_rpc_stats check passed!"
11061         done
11062         cleanup_test101bc
11063         true
11064 }
11065 run_test 101c "check stripe_size aligned read-ahead"
11066
11067 test_101d() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069
11070         local file=$DIR/$tfile
11071         local sz_MB=${FILESIZE_101d:-80}
11072         local ra_MB=${READAHEAD_MB:-40}
11073
11074         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11075         [ $free_MB -lt $sz_MB ] &&
11076                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11077
11078         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11079         $LFS setstripe -c -1 $file || error "setstripe failed"
11080
11081         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11082         echo Cancel LRU locks on lustre client to flush the client cache
11083         cancel_lru_locks osc
11084
11085         echo Disable read-ahead
11086         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11087         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11088         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11089         $LCTL get_param -n llite.*.max_read_ahead_mb
11090
11091         echo "Reading the test file $file with read-ahead disabled"
11092         local sz_KB=$((sz_MB * 1024 / 4))
11093         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11094         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11095         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11096                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11097
11098         echo "Cancel LRU locks on lustre client to flush the client cache"
11099         cancel_lru_locks osc
11100         echo Enable read-ahead with ${ra_MB}MB
11101         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11102
11103         echo "Reading the test file $file with read-ahead enabled"
11104         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11105                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11106
11107         echo "read-ahead disabled time read $raOFF"
11108         echo "read-ahead enabled time read $raON"
11109
11110         rm -f $file
11111         wait_delete_completed
11112
11113         # use awk for this check instead of bash because it handles decimals
11114         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11115                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11116 }
11117 run_test 101d "file read with and without read-ahead enabled"
11118
11119 test_101e() {
11120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11121
11122         local file=$DIR/$tfile
11123         local size_KB=500  #KB
11124         local count=100
11125         local bsize=1024
11126
11127         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11128         local need_KB=$((count * size_KB))
11129         [[ $free_KB -le $need_KB ]] &&
11130                 skip_env "Need free space $need_KB, have $free_KB"
11131
11132         echo "Creating $count ${size_KB}K test files"
11133         for ((i = 0; i < $count; i++)); do
11134                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11135         done
11136
11137         echo "Cancel LRU locks on lustre client to flush the client cache"
11138         cancel_lru_locks $OSC
11139
11140         echo "Reset readahead stats"
11141         $LCTL set_param -n llite.*.read_ahead_stats=0
11142
11143         for ((i = 0; i < $count; i++)); do
11144                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11145         done
11146
11147         $LCTL get_param llite.*.max_cached_mb
11148         $LCTL get_param llite.*.read_ahead_stats
11149         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11150                      get_named_value 'misses' | calc_total)
11151
11152         for ((i = 0; i < $count; i++)); do
11153                 rm -rf $file.$i 2>/dev/null
11154         done
11155
11156         #10000 means 20% reads are missing in readahead
11157         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11158 }
11159 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11160
11161 test_101f() {
11162         which iozone || skip_env "no iozone installed"
11163
11164         local old_debug=$($LCTL get_param debug)
11165         old_debug=${old_debug#*=}
11166         $LCTL set_param debug="reada mmap"
11167
11168         # create a test file
11169         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11170
11171         echo Cancel LRU locks on lustre client to flush the client cache
11172         cancel_lru_locks osc
11173
11174         echo Reset readahead stats
11175         $LCTL set_param -n llite.*.read_ahead_stats=0
11176
11177         echo mmap read the file with small block size
11178         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11179                 > /dev/null 2>&1
11180
11181         echo checking missing pages
11182         $LCTL get_param llite.*.read_ahead_stats
11183         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11184                         get_named_value 'misses' | calc_total)
11185
11186         $LCTL set_param debug="$old_debug"
11187         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11188         rm -f $DIR/$tfile
11189 }
11190 run_test 101f "check mmap read performance"
11191
11192 test_101g_brw_size_test() {
11193         local mb=$1
11194         local pages=$((mb * 1048576 / PAGE_SIZE))
11195         local file=$DIR/$tfile
11196
11197         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11198                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11199         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11200                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11201                         return 2
11202         done
11203
11204         stack_trap "rm -f $file" EXIT
11205         $LCTL set_param -n osc.*.rpc_stats=0
11206
11207         # 10 RPCs should be enough for the test
11208         local count=10
11209         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11210                 { error "dd write ${mb} MB blocks failed"; return 3; }
11211         cancel_lru_locks osc
11212         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11213                 { error "dd write ${mb} MB blocks failed"; return 4; }
11214
11215         # calculate number of full-sized read and write RPCs
11216         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11217                 sed -n '/pages per rpc/,/^$/p' |
11218                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11219                 END { print reads,writes }'))
11220         # allow one extra full-sized read RPC for async readahead
11221         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11222                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11223         [[ ${rpcs[1]} == $count ]] ||
11224                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11225 }
11226
11227 test_101g() {
11228         remote_ost_nodsh && skip "remote OST with nodsh"
11229
11230         local rpcs
11231         local osts=$(get_facets OST)
11232         local list=$(comma_list $(osts_nodes))
11233         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11234         local brw_size="obdfilter.*.brw_size"
11235
11236         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11237
11238         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11239
11240         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11241                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11242                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11243            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11244                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11245                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11246
11247                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11248                         suffix="M"
11249
11250                 if [[ $orig_mb -lt 16 ]]; then
11251                         save_lustre_params $osts "$brw_size" > $p
11252                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11253                                 error "set 16MB RPC size failed"
11254
11255                         echo "remount client to enable new RPC size"
11256                         remount_client $MOUNT || error "remount_client failed"
11257                 fi
11258
11259                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11260                 # should be able to set brw_size=12, but no rpc_stats for that
11261                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11262         fi
11263
11264         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11265
11266         if [[ $orig_mb -lt 16 ]]; then
11267                 restore_lustre_params < $p
11268                 remount_client $MOUNT || error "remount_client restore failed"
11269         fi
11270
11271         rm -f $p $DIR/$tfile
11272 }
11273 run_test 101g "Big bulk(4/16 MiB) readahead"
11274
11275 test_101h() {
11276         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11277
11278         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11279                 error "dd 70M file failed"
11280         echo Cancel LRU locks on lustre client to flush the client cache
11281         cancel_lru_locks osc
11282
11283         echo "Reset readahead stats"
11284         $LCTL set_param -n llite.*.read_ahead_stats 0
11285
11286         echo "Read 10M of data but cross 64M bundary"
11287         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11288         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11289                      get_named_value 'misses' | calc_total)
11290         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11291         rm -f $p $DIR/$tfile
11292 }
11293 run_test 101h "Readahead should cover current read window"
11294
11295 test_101i() {
11296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11297                 error "dd 10M file failed"
11298
11299         local max_per_file_mb=$($LCTL get_param -n \
11300                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11301         cancel_lru_locks osc
11302         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11303         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11304                 error "set max_read_ahead_per_file_mb to 1 failed"
11305
11306         echo "Reset readahead stats"
11307         $LCTL set_param llite.*.read_ahead_stats=0
11308
11309         dd if=$DIR/$tfile of=/dev/null bs=2M
11310
11311         $LCTL get_param llite.*.read_ahead_stats
11312         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11313                      awk '/misses/ { print $2 }')
11314         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11315         rm -f $DIR/$tfile
11316 }
11317 run_test 101i "allow current readahead to exceed reservation"
11318
11319 test_101j() {
11320         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11321                 error "setstripe $DIR/$tfile failed"
11322         local file_size=$((1048576 * 16))
11323         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11324         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11325
11326         echo Disable read-ahead
11327         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11328
11329         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11330         for blk in $PAGE_SIZE 1048576 $file_size; do
11331                 cancel_lru_locks osc
11332                 echo "Reset readahead stats"
11333                 $LCTL set_param -n llite.*.read_ahead_stats=0
11334                 local count=$(($file_size / $blk))
11335                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11336                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11337                              get_named_value 'failed.to.fast.read' | calc_total)
11338                 $LCTL get_param -n llite.*.read_ahead_stats
11339                 [ $miss -eq $count ] || error "expected $count got $miss"
11340         done
11341
11342         rm -f $p $DIR/$tfile
11343 }
11344 run_test 101j "A complete read block should be submitted when no RA"
11345
11346 test_101k()
11347 {
11348         local file=$DIR/$tfile
11349
11350         check_set_fallocate_or_skip
11351
11352         $LCTL set_param -n llite.*.read_ahead_stats=0
11353         fallocate -l 16K $file || error "failed to fallocate $file"
11354         cancel_lru_locks osc
11355         $MULTIOP $file or1048576c
11356         $LCTL get_param llite.*.read_ahead_stats
11357 }
11358 run_test 101k "read ahead for small file"
11359
11360 setup_test102() {
11361         test_mkdir $DIR/$tdir
11362         chown $RUNAS_ID $DIR/$tdir
11363         STRIPE_SIZE=65536
11364         STRIPE_OFFSET=1
11365         STRIPE_COUNT=$OSTCOUNT
11366         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11367
11368         trap cleanup_test102 EXIT
11369         cd $DIR
11370         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11371         cd $DIR/$tdir
11372         for num in 1 2 3 4; do
11373                 for count in $(seq 1 $STRIPE_COUNT); do
11374                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11375                                 local size=`expr $STRIPE_SIZE \* $num`
11376                                 local file=file"$num-$idx-$count"
11377                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11378                         done
11379                 done
11380         done
11381
11382         cd $DIR
11383         $1 tar cf $TMP/f102.tar $tdir --xattrs
11384 }
11385
11386 cleanup_test102() {
11387         trap 0
11388         rm -f $TMP/f102.tar
11389         rm -rf $DIR/d0.sanity/d102
11390 }
11391
11392 test_102a() {
11393         [ "$UID" != 0 ] && skip "must run as root"
11394         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11395                 skip_env "must have user_xattr"
11396
11397         [ -z "$(which setfattr 2>/dev/null)" ] &&
11398                 skip_env "could not find setfattr"
11399
11400         local testfile=$DIR/$tfile
11401
11402         touch $testfile
11403         echo "set/get xattr..."
11404         setfattr -n trusted.name1 -v value1 $testfile ||
11405                 error "setfattr -n trusted.name1=value1 $testfile failed"
11406         getfattr -n trusted.name1 $testfile 2> /dev/null |
11407           grep "trusted.name1=.value1" ||
11408                 error "$testfile missing trusted.name1=value1"
11409
11410         setfattr -n user.author1 -v author1 $testfile ||
11411                 error "setfattr -n user.author1=author1 $testfile failed"
11412         getfattr -n user.author1 $testfile 2> /dev/null |
11413           grep "user.author1=.author1" ||
11414                 error "$testfile missing trusted.author1=author1"
11415
11416         echo "listxattr..."
11417         setfattr -n trusted.name2 -v value2 $testfile ||
11418                 error "$testfile unable to set trusted.name2"
11419         setfattr -n trusted.name3 -v value3 $testfile ||
11420                 error "$testfile unable to set trusted.name3"
11421         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11422             grep "trusted.name" | wc -l) -eq 3 ] ||
11423                 error "$testfile missing 3 trusted.name xattrs"
11424
11425         setfattr -n user.author2 -v author2 $testfile ||
11426                 error "$testfile unable to set user.author2"
11427         setfattr -n user.author3 -v author3 $testfile ||
11428                 error "$testfile unable to set user.author3"
11429         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11430             grep "user.author" | wc -l) -eq 3 ] ||
11431                 error "$testfile missing 3 user.author xattrs"
11432
11433         echo "remove xattr..."
11434         setfattr -x trusted.name1 $testfile ||
11435                 error "$testfile error deleting trusted.name1"
11436         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11437                 error "$testfile did not delete trusted.name1 xattr"
11438
11439         setfattr -x user.author1 $testfile ||
11440                 error "$testfile error deleting user.author1"
11441         echo "set lustre special xattr ..."
11442         $LFS setstripe -c1 $testfile
11443         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11444                 awk -F "=" '/trusted.lov/ { print $2 }' )
11445         setfattr -n "trusted.lov" -v $lovea $testfile ||
11446                 error "$testfile doesn't ignore setting trusted.lov again"
11447         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11448                 error "$testfile allow setting invalid trusted.lov"
11449         rm -f $testfile
11450 }
11451 run_test 102a "user xattr test =================================="
11452
11453 check_102b_layout() {
11454         local layout="$*"
11455         local testfile=$DIR/$tfile
11456
11457         echo "test layout '$layout'"
11458         $LFS setstripe $layout $testfile || error "setstripe failed"
11459         $LFS getstripe -y $testfile
11460
11461         echo "get/set/list trusted.lov xattr ..." # b=10930
11462         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11463         [[ "$value" =~ "trusted.lov" ]] ||
11464                 error "can't get trusted.lov from $testfile"
11465         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11466                 error "getstripe failed"
11467
11468         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11469
11470         value=$(cut -d= -f2 <<<$value)
11471         # LU-13168: truncated xattr should fail if short lov_user_md header
11472         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11473                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11474         for len in $lens; do
11475                 echo "setfattr $len $testfile.2"
11476                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11477                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11478         done
11479         local stripe_size=$($LFS getstripe -S $testfile.2)
11480         local stripe_count=$($LFS getstripe -c $testfile.2)
11481         [[ $stripe_size -eq 65536 ]] ||
11482                 error "stripe size $stripe_size != 65536"
11483         [[ $stripe_count -eq $stripe_count_orig ]] ||
11484                 error "stripe count $stripe_count != $stripe_count_orig"
11485         rm $testfile $testfile.2
11486 }
11487
11488 test_102b() {
11489         [ -z "$(which setfattr 2>/dev/null)" ] &&
11490                 skip_env "could not find setfattr"
11491         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11492
11493         # check plain layout
11494         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11495
11496         # and also check composite layout
11497         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11498
11499 }
11500 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11501
11502 test_102c() {
11503         [ -z "$(which setfattr 2>/dev/null)" ] &&
11504                 skip_env "could not find setfattr"
11505         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11506
11507         # b10930: get/set/list lustre.lov xattr
11508         echo "get/set/list lustre.lov xattr ..."
11509         test_mkdir $DIR/$tdir
11510         chown $RUNAS_ID $DIR/$tdir
11511         local testfile=$DIR/$tdir/$tfile
11512         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11513                 error "setstripe failed"
11514         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11515                 error "getstripe failed"
11516         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11517         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11518
11519         local testfile2=${testfile}2
11520         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11521                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11522
11523         $RUNAS $MCREATE $testfile2
11524         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11525         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11526         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11527         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11528         [ $stripe_count -eq $STRIPECOUNT ] ||
11529                 error "stripe count $stripe_count != $STRIPECOUNT"
11530 }
11531 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11532
11533 compare_stripe_info1() {
11534         local stripe_index_all_zero=true
11535
11536         for num in 1 2 3 4; do
11537                 for count in $(seq 1 $STRIPE_COUNT); do
11538                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11539                                 local size=$((STRIPE_SIZE * num))
11540                                 local file=file"$num-$offset-$count"
11541                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11542                                 [[ $stripe_size -ne $size ]] &&
11543                                     error "$file: size $stripe_size != $size"
11544                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11545                                 # allow fewer stripes to be created, ORI-601
11546                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11547                                     error "$file: count $stripe_count != $count"
11548                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11549                                 [[ $stripe_index -ne 0 ]] &&
11550                                         stripe_index_all_zero=false
11551                         done
11552                 done
11553         done
11554         $stripe_index_all_zero &&
11555                 error "all files are being extracted starting from OST index 0"
11556         return 0
11557 }
11558
11559 have_xattrs_include() {
11560         tar --help | grep -q xattrs-include &&
11561                 echo --xattrs-include="lustre.*"
11562 }
11563
11564 test_102d() {
11565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11566         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11567
11568         XINC=$(have_xattrs_include)
11569         setup_test102
11570         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11571         cd $DIR/$tdir/$tdir
11572         compare_stripe_info1
11573 }
11574 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11575
11576 test_102f() {
11577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11579
11580         XINC=$(have_xattrs_include)
11581         setup_test102
11582         test_mkdir $DIR/$tdir.restore
11583         cd $DIR
11584         tar cf - --xattrs $tdir | tar xf - \
11585                 -C $DIR/$tdir.restore --xattrs $XINC
11586         cd $DIR/$tdir.restore/$tdir
11587         compare_stripe_info1
11588 }
11589 run_test 102f "tar copy files, not keep osts"
11590
11591 grow_xattr() {
11592         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11593                 skip "must have user_xattr"
11594         [ -z "$(which setfattr 2>/dev/null)" ] &&
11595                 skip_env "could not find setfattr"
11596         [ -z "$(which getfattr 2>/dev/null)" ] &&
11597                 skip_env "could not find getfattr"
11598
11599         local xsize=${1:-1024}  # in bytes
11600         local file=$DIR/$tfile
11601         local value="$(generate_string $xsize)"
11602         local xbig=trusted.big
11603         local toobig=$2
11604
11605         touch $file
11606         log "save $xbig on $file"
11607         if [ -z "$toobig" ]
11608         then
11609                 setfattr -n $xbig -v $value $file ||
11610                         error "saving $xbig on $file failed"
11611         else
11612                 setfattr -n $xbig -v $value $file &&
11613                         error "saving $xbig on $file succeeded"
11614                 return 0
11615         fi
11616
11617         local orig=$(get_xattr_value $xbig $file)
11618         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11619
11620         local xsml=trusted.sml
11621         log "save $xsml on $file"
11622         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11623
11624         local new=$(get_xattr_value $xbig $file)
11625         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11626
11627         log "grow $xsml on $file"
11628         setfattr -n $xsml -v "$value" $file ||
11629                 error "growing $xsml on $file failed"
11630
11631         new=$(get_xattr_value $xbig $file)
11632         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11633         log "$xbig still valid after growing $xsml"
11634
11635         rm -f $file
11636 }
11637
11638 test_102h() { # bug 15777
11639         grow_xattr 1024
11640 }
11641 run_test 102h "grow xattr from inside inode to external block"
11642
11643 test_102ha() {
11644         large_xattr_enabled || skip_env "ea_inode feature disabled"
11645
11646         echo "setting xattr of max xattr size: $(max_xattr_size)"
11647         grow_xattr $(max_xattr_size)
11648
11649         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11650         echo "This should fail:"
11651         grow_xattr $(($(max_xattr_size) + 10)) 1
11652 }
11653 run_test 102ha "grow xattr from inside inode to external inode"
11654
11655 test_102i() { # bug 17038
11656         [ -z "$(which getfattr 2>/dev/null)" ] &&
11657                 skip "could not find getfattr"
11658
11659         touch $DIR/$tfile
11660         ln -s $DIR/$tfile $DIR/${tfile}link
11661         getfattr -n trusted.lov $DIR/$tfile ||
11662                 error "lgetxattr on $DIR/$tfile failed"
11663         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11664                 grep -i "no such attr" ||
11665                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11666         rm -f $DIR/$tfile $DIR/${tfile}link
11667 }
11668 run_test 102i "lgetxattr test on symbolic link ============"
11669
11670 test_102j() {
11671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11672         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11673
11674         XINC=$(have_xattrs_include)
11675         setup_test102 "$RUNAS"
11676         chown $RUNAS_ID $DIR/$tdir
11677         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11678         cd $DIR/$tdir/$tdir
11679         compare_stripe_info1 "$RUNAS"
11680 }
11681 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11682
11683 test_102k() {
11684         [ -z "$(which setfattr 2>/dev/null)" ] &&
11685                 skip "could not find setfattr"
11686
11687         touch $DIR/$tfile
11688         # b22187 just check that does not crash for regular file.
11689         setfattr -n trusted.lov $DIR/$tfile
11690         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11691         local test_kdir=$DIR/$tdir
11692         test_mkdir $test_kdir
11693         local default_size=$($LFS getstripe -S $test_kdir)
11694         local default_count=$($LFS getstripe -c $test_kdir)
11695         local default_offset=$($LFS getstripe -i $test_kdir)
11696         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11697                 error 'dir setstripe failed'
11698         setfattr -n trusted.lov $test_kdir
11699         local stripe_size=$($LFS getstripe -S $test_kdir)
11700         local stripe_count=$($LFS getstripe -c $test_kdir)
11701         local stripe_offset=$($LFS getstripe -i $test_kdir)
11702         [ $stripe_size -eq $default_size ] ||
11703                 error "stripe size $stripe_size != $default_size"
11704         [ $stripe_count -eq $default_count ] ||
11705                 error "stripe count $stripe_count != $default_count"
11706         [ $stripe_offset -eq $default_offset ] ||
11707                 error "stripe offset $stripe_offset != $default_offset"
11708         rm -rf $DIR/$tfile $test_kdir
11709 }
11710 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11711
11712 test_102l() {
11713         [ -z "$(which getfattr 2>/dev/null)" ] &&
11714                 skip "could not find getfattr"
11715
11716         # LU-532 trusted. xattr is invisible to non-root
11717         local testfile=$DIR/$tfile
11718
11719         touch $testfile
11720
11721         echo "listxattr as user..."
11722         chown $RUNAS_ID $testfile
11723         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11724             grep -q "trusted" &&
11725                 error "$testfile trusted xattrs are user visible"
11726
11727         return 0;
11728 }
11729 run_test 102l "listxattr size test =================================="
11730
11731 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11732         local path=$DIR/$tfile
11733         touch $path
11734
11735         listxattr_size_check $path || error "listattr_size_check $path failed"
11736 }
11737 run_test 102m "Ensure listxattr fails on small bufffer ========"
11738
11739 cleanup_test102
11740
11741 getxattr() { # getxattr path name
11742         # Return the base64 encoding of the value of xattr name on path.
11743         local path=$1
11744         local name=$2
11745
11746         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11747         # file: $path
11748         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11749         #
11750         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11751
11752         getfattr --absolute-names --encoding=base64 --name=$name $path |
11753                 awk -F= -v name=$name '$1 == name {
11754                         print substr($0, index($0, "=") + 1);
11755         }'
11756 }
11757
11758 test_102n() { # LU-4101 mdt: protect internal xattrs
11759         [ -z "$(which setfattr 2>/dev/null)" ] &&
11760                 skip "could not find setfattr"
11761         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11762         then
11763                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11764         fi
11765
11766         local file0=$DIR/$tfile.0
11767         local file1=$DIR/$tfile.1
11768         local xattr0=$TMP/$tfile.0
11769         local xattr1=$TMP/$tfile.1
11770         local namelist="lov lma lmv link fid version som hsm"
11771         local name
11772         local value
11773
11774         rm -rf $file0 $file1 $xattr0 $xattr1
11775         touch $file0 $file1
11776
11777         # Get 'before' xattrs of $file1.
11778         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11779
11780         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11781                 namelist+=" lfsck_namespace"
11782         for name in $namelist; do
11783                 # Try to copy xattr from $file0 to $file1.
11784                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11785
11786                 setfattr --name=trusted.$name --value="$value" $file1 ||
11787                         error "setxattr 'trusted.$name' failed"
11788
11789                 # Try to set a garbage xattr.
11790                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11791
11792                 if [[ x$name == "xlov" ]]; then
11793                         setfattr --name=trusted.lov --value="$value" $file1 &&
11794                         error "setxattr invalid 'trusted.lov' success"
11795                 else
11796                         setfattr --name=trusted.$name --value="$value" $file1 ||
11797                                 error "setxattr invalid 'trusted.$name' failed"
11798                 fi
11799
11800                 # Try to remove the xattr from $file1. We don't care if this
11801                 # appears to succeed or fail, we just don't want there to be
11802                 # any changes or crashes.
11803                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11804         done
11805
11806         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11807         then
11808                 name="lfsck_ns"
11809                 # Try to copy xattr from $file0 to $file1.
11810                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11811
11812                 setfattr --name=trusted.$name --value="$value" $file1 ||
11813                         error "setxattr 'trusted.$name' failed"
11814
11815                 # Try to set a garbage xattr.
11816                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11817
11818                 setfattr --name=trusted.$name --value="$value" $file1 ||
11819                         error "setxattr 'trusted.$name' failed"
11820
11821                 # Try to remove the xattr from $file1. We don't care if this
11822                 # appears to succeed or fail, we just don't want there to be
11823                 # any changes or crashes.
11824                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11825         fi
11826
11827         # Get 'after' xattrs of file1.
11828         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11829
11830         if ! diff $xattr0 $xattr1; then
11831                 error "before and after xattrs of '$file1' differ"
11832         fi
11833
11834         rm -rf $file0 $file1 $xattr0 $xattr1
11835
11836         return 0
11837 }
11838 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11839
11840 test_102p() { # LU-4703 setxattr did not check ownership
11841         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11842                 skip "MDS needs to be at least 2.5.56"
11843
11844         local testfile=$DIR/$tfile
11845
11846         touch $testfile
11847
11848         echo "setfacl as user..."
11849         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11850         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11851
11852         echo "setfattr as user..."
11853         setfacl -m "u:$RUNAS_ID:---" $testfile
11854         $RUNAS setfattr -x system.posix_acl_access $testfile
11855         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11856 }
11857 run_test 102p "check setxattr(2) correctly fails without permission"
11858
11859 test_102q() {
11860         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11861                 skip "MDS needs to be at least 2.6.92"
11862
11863         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11864 }
11865 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11866
11867 test_102r() {
11868         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11869                 skip "MDS needs to be at least 2.6.93"
11870
11871         touch $DIR/$tfile || error "touch"
11872         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11873         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11874         rm $DIR/$tfile || error "rm"
11875
11876         #normal directory
11877         mkdir -p $DIR/$tdir || error "mkdir"
11878         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11879         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11880         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11881                 error "$testfile error deleting user.author1"
11882         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11883                 grep "user.$(basename $tdir)" &&
11884                 error "$tdir did not delete user.$(basename $tdir)"
11885         rmdir $DIR/$tdir || error "rmdir"
11886
11887         #striped directory
11888         test_mkdir $DIR/$tdir
11889         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11890         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11891         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11892                 error "$testfile error deleting user.author1"
11893         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11894                 grep "user.$(basename $tdir)" &&
11895                 error "$tdir did not delete user.$(basename $tdir)"
11896         rmdir $DIR/$tdir || error "rm striped dir"
11897 }
11898 run_test 102r "set EAs with empty values"
11899
11900 test_102s() {
11901         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11902                 skip "MDS needs to be at least 2.11.52"
11903
11904         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11905
11906         save_lustre_params client "llite.*.xattr_cache" > $save
11907
11908         for cache in 0 1; do
11909                 lctl set_param llite.*.xattr_cache=$cache
11910
11911                 rm -f $DIR/$tfile
11912                 touch $DIR/$tfile || error "touch"
11913                 for prefix in lustre security system trusted user; do
11914                         # Note getxattr() may fail with 'Operation not
11915                         # supported' or 'No such attribute' depending
11916                         # on prefix and cache.
11917                         getfattr -n $prefix.n102s $DIR/$tfile &&
11918                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11919                 done
11920         done
11921
11922         restore_lustre_params < $save
11923 }
11924 run_test 102s "getting nonexistent xattrs should fail"
11925
11926 test_102t() {
11927         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11928                 skip "MDS needs to be at least 2.11.52"
11929
11930         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11931
11932         save_lustre_params client "llite.*.xattr_cache" > $save
11933
11934         for cache in 0 1; do
11935                 lctl set_param llite.*.xattr_cache=$cache
11936
11937                 for buf_size in 0 256; do
11938                         rm -f $DIR/$tfile
11939                         touch $DIR/$tfile || error "touch"
11940                         setfattr -n user.multiop $DIR/$tfile
11941                         $MULTIOP $DIR/$tfile oa$buf_size ||
11942                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11943                 done
11944         done
11945
11946         restore_lustre_params < $save
11947 }
11948 run_test 102t "zero length xattr values handled correctly"
11949
11950 run_acl_subtest()
11951 {
11952         local test=$LUSTRE/tests/acl/$1.test
11953         local tmp=$(mktemp -t $1-XXXXXX).test
11954         local bin=$2
11955         local dmn=$3
11956         local grp=$4
11957         local nbd=$5
11958         export LANG=C
11959
11960
11961         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11962         local sedgroups="-e s/:users/:$grp/g"
11963         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11964
11965         sed $sedusers $sedgroups < $test > $tmp
11966         stack_trap "rm -f $tmp"
11967         [[ -s $tmp ]] || error "sed failed to create test script"
11968
11969         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11970         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11971 }
11972
11973 test_103a() {
11974         [ "$UID" != 0 ] && skip "must run as root"
11975         $GSS && skip_env "could not run under gss"
11976         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11977                 skip_env "must have acl enabled"
11978         which setfacl || skip_env "could not find setfacl"
11979         remote_mds_nodsh && skip "remote MDS with nodsh"
11980
11981         ACLBIN=${ACLBIN:-"bin"}
11982         ACLDMN=${ACLDMN:-"daemon"}
11983         ACLGRP=${ACLGRP:-"users"}
11984         ACLNBD=${ACLNBD:-"nobody"}
11985
11986         if ! id $ACLBIN ||
11987            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11988                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11989                 ACLBIN=$USER0
11990                 if ! id $ACLBIN ; then
11991                         cat /etc/passwd
11992                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11993                 fi
11994         fi
11995         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11996            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11997                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11998                 ACLDMN=$USER1
11999                 if ! id $ACLDMN ; then
12000                         cat /etc/passwd
12001                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12002                 fi
12003         fi
12004         if ! getent group $ACLGRP; then
12005                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12006                 ACLGRP="$TSTUSR"
12007                 if ! getent group $ACLGRP; then
12008                         echo "cannot find group '$ACLGRP', adding it"
12009                         cat /etc/group
12010                         add_group 60000 $ACLGRP
12011                 fi
12012         fi
12013
12014         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12015         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12016         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12017
12018         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12019                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12020                 ACLGRP="$TSTUSR"
12021                 if ! getent group $ACLGRP; then
12022                         echo "cannot find group '$ACLGRP', adding it"
12023                         cat /etc/group
12024                         add_group 60000 $ACLGRP
12025                 fi
12026                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12027                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12028                         cat /etc/group
12029                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12030                 fi
12031         fi
12032
12033         gpasswd -a $ACLDMN $ACLBIN ||
12034                 error "setting client group failed"             # LU-5641
12035         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12036                 error "setting MDS group failed"                # LU-5641
12037
12038         declare -a identity_old
12039
12040         for num in $(seq $MDSCOUNT); do
12041                 switch_identity $num true || identity_old[$num]=$?
12042         done
12043
12044         SAVE_UMASK=$(umask)
12045         umask 0022
12046         mkdir -p $DIR/$tdir
12047         cd $DIR/$tdir
12048
12049         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12050         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12051         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12052         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12053         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12054         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12055         if ! id -u $ACLNBD ||
12056            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12057                 ACLNBD="nfsnobody"
12058                 if ! id -u $ACLNBD; then
12059                         ACLNBD=""
12060                 fi
12061         fi
12062         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12063                 add_group $(id -u $ACLNBD) $ACLNBD
12064                 if ! getent group $ACLNBD; then
12065                         ACLNBD=""
12066                 fi
12067         fi
12068         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12069            [[ -n "$ACLNBD" ]] && which setfattr; then
12070                 run_acl_subtest permissions_xattr \
12071                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12072         elif [[ -z "$ACLNBD" ]]; then
12073                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12074         else
12075                 echo "skip 'permission_xattr' test - missing setfattr command"
12076         fi
12077         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12078
12079         # inheritance test got from HP
12080         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12081         chmod +x make-tree || error "chmod +x failed"
12082         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12083         rm -f make-tree
12084
12085         echo "LU-974 ignore umask when acl is enabled..."
12086         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12087         if [ $MDSCOUNT -ge 2 ]; then
12088                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12089         fi
12090
12091         echo "LU-2561 newly created file is same size as directory..."
12092         if [ "$mds1_FSTYPE" != "zfs" ]; then
12093                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12094         else
12095                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12096         fi
12097
12098         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12099
12100         cd $SAVE_PWD
12101         umask $SAVE_UMASK
12102
12103         for num in $(seq $MDSCOUNT); do
12104                 if [ "${identity_old[$num]}" = 1 ]; then
12105                         switch_identity $num false || identity_old[$num]=$?
12106                 fi
12107         done
12108 }
12109 run_test 103a "acl test"
12110
12111 test_103b() {
12112         declare -a pids
12113         local U
12114
12115         for U in {0..511}; do
12116                 {
12117                 local O=$(printf "%04o" $U)
12118
12119                 umask $(printf "%04o" $((511 ^ $O)))
12120                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12121                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12122
12123                 (( $S == ($O & 0666) )) ||
12124                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12125
12126                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12127                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12128                 (( $S == ($O & 0666) )) ||
12129                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12130
12131                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12132                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12133                 (( $S == ($O & 0666) )) ||
12134                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12135                 rm -f $DIR/$tfile.[smp]$0
12136                 } &
12137                 local pid=$!
12138
12139                 # limit the concurrently running threads to 64. LU-11878
12140                 local idx=$((U % 64))
12141                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12142                 pids[idx]=$pid
12143         done
12144         wait
12145 }
12146 run_test 103b "umask lfs setstripe"
12147
12148 test_103c() {
12149         mkdir -p $DIR/$tdir
12150         cp -rp $DIR/$tdir $DIR/$tdir.bak
12151
12152         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12153                 error "$DIR/$tdir shouldn't contain default ACL"
12154         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12155                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12156         true
12157 }
12158 run_test 103c "'cp -rp' won't set empty acl"
12159
12160 test_103e() {
12161         local numacl
12162         local fileacl
12163         local saved_debug=$($LCTL get_param -n debug)
12164
12165         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12166                 skip "MDS needs to be at least 2.14.52"
12167
12168         large_xattr_enabled || skip_env "ea_inode feature disabled"
12169
12170         mkdir -p $DIR/$tdir
12171         # add big LOV EA to cause reply buffer overflow earlier
12172         $LFS setstripe -C 1000 $DIR/$tdir
12173         lctl set_param mdc.*-mdc*.stats=clear
12174
12175         $LCTL set_param debug=0
12176         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12177         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12178
12179         # add a large number of default ACLs (expect 8000+ for 2.13+)
12180         for U in {2..7000}; do
12181                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12182                         error "Able to add just $U default ACLs"
12183         done
12184         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12185         echo "$numacl default ACLs created"
12186
12187         stat $DIR/$tdir || error "Cannot stat directory"
12188         # check file creation
12189         touch $DIR/$tdir/$tfile ||
12190                 error "failed to create $tfile with $numacl default ACLs"
12191         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12192         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12193         echo "$fileacl ACLs were inherited"
12194         (( $fileacl == $numacl )) ||
12195                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12196         # check that new ACLs creation adds new ACLs to inherited ACLs
12197         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12198                 error "Cannot set new ACL"
12199         numacl=$((numacl + 1))
12200         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12201         (( $fileacl == $numacl )) ||
12202                 error "failed to add new ACL: $fileacl != $numacl as expected"
12203         # adds more ACLs to a file to reach their maximum at 8000+
12204         numacl=0
12205         for U in {20000..25000}; do
12206                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12207                 numacl=$((numacl + 1))
12208         done
12209         echo "Added $numacl more ACLs to the file"
12210         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12211         echo "Total $fileacl ACLs in file"
12212         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12213         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12214         rmdir $DIR/$tdir || error "Cannot remove directory"
12215 }
12216 run_test 103e "inheritance of big amount of default ACLs"
12217
12218 test_103f() {
12219         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12220                 skip "MDS needs to be at least 2.14.51"
12221
12222         large_xattr_enabled || skip_env "ea_inode feature disabled"
12223
12224         # enable changelog to consume more internal MDD buffers
12225         changelog_register
12226
12227         mkdir -p $DIR/$tdir
12228         # add big LOV EA
12229         $LFS setstripe -C 1000 $DIR/$tdir
12230         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12231         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12232         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12233         rmdir $DIR/$tdir || error "Cannot remove directory"
12234 }
12235 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12236
12237 test_104a() {
12238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12239
12240         touch $DIR/$tfile
12241         lfs df || error "lfs df failed"
12242         lfs df -ih || error "lfs df -ih failed"
12243         lfs df -h $DIR || error "lfs df -h $DIR failed"
12244         lfs df -i $DIR || error "lfs df -i $DIR failed"
12245         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12246         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12247
12248         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12249         lctl --device %$OSC deactivate
12250         lfs df || error "lfs df with deactivated OSC failed"
12251         lctl --device %$OSC activate
12252         # wait the osc back to normal
12253         wait_osc_import_ready client ost
12254
12255         lfs df || error "lfs df with reactivated OSC failed"
12256         rm -f $DIR/$tfile
12257 }
12258 run_test 104a "lfs df [-ih] [path] test ========================="
12259
12260 test_104b() {
12261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12262         [ $RUNAS_ID -eq $UID ] &&
12263                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12264
12265         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12266                         grep "Permission denied" | wc -l)))
12267         if [ $denied_cnt -ne 0 ]; then
12268                 error "lfs check servers test failed"
12269         fi
12270 }
12271 run_test 104b "$RUNAS lfs check servers test ===================="
12272
12273 #
12274 # Verify $1 is within range of $2.
12275 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12276 # $1 is <= 2% of $2. Else Fail.
12277 #
12278 value_in_range() {
12279         # Strip all units (M, G, T)
12280         actual=$(echo $1 | tr -d A-Z)
12281         expect=$(echo $2 | tr -d A-Z)
12282
12283         expect_lo=$(($expect * 98 / 100)) # 2% below
12284         expect_hi=$(($expect * 102 / 100)) # 2% above
12285
12286         # permit 2% drift above and below
12287         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12288 }
12289
12290 test_104c() {
12291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12292         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12293
12294         local ost_param="osd-zfs.$FSNAME-OST0000."
12295         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12296         local ofacets=$(get_facets OST)
12297         local mfacets=$(get_facets MDS)
12298         local saved_ost_blocks=
12299         local saved_mdt_blocks=
12300
12301         echo "Before recordsize change"
12302         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12303         df=($(df -h | grep "$MOUNT"$))
12304
12305         # For checking.
12306         echo "lfs output : ${lfs_df[*]}"
12307         echo "df  output : ${df[*]}"
12308
12309         for facet in ${ofacets//,/ }; do
12310                 if [ -z $saved_ost_blocks ]; then
12311                         saved_ost_blocks=$(do_facet $facet \
12312                                 lctl get_param -n $ost_param.blocksize)
12313                         echo "OST Blocksize: $saved_ost_blocks"
12314                 fi
12315                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12316                 do_facet $facet zfs set recordsize=32768 $ost
12317         done
12318
12319         # BS too small. Sufficient for functional testing.
12320         for facet in ${mfacets//,/ }; do
12321                 if [ -z $saved_mdt_blocks ]; then
12322                         saved_mdt_blocks=$(do_facet $facet \
12323                                 lctl get_param -n $mdt_param.blocksize)
12324                         echo "MDT Blocksize: $saved_mdt_blocks"
12325                 fi
12326                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12327                 do_facet $facet zfs set recordsize=32768 $mdt
12328         done
12329
12330         # Give new values chance to reflect change
12331         sleep 2
12332
12333         echo "After recordsize change"
12334         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12335         df_after=($(df -h | grep "$MOUNT"$))
12336
12337         # For checking.
12338         echo "lfs output : ${lfs_df_after[*]}"
12339         echo "df  output : ${df_after[*]}"
12340
12341         # Verify lfs df
12342         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12343                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12344         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12345                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12346         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12347                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12348
12349         # Verify df
12350         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12351                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12352         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12353                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12354         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12355                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12356
12357         # Restore MDT recordize back to original
12358         for facet in ${mfacets//,/ }; do
12359                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12360                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12361         done
12362
12363         # Restore OST recordize back to original
12364         for facet in ${ofacets//,/ }; do
12365                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12366                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12367         done
12368
12369         return 0
12370 }
12371 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12372
12373 test_104d() {
12374         (( $RUNAS_ID != $UID )) ||
12375                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12376
12377         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12378                 skip "lustre version doesn't support lctl dl with non-root"
12379
12380         # debugfs only allows root users to access files, so the
12381         # previous move of the "devices" file to debugfs broke
12382         # "lctl dl" for non-root users. The LU-9680 Netlink
12383         # interface again allows non-root users to list devices.
12384         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12385                 error "lctl dl doesn't work for non root"
12386
12387         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12388         [ "$ost_count" -eq $OSTCOUNT ]  ||
12389                 error "lctl dl reports wrong number of OST devices"
12390
12391         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12392         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12393                 error "lctl dl reports wrong number of MDT devices"
12394 }
12395 run_test 104d "$RUNAS lctl dl test"
12396
12397 test_105a() {
12398         # doesn't work on 2.4 kernels
12399         touch $DIR/$tfile
12400         if $(flock_is_enabled); then
12401                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12402         else
12403                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12404         fi
12405         rm -f $DIR/$tfile
12406 }
12407 run_test 105a "flock when mounted without -o flock test ========"
12408
12409 test_105b() {
12410         touch $DIR/$tfile
12411         if $(flock_is_enabled); then
12412                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12413         else
12414                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12415         fi
12416         rm -f $DIR/$tfile
12417 }
12418 run_test 105b "fcntl when mounted without -o flock test ========"
12419
12420 test_105c() {
12421         touch $DIR/$tfile
12422         if $(flock_is_enabled); then
12423                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12424         else
12425                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12426         fi
12427         rm -f $DIR/$tfile
12428 }
12429 run_test 105c "lockf when mounted without -o flock test"
12430
12431 test_105d() { # bug 15924
12432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12433
12434         test_mkdir $DIR/$tdir
12435         flock_is_enabled || skip_env "mount w/o flock enabled"
12436         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12437         $LCTL set_param fail_loc=0x80000315
12438         flocks_test 2 $DIR/$tdir
12439 }
12440 run_test 105d "flock race (should not freeze) ========"
12441
12442 test_105e() { # bug 22660 && 22040
12443         flock_is_enabled || skip_env "mount w/o flock enabled"
12444
12445         touch $DIR/$tfile
12446         flocks_test 3 $DIR/$tfile
12447 }
12448 run_test 105e "Two conflicting flocks from same process"
12449
12450 test_106() { #bug 10921
12451         test_mkdir $DIR/$tdir
12452         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12453         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12454 }
12455 run_test 106 "attempt exec of dir followed by chown of that dir"
12456
12457 test_107() {
12458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12459
12460         CDIR=`pwd`
12461         local file=core
12462
12463         cd $DIR
12464         rm -f $file
12465
12466         local save_pattern=$(sysctl -n kernel.core_pattern)
12467         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12468         sysctl -w kernel.core_pattern=$file
12469         sysctl -w kernel.core_uses_pid=0
12470
12471         ulimit -c unlimited
12472         sleep 60 &
12473         SLEEPPID=$!
12474
12475         sleep 1
12476
12477         kill -s 11 $SLEEPPID
12478         wait $SLEEPPID
12479         if [ -e $file ]; then
12480                 size=`stat -c%s $file`
12481                 [ $size -eq 0 ] && error "Fail to create core file $file"
12482         else
12483                 error "Fail to create core file $file"
12484         fi
12485         rm -f $file
12486         sysctl -w kernel.core_pattern=$save_pattern
12487         sysctl -w kernel.core_uses_pid=$save_uses_pid
12488         cd $CDIR
12489 }
12490 run_test 107 "Coredump on SIG"
12491
12492 test_110() {
12493         test_mkdir $DIR/$tdir
12494         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12495         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12496                 error "mkdir with 256 char should fail, but did not"
12497         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12498                 error "create with 255 char failed"
12499         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12500                 error "create with 256 char should fail, but did not"
12501
12502         ls -l $DIR/$tdir
12503         rm -rf $DIR/$tdir
12504 }
12505 run_test 110 "filename length checking"
12506
12507 test_116a() { # was previously test_116()
12508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12509         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12510         remote_mds_nodsh && skip "remote MDS with nodsh"
12511
12512         echo -n "Free space priority "
12513         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12514                 head -n1
12515         declare -a AVAIL
12516         free_min_max
12517
12518         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12519         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12520         stack_trap simple_cleanup_common
12521
12522         # Check if we need to generate uneven OSTs
12523         test_mkdir -p $DIR/$tdir/OST${MINI}
12524         local FILL=$((MINV / 4))
12525         local DIFF=$((MAXV - MINV))
12526         local DIFF2=$((DIFF * 100 / MINV))
12527
12528         local threshold=$(do_facet $SINGLEMDS \
12529                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12530         threshold=${threshold%%%}
12531         echo -n "Check for uneven OSTs: "
12532         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12533
12534         if [[ $DIFF2 -gt $threshold ]]; then
12535                 echo "ok"
12536                 echo "Don't need to fill OST$MINI"
12537         else
12538                 # generate uneven OSTs. Write 2% over the QOS threshold value
12539                 echo "no"
12540                 DIFF=$((threshold - DIFF2 + 2))
12541                 DIFF2=$((MINV * DIFF / 100))
12542                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12543                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12544                         error "setstripe failed"
12545                 DIFF=$((DIFF2 / 2048))
12546                 i=0
12547                 while [ $i -lt $DIFF ]; do
12548                         i=$((i + 1))
12549                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12550                                 bs=2M count=1 2>/dev/null
12551                         echo -n .
12552                 done
12553                 echo .
12554                 sync
12555                 sleep_maxage
12556                 free_min_max
12557         fi
12558
12559         DIFF=$((MAXV - MINV))
12560         DIFF2=$((DIFF * 100 / MINV))
12561         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12562         if [ $DIFF2 -gt $threshold ]; then
12563                 echo "ok"
12564         else
12565                 skip "QOS imbalance criteria not met"
12566         fi
12567
12568         MINI1=$MINI
12569         MINV1=$MINV
12570         MAXI1=$MAXI
12571         MAXV1=$MAXV
12572
12573         # now fill using QOS
12574         $LFS setstripe -c 1 $DIR/$tdir
12575         FILL=$((FILL / 200))
12576         if [ $FILL -gt 600 ]; then
12577                 FILL=600
12578         fi
12579         echo "writing $FILL files to QOS-assigned OSTs"
12580         i=0
12581         while [ $i -lt $FILL ]; do
12582                 i=$((i + 1))
12583                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12584                         count=1 2>/dev/null
12585                 echo -n .
12586         done
12587         echo "wrote $i 200k files"
12588         sync
12589         sleep_maxage
12590
12591         echo "Note: free space may not be updated, so measurements might be off"
12592         free_min_max
12593         DIFF2=$((MAXV - MINV))
12594         echo "free space delta: orig $DIFF final $DIFF2"
12595         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12596         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12597         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12598         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12599         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12600         if [[ $DIFF -gt 0 ]]; then
12601                 FILL=$((DIFF2 * 100 / DIFF - 100))
12602                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12603         fi
12604
12605         # Figure out which files were written where
12606         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12607                awk '/'$MINI1': / {print $2; exit}')
12608         echo $UUID
12609         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12610         echo "$MINC files created on smaller OST $MINI1"
12611         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12612                awk '/'$MAXI1': / {print $2; exit}')
12613         echo $UUID
12614         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12615         echo "$MAXC files created on larger OST $MAXI1"
12616         if [[ $MINC -gt 0 ]]; then
12617                 FILL=$((MAXC * 100 / MINC - 100))
12618                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12619         fi
12620         [[ $MAXC -gt $MINC ]] ||
12621                 error_ignore LU-9 "stripe QOS didn't balance free space"
12622 }
12623 run_test 116a "stripe QOS: free space balance ==================="
12624
12625 test_116b() { # LU-2093
12626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12627         remote_mds_nodsh && skip "remote MDS with nodsh"
12628
12629 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12630         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12631                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12632         [ -z "$old_rr" ] && skip "no QOS"
12633         do_facet $SINGLEMDS lctl set_param \
12634                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12635         mkdir -p $DIR/$tdir
12636         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12637         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12638         do_facet $SINGLEMDS lctl set_param fail_loc=0
12639         rm -rf $DIR/$tdir
12640         do_facet $SINGLEMDS lctl set_param \
12641                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12642 }
12643 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12644
12645 test_117() # bug 10891
12646 {
12647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12648
12649         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12650         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12651         lctl set_param fail_loc=0x21e
12652         > $DIR/$tfile || error "truncate failed"
12653         lctl set_param fail_loc=0
12654         echo "Truncate succeeded."
12655         rm -f $DIR/$tfile
12656 }
12657 run_test 117 "verify osd extend =========="
12658
12659 NO_SLOW_RESENDCOUNT=4
12660 export OLD_RESENDCOUNT=""
12661 set_resend_count () {
12662         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12663         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12664         lctl set_param -n $PROC_RESENDCOUNT $1
12665         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12666 }
12667
12668 # for reduce test_118* time (b=14842)
12669 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12670
12671 # Reset async IO behavior after error case
12672 reset_async() {
12673         FILE=$DIR/reset_async
12674
12675         # Ensure all OSCs are cleared
12676         $LFS setstripe -c -1 $FILE
12677         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12678         sync
12679         rm $FILE
12680 }
12681
12682 test_118a() #bug 11710
12683 {
12684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12685
12686         reset_async
12687
12688         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12689         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12690         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12691
12692         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12693                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12694                 return 1;
12695         fi
12696         rm -f $DIR/$tfile
12697 }
12698 run_test 118a "verify O_SYNC works =========="
12699
12700 test_118b()
12701 {
12702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12703         remote_ost_nodsh && skip "remote OST with nodsh"
12704
12705         reset_async
12706
12707         #define OBD_FAIL_SRV_ENOENT 0x217
12708         set_nodes_failloc "$(osts_nodes)" 0x217
12709         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12710         RC=$?
12711         set_nodes_failloc "$(osts_nodes)" 0
12712         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12713         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12714                     grep -c writeback)
12715
12716         if [[ $RC -eq 0 ]]; then
12717                 error "Must return error due to dropped pages, rc=$RC"
12718                 return 1;
12719         fi
12720
12721         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12722                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12723                 return 1;
12724         fi
12725
12726         echo "Dirty pages not leaked on ENOENT"
12727
12728         # Due to the above error the OSC will issue all RPCs syncronously
12729         # until a subsequent RPC completes successfully without error.
12730         $MULTIOP $DIR/$tfile Ow4096yc
12731         rm -f $DIR/$tfile
12732
12733         return 0
12734 }
12735 run_test 118b "Reclaim dirty pages on fatal error =========="
12736
12737 test_118c()
12738 {
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740
12741         # for 118c, restore the original resend count, LU-1940
12742         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12743                                 set_resend_count $OLD_RESENDCOUNT
12744         remote_ost_nodsh && skip "remote OST with nodsh"
12745
12746         reset_async
12747
12748         #define OBD_FAIL_OST_EROFS               0x216
12749         set_nodes_failloc "$(osts_nodes)" 0x216
12750
12751         # multiop should block due to fsync until pages are written
12752         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12753         MULTIPID=$!
12754         sleep 1
12755
12756         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12757                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12758         fi
12759
12760         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12761                     grep -c writeback)
12762         if [[ $WRITEBACK -eq 0 ]]; then
12763                 error "No page in writeback, writeback=$WRITEBACK"
12764         fi
12765
12766         set_nodes_failloc "$(osts_nodes)" 0
12767         wait $MULTIPID
12768         RC=$?
12769         if [[ $RC -ne 0 ]]; then
12770                 error "Multiop fsync failed, rc=$RC"
12771         fi
12772
12773         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12774         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12775                     grep -c writeback)
12776         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12777                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12778         fi
12779
12780         rm -f $DIR/$tfile
12781         echo "Dirty pages flushed via fsync on EROFS"
12782         return 0
12783 }
12784 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12785
12786 # continue to use small resend count to reduce test_118* time (b=14842)
12787 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12788
12789 test_118d()
12790 {
12791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12792         remote_ost_nodsh && skip "remote OST with nodsh"
12793
12794         reset_async
12795
12796         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12797         set_nodes_failloc "$(osts_nodes)" 0x214
12798         # multiop should block due to fsync until pages are written
12799         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12800         MULTIPID=$!
12801         sleep 1
12802
12803         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12804                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12805         fi
12806
12807         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12808                     grep -c writeback)
12809         if [[ $WRITEBACK -eq 0 ]]; then
12810                 error "No page in writeback, writeback=$WRITEBACK"
12811         fi
12812
12813         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12814         set_nodes_failloc "$(osts_nodes)" 0
12815
12816         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12817         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12818                     grep -c writeback)
12819         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12820                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12821         fi
12822
12823         rm -f $DIR/$tfile
12824         echo "Dirty pages gaurenteed flushed via fsync"
12825         return 0
12826 }
12827 run_test 118d "Fsync validation inject a delay of the bulk =========="
12828
12829 test_118f() {
12830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12831
12832         reset_async
12833
12834         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12835         lctl set_param fail_loc=0x8000040a
12836
12837         # Should simulate EINVAL error which is fatal
12838         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12839         RC=$?
12840         if [[ $RC -eq 0 ]]; then
12841                 error "Must return error due to dropped pages, rc=$RC"
12842         fi
12843
12844         lctl set_param fail_loc=0x0
12845
12846         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12847         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12848         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12849                     grep -c writeback)
12850         if [[ $LOCKED -ne 0 ]]; then
12851                 error "Locked pages remain in cache, locked=$LOCKED"
12852         fi
12853
12854         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12855                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12856         fi
12857
12858         rm -f $DIR/$tfile
12859         echo "No pages locked after fsync"
12860
12861         reset_async
12862         return 0
12863 }
12864 run_test 118f "Simulate unrecoverable OSC side error =========="
12865
12866 test_118g() {
12867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12868
12869         reset_async
12870
12871         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12872         lctl set_param fail_loc=0x406
12873
12874         # simulate local -ENOMEM
12875         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12876         RC=$?
12877
12878         lctl set_param fail_loc=0
12879         if [[ $RC -eq 0 ]]; then
12880                 error "Must return error due to dropped pages, rc=$RC"
12881         fi
12882
12883         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12884         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12885         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12886                         grep -c writeback)
12887         if [[ $LOCKED -ne 0 ]]; then
12888                 error "Locked pages remain in cache, locked=$LOCKED"
12889         fi
12890
12891         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12892                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12893         fi
12894
12895         rm -f $DIR/$tfile
12896         echo "No pages locked after fsync"
12897
12898         reset_async
12899         return 0
12900 }
12901 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12902
12903 test_118h() {
12904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12905         remote_ost_nodsh && skip "remote OST with nodsh"
12906
12907         reset_async
12908
12909         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12910         set_nodes_failloc "$(osts_nodes)" 0x20e
12911         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12912         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12913         RC=$?
12914
12915         set_nodes_failloc "$(osts_nodes)" 0
12916         if [[ $RC -eq 0 ]]; then
12917                 error "Must return error due to dropped pages, rc=$RC"
12918         fi
12919
12920         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12921         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12922         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12923                     grep -c writeback)
12924         if [[ $LOCKED -ne 0 ]]; then
12925                 error "Locked pages remain in cache, locked=$LOCKED"
12926         fi
12927
12928         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12929                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12930         fi
12931
12932         rm -f $DIR/$tfile
12933         echo "No pages locked after fsync"
12934
12935         return 0
12936 }
12937 run_test 118h "Verify timeout in handling recoverables errors  =========="
12938
12939 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12940
12941 test_118i() {
12942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12943         remote_ost_nodsh && skip "remote OST with nodsh"
12944
12945         reset_async
12946
12947         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12948         set_nodes_failloc "$(osts_nodes)" 0x20e
12949
12950         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12951         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12952         PID=$!
12953         sleep 5
12954         set_nodes_failloc "$(osts_nodes)" 0
12955
12956         wait $PID
12957         RC=$?
12958         if [[ $RC -ne 0 ]]; then
12959                 error "got error, but should be not, rc=$RC"
12960         fi
12961
12962         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12963         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12964         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12965         if [[ $LOCKED -ne 0 ]]; then
12966                 error "Locked pages remain in cache, locked=$LOCKED"
12967         fi
12968
12969         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12970                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12971         fi
12972
12973         rm -f $DIR/$tfile
12974         echo "No pages locked after fsync"
12975
12976         return 0
12977 }
12978 run_test 118i "Fix error before timeout in recoverable error  =========="
12979
12980 [ "$SLOW" = "no" ] && set_resend_count 4
12981
12982 test_118j() {
12983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12984         remote_ost_nodsh && skip "remote OST with nodsh"
12985
12986         reset_async
12987
12988         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12989         set_nodes_failloc "$(osts_nodes)" 0x220
12990
12991         # return -EIO from OST
12992         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12993         RC=$?
12994         set_nodes_failloc "$(osts_nodes)" 0x0
12995         if [[ $RC -eq 0 ]]; then
12996                 error "Must return error due to dropped pages, rc=$RC"
12997         fi
12998
12999         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13002         if [[ $LOCKED -ne 0 ]]; then
13003                 error "Locked pages remain in cache, locked=$LOCKED"
13004         fi
13005
13006         # in recoverable error on OST we want resend and stay until it finished
13007         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13008                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13009         fi
13010
13011         rm -f $DIR/$tfile
13012         echo "No pages locked after fsync"
13013
13014         return 0
13015 }
13016 run_test 118j "Simulate unrecoverable OST side error =========="
13017
13018 test_118k()
13019 {
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021         remote_ost_nodsh && skip "remote OSTs with nodsh"
13022
13023         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13024         set_nodes_failloc "$(osts_nodes)" 0x20e
13025         test_mkdir $DIR/$tdir
13026
13027         for ((i=0;i<10;i++)); do
13028                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13029                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13030                 SLEEPPID=$!
13031                 sleep 0.500s
13032                 kill $SLEEPPID
13033                 wait $SLEEPPID
13034         done
13035
13036         set_nodes_failloc "$(osts_nodes)" 0
13037         rm -rf $DIR/$tdir
13038 }
13039 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13040
13041 test_118l() # LU-646
13042 {
13043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13044
13045         test_mkdir $DIR/$tdir
13046         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13047         rm -rf $DIR/$tdir
13048 }
13049 run_test 118l "fsync dir"
13050
13051 test_118m() # LU-3066
13052 {
13053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13054
13055         test_mkdir $DIR/$tdir
13056         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13057         rm -rf $DIR/$tdir
13058 }
13059 run_test 118m "fdatasync dir ========="
13060
13061 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13062
13063 test_118n()
13064 {
13065         local begin
13066         local end
13067
13068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13069         remote_ost_nodsh && skip "remote OSTs with nodsh"
13070
13071         # Sleep to avoid a cached response.
13072         #define OBD_STATFS_CACHE_SECONDS 1
13073         sleep 2
13074
13075         # Inject a 10 second delay in the OST_STATFS handler.
13076         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13077         set_nodes_failloc "$(osts_nodes)" 0x242
13078
13079         begin=$SECONDS
13080         stat --file-system $MOUNT > /dev/null
13081         end=$SECONDS
13082
13083         set_nodes_failloc "$(osts_nodes)" 0
13084
13085         if ((end - begin > 20)); then
13086             error "statfs took $((end - begin)) seconds, expected 10"
13087         fi
13088 }
13089 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13090
13091 test_119a() # bug 11737
13092 {
13093         BSIZE=$((512 * 1024))
13094         directio write $DIR/$tfile 0 1 $BSIZE
13095         # We ask to read two blocks, which is more than a file size.
13096         # directio will indicate an error when requested and actual
13097         # sizes aren't equeal (a normal situation in this case) and
13098         # print actual read amount.
13099         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13100         if [ "$NOB" != "$BSIZE" ]; then
13101                 error "read $NOB bytes instead of $BSIZE"
13102         fi
13103         rm -f $DIR/$tfile
13104 }
13105 run_test 119a "Short directIO read must return actual read amount"
13106
13107 test_119b() # bug 11737
13108 {
13109         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13110
13111         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13112         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13113         sync
13114         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13115                 error "direct read failed"
13116         rm -f $DIR/$tfile
13117 }
13118 run_test 119b "Sparse directIO read must return actual read amount"
13119
13120 test_119c() # bug 13099
13121 {
13122         BSIZE=1048576
13123         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13124         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13125         rm -f $DIR/$tfile
13126 }
13127 run_test 119c "Testing for direct read hitting hole"
13128
13129 test_119d() # bug 15950
13130 {
13131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13132
13133         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13134         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13135         BSIZE=1048576
13136         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13137         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13138         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13139         lctl set_param fail_loc=0x40d
13140         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13141         pid_dio=$!
13142         sleep 1
13143         cat $DIR/$tfile > /dev/null &
13144         lctl set_param fail_loc=0
13145         pid_reads=$!
13146         wait $pid_dio
13147         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13148         sleep 2
13149         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13150         error "the read rpcs have not completed in 2s"
13151         rm -f $DIR/$tfile
13152         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13153 }
13154 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13155
13156 test_120a() {
13157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13158         remote_mds_nodsh && skip "remote MDS with nodsh"
13159         test_mkdir -i0 -c1 $DIR/$tdir
13160         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13161                 skip_env "no early lock cancel on server"
13162
13163         lru_resize_disable mdc
13164         lru_resize_disable osc
13165         cancel_lru_locks mdc
13166         # asynchronous object destroy at MDT could cause bl ast to client
13167         cancel_lru_locks osc
13168
13169         stat $DIR/$tdir > /dev/null
13170         can1=$(do_facet mds1 \
13171                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13172                awk '/ldlm_cancel/ {print $2}')
13173         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13174                awk '/ldlm_bl_callback/ {print $2}')
13175         test_mkdir -i0 -c1 $DIR/$tdir/d1
13176         can2=$(do_facet mds1 \
13177                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13178                awk '/ldlm_cancel/ {print $2}')
13179         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13180                awk '/ldlm_bl_callback/ {print $2}')
13181         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13182         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13183         lru_resize_enable mdc
13184         lru_resize_enable osc
13185 }
13186 run_test 120a "Early Lock Cancel: mkdir test"
13187
13188 test_120b() {
13189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13190         remote_mds_nodsh && skip "remote MDS with nodsh"
13191         test_mkdir $DIR/$tdir
13192         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13193                 skip_env "no early lock cancel on server"
13194
13195         lru_resize_disable mdc
13196         lru_resize_disable osc
13197         cancel_lru_locks mdc
13198         stat $DIR/$tdir > /dev/null
13199         can1=$(do_facet $SINGLEMDS \
13200                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13201                awk '/ldlm_cancel/ {print $2}')
13202         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13203                awk '/ldlm_bl_callback/ {print $2}')
13204         touch $DIR/$tdir/f1
13205         can2=$(do_facet $SINGLEMDS \
13206                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13207                awk '/ldlm_cancel/ {print $2}')
13208         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13209                awk '/ldlm_bl_callback/ {print $2}')
13210         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13211         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13212         lru_resize_enable mdc
13213         lru_resize_enable osc
13214 }
13215 run_test 120b "Early Lock Cancel: create test"
13216
13217 test_120c() {
13218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13219         remote_mds_nodsh && skip "remote MDS with nodsh"
13220         test_mkdir -i0 -c1 $DIR/$tdir
13221         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13222                 skip "no early lock cancel on server"
13223
13224         lru_resize_disable mdc
13225         lru_resize_disable osc
13226         test_mkdir -i0 -c1 $DIR/$tdir/d1
13227         test_mkdir -i0 -c1 $DIR/$tdir/d2
13228         touch $DIR/$tdir/d1/f1
13229         cancel_lru_locks mdc
13230         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13231         can1=$(do_facet mds1 \
13232                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13233                awk '/ldlm_cancel/ {print $2}')
13234         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13235                awk '/ldlm_bl_callback/ {print $2}')
13236         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13237         can2=$(do_facet mds1 \
13238                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13239                awk '/ldlm_cancel/ {print $2}')
13240         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13241                awk '/ldlm_bl_callback/ {print $2}')
13242         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13243         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13244         lru_resize_enable mdc
13245         lru_resize_enable osc
13246 }
13247 run_test 120c "Early Lock Cancel: link test"
13248
13249 test_120d() {
13250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13251         remote_mds_nodsh && skip "remote MDS with nodsh"
13252         test_mkdir -i0 -c1 $DIR/$tdir
13253         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13254                 skip_env "no early lock cancel on server"
13255
13256         lru_resize_disable mdc
13257         lru_resize_disable osc
13258         touch $DIR/$tdir
13259         cancel_lru_locks mdc
13260         stat $DIR/$tdir > /dev/null
13261         can1=$(do_facet mds1 \
13262                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13263                awk '/ldlm_cancel/ {print $2}')
13264         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13265                awk '/ldlm_bl_callback/ {print $2}')
13266         chmod a+x $DIR/$tdir
13267         can2=$(do_facet mds1 \
13268                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13269                awk '/ldlm_cancel/ {print $2}')
13270         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13271                awk '/ldlm_bl_callback/ {print $2}')
13272         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13273         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13274         lru_resize_enable mdc
13275         lru_resize_enable osc
13276 }
13277 run_test 120d "Early Lock Cancel: setattr test"
13278
13279 test_120e() {
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13282                 skip_env "no early lock cancel on server"
13283         remote_mds_nodsh && skip "remote MDS with nodsh"
13284
13285         local dlmtrace_set=false
13286
13287         test_mkdir -i0 -c1 $DIR/$tdir
13288         lru_resize_disable mdc
13289         lru_resize_disable osc
13290         ! $LCTL get_param debug | grep -q dlmtrace &&
13291                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13292         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13293         cancel_lru_locks mdc
13294         cancel_lru_locks osc
13295         dd if=$DIR/$tdir/f1 of=/dev/null
13296         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13297         # XXX client can not do early lock cancel of OST lock
13298         # during unlink (LU-4206), so cancel osc lock now.
13299         sleep 2
13300         cancel_lru_locks osc
13301         can1=$(do_facet mds1 \
13302                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13303                awk '/ldlm_cancel/ {print $2}')
13304         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13305                awk '/ldlm_bl_callback/ {print $2}')
13306         unlink $DIR/$tdir/f1
13307         sleep 5
13308         can2=$(do_facet mds1 \
13309                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13310                awk '/ldlm_cancel/ {print $2}')
13311         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13312                awk '/ldlm_bl_callback/ {print $2}')
13313         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13314                 $LCTL dk $TMP/cancel.debug.txt
13315         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13316                 $LCTL dk $TMP/blocking.debug.txt
13317         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13318         lru_resize_enable mdc
13319         lru_resize_enable osc
13320 }
13321 run_test 120e "Early Lock Cancel: unlink test"
13322
13323 test_120f() {
13324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13325         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13326                 skip_env "no early lock cancel on server"
13327         remote_mds_nodsh && skip "remote MDS with nodsh"
13328
13329         test_mkdir -i0 -c1 $DIR/$tdir
13330         lru_resize_disable mdc
13331         lru_resize_disable osc
13332         test_mkdir -i0 -c1 $DIR/$tdir/d1
13333         test_mkdir -i0 -c1 $DIR/$tdir/d2
13334         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13335         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13336         cancel_lru_locks mdc
13337         cancel_lru_locks osc
13338         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13339         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13340         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13341         # XXX client can not do early lock cancel of OST lock
13342         # during rename (LU-4206), so cancel osc lock now.
13343         sleep 2
13344         cancel_lru_locks osc
13345         can1=$(do_facet mds1 \
13346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13347                awk '/ldlm_cancel/ {print $2}')
13348         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13349                awk '/ldlm_bl_callback/ {print $2}')
13350         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13351         sleep 5
13352         can2=$(do_facet mds1 \
13353                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13354                awk '/ldlm_cancel/ {print $2}')
13355         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13356                awk '/ldlm_bl_callback/ {print $2}')
13357         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13358         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13359         lru_resize_enable mdc
13360         lru_resize_enable osc
13361 }
13362 run_test 120f "Early Lock Cancel: rename test"
13363
13364 test_120g() {
13365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13366         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13367                 skip_env "no early lock cancel on server"
13368         remote_mds_nodsh && skip "remote MDS with nodsh"
13369
13370         lru_resize_disable mdc
13371         lru_resize_disable osc
13372         count=10000
13373         echo create $count files
13374         test_mkdir $DIR/$tdir
13375         cancel_lru_locks mdc
13376         cancel_lru_locks osc
13377         t0=$(date +%s)
13378
13379         can0=$(do_facet $SINGLEMDS \
13380                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13381                awk '/ldlm_cancel/ {print $2}')
13382         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13383                awk '/ldlm_bl_callback/ {print $2}')
13384         createmany -o $DIR/$tdir/f $count
13385         sync
13386         can1=$(do_facet $SINGLEMDS \
13387                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13388                awk '/ldlm_cancel/ {print $2}')
13389         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13390                awk '/ldlm_bl_callback/ {print $2}')
13391         t1=$(date +%s)
13392         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13393         echo rm $count files
13394         rm -r $DIR/$tdir
13395         sync
13396         can2=$(do_facet $SINGLEMDS \
13397                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13398                awk '/ldlm_cancel/ {print $2}')
13399         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13400                awk '/ldlm_bl_callback/ {print $2}')
13401         t2=$(date +%s)
13402         echo total: $count removes in $((t2-t1))
13403         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13404         sleep 2
13405         # wait for commitment of removal
13406         lru_resize_enable mdc
13407         lru_resize_enable osc
13408 }
13409 run_test 120g "Early Lock Cancel: performance test"
13410
13411 test_121() { #bug #10589
13412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13413
13414         rm -rf $DIR/$tfile
13415         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13416 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13417         lctl set_param fail_loc=0x310
13418         cancel_lru_locks osc > /dev/null
13419         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13420         lctl set_param fail_loc=0
13421         [[ $reads -eq $writes ]] ||
13422                 error "read $reads blocks, must be $writes blocks"
13423 }
13424 run_test 121 "read cancel race ========="
13425
13426 test_123a_base() { # was test 123, statahead(bug 11401)
13427         local lsx="$1"
13428
13429         SLOWOK=0
13430         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13431                 log "testing UP system. Performance may be lower than expected."
13432                 SLOWOK=1
13433         fi
13434         running_in_vm && SLOWOK=1
13435
13436         rm -rf $DIR/$tdir
13437         test_mkdir $DIR/$tdir
13438         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13439         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13440         MULT=10
13441         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13442                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13443
13444                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13445                 lctl set_param -n llite.*.statahead_max 0
13446                 lctl get_param llite.*.statahead_max
13447                 cancel_lru_locks mdc
13448                 cancel_lru_locks osc
13449                 stime=$(date +%s)
13450                 time $lsx $DIR/$tdir | wc -l
13451                 etime=$(date +%s)
13452                 delta=$((etime - stime))
13453                 log "$lsx $i files without statahead: $delta sec"
13454                 lctl set_param llite.*.statahead_max=$max
13455
13456                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13457                          awk '/statahead.wrong:/ { print $NF }')
13458                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13459                 cancel_lru_locks mdc
13460                 cancel_lru_locks osc
13461                 stime=$(date +%s)
13462                 time $lsx $DIR/$tdir | wc -l
13463                 etime=$(date +%s)
13464                 delta_sa=$((etime - stime))
13465                 log "$lsx $i files with statahead: $delta_sa sec"
13466                 lctl get_param -n llite.*.statahead_stats
13467                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13468                          awk '/statahead.wrong:/ { print $NF }')
13469
13470                 [[ $swrong -lt $ewrong ]] &&
13471                         log "statahead was stopped, maybe too many locks held!"
13472                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13473
13474                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13475                         max=$(lctl get_param -n llite.*.statahead_max |
13476                                 head -n 1)
13477                         lctl set_param -n llite.*.statahead_max 0
13478                         lctl get_param llite.*.statahead_max
13479                         cancel_lru_locks mdc
13480                         cancel_lru_locks osc
13481                         stime=$(date +%s)
13482                         time $lsx $DIR/$tdir | wc -l
13483                         etime=$(date +%s)
13484                         delta=$((etime - stime))
13485                         log "$lsx $i files again without statahead: $delta sec"
13486                         lctl set_param llite.*.statahead_max=$max
13487                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13488                                 if [ $SLOWOK -eq 0 ]; then
13489                                         error "$lsx $i files is slower with statahead!"
13490                                 else
13491                                         log "$lsx $i files is slower with statahead!"
13492                                 fi
13493                                 break
13494                         fi
13495                 fi
13496
13497                 [ $delta -gt 20 ] && break
13498                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13499                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13500         done
13501         log "$lsx done"
13502
13503         stime=$(date +%s)
13504         rm -r $DIR/$tdir
13505         sync
13506         etime=$(date +%s)
13507         delta=$((etime - stime))
13508         log "rm -r $DIR/$tdir/: $delta seconds"
13509         log "rm done"
13510         lctl get_param -n llite.*.statahead_stats
13511 }
13512
13513 test_123aa() {
13514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13515
13516         test_123a_base "ls -l"
13517 }
13518 run_test 123aa "verify statahead work"
13519
13520 test_123ab() {
13521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13522
13523         statx_supported || skip_env "Test must be statx() syscall supported"
13524
13525         test_123a_base "$STATX -l"
13526 }
13527 run_test 123ab "verify statahead work by using statx"
13528
13529 test_123ac() {
13530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13531
13532         statx_supported || skip_env "Test must be statx() syscall supported"
13533
13534         local rpcs_before
13535         local rpcs_after
13536         local agl_before
13537         local agl_after
13538
13539         cancel_lru_locks $OSC
13540         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13541         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13542                      awk '/agl.total:/ { print $NF }')
13543         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13544         test_123a_base "$STATX --cached=always -D"
13545         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13546                     awk '/agl.total:/ { print $NF }')
13547         [ $agl_before -eq $agl_after ] ||
13548                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13549         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13550         [ $rpcs_after -eq $rpcs_before ] ||
13551                 error "$STATX should not send glimpse RPCs to $OSC"
13552 }
13553 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13554
13555 test_123b () { # statahead(bug 15027)
13556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13557
13558         test_mkdir $DIR/$tdir
13559         createmany -o $DIR/$tdir/$tfile-%d 1000
13560
13561         cancel_lru_locks mdc
13562         cancel_lru_locks osc
13563
13564 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13565         lctl set_param fail_loc=0x80000803
13566         ls -lR $DIR/$tdir > /dev/null
13567         log "ls done"
13568         lctl set_param fail_loc=0x0
13569         lctl get_param -n llite.*.statahead_stats
13570         rm -r $DIR/$tdir
13571         sync
13572
13573 }
13574 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13575
13576 test_123c() {
13577         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13578
13579         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13580         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13581         touch $DIR/$tdir.1/{1..3}
13582         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13583
13584         remount_client $MOUNT
13585
13586         $MULTIOP $DIR/$tdir.0 Q
13587
13588         # let statahead to complete
13589         ls -l $DIR/$tdir.0 > /dev/null
13590
13591         testid=$(echo $TESTNAME | tr '_' ' ')
13592         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13593                 error "statahead warning" || true
13594 }
13595 run_test 123c "Can not initialize inode warning on DNE statahead"
13596
13597 test_123d() {
13598         local num=100
13599         local swrong
13600         local ewrong
13601
13602         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13603         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13604                 error "setdirstripe $DIR/$tdir failed"
13605         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13606         remount_client $MOUNT
13607         $LCTL get_param llite.*.statahead_max
13608         $LCTL set_param llite.*.statahead_stats=0 ||
13609                 error "clear statahead_stats failed"
13610         swrong=$(lctl get_param -n llite.*.statahead_stats |
13611                  awk '/statahead.wrong:/ { print $NF }')
13612         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13613         # wait for statahead thread finished to update hit/miss stats.
13614         sleep 1
13615         $LCTL get_param -n llite.*.statahead_stats
13616         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13617                  awk '/statahead.wrong:/ { print $NF }')
13618         (( $swrong == $ewrong )) ||
13619                 log "statahead was stopped, maybe too many locks held!"
13620 }
13621 run_test 123d "Statahead on striped directories works correctly"
13622
13623 test_124a() {
13624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13625         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13626                 skip_env "no lru resize on server"
13627
13628         local NR=2000
13629
13630         test_mkdir $DIR/$tdir
13631
13632         log "create $NR files at $DIR/$tdir"
13633         createmany -o $DIR/$tdir/f $NR ||
13634                 error "failed to create $NR files in $DIR/$tdir"
13635
13636         cancel_lru_locks mdc
13637         ls -l $DIR/$tdir > /dev/null
13638
13639         local NSDIR=""
13640         local LRU_SIZE=0
13641         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13642                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13643                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13644                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13645                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13646                         log "NSDIR=$NSDIR"
13647                         log "NS=$(basename $NSDIR)"
13648                         break
13649                 fi
13650         done
13651
13652         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13653                 skip "Not enough cached locks created!"
13654         fi
13655         log "LRU=$LRU_SIZE"
13656
13657         local SLEEP=30
13658
13659         # We know that lru resize allows one client to hold $LIMIT locks
13660         # for 10h. After that locks begin to be killed by client.
13661         local MAX_HRS=10
13662         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13663         log "LIMIT=$LIMIT"
13664         if [ $LIMIT -lt $LRU_SIZE ]; then
13665                 skip "Limit is too small $LIMIT"
13666         fi
13667
13668         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13669         # killing locks. Some time was spent for creating locks. This means
13670         # that up to the moment of sleep finish we must have killed some of
13671         # them (10-100 locks). This depends on how fast ther were created.
13672         # Many of them were touched in almost the same moment and thus will
13673         # be killed in groups.
13674         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13675
13676         # Use $LRU_SIZE_B here to take into account real number of locks
13677         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13678         local LRU_SIZE_B=$LRU_SIZE
13679         log "LVF=$LVF"
13680         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13681         log "OLD_LVF=$OLD_LVF"
13682         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13683
13684         # Let's make sure that we really have some margin. Client checks
13685         # cached locks every 10 sec.
13686         SLEEP=$((SLEEP+20))
13687         log "Sleep ${SLEEP} sec"
13688         local SEC=0
13689         while ((SEC<$SLEEP)); do
13690                 echo -n "..."
13691                 sleep 5
13692                 SEC=$((SEC+5))
13693                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13694                 echo -n "$LRU_SIZE"
13695         done
13696         echo ""
13697         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13698         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13699
13700         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13701                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13702                 unlinkmany $DIR/$tdir/f $NR
13703                 return
13704         }
13705
13706         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13707         log "unlink $NR files at $DIR/$tdir"
13708         unlinkmany $DIR/$tdir/f $NR
13709 }
13710 run_test 124a "lru resize ======================================="
13711
13712 get_max_pool_limit()
13713 {
13714         local limit=$($LCTL get_param \
13715                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13716         local max=0
13717         for l in $limit; do
13718                 if [[ $l -gt $max ]]; then
13719                         max=$l
13720                 fi
13721         done
13722         echo $max
13723 }
13724
13725 test_124b() {
13726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13727         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13728                 skip_env "no lru resize on server"
13729
13730         LIMIT=$(get_max_pool_limit)
13731
13732         NR=$(($(default_lru_size)*20))
13733         if [[ $NR -gt $LIMIT ]]; then
13734                 log "Limit lock number by $LIMIT locks"
13735                 NR=$LIMIT
13736         fi
13737
13738         IFree=$(mdsrate_inodes_available)
13739         if [ $IFree -lt $NR ]; then
13740                 log "Limit lock number by $IFree inodes"
13741                 NR=$IFree
13742         fi
13743
13744         lru_resize_disable mdc
13745         test_mkdir -p $DIR/$tdir/disable_lru_resize
13746
13747         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13748         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13749         cancel_lru_locks mdc
13750         stime=`date +%s`
13751         PID=""
13752         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13753         PID="$PID $!"
13754         sleep 2
13755         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13756         PID="$PID $!"
13757         sleep 2
13758         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13759         PID="$PID $!"
13760         wait $PID
13761         etime=`date +%s`
13762         nolruresize_delta=$((etime-stime))
13763         log "ls -la time: $nolruresize_delta seconds"
13764         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13765         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13766
13767         lru_resize_enable mdc
13768         test_mkdir -p $DIR/$tdir/enable_lru_resize
13769
13770         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13771         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13772         cancel_lru_locks mdc
13773         stime=`date +%s`
13774         PID=""
13775         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13776         PID="$PID $!"
13777         sleep 2
13778         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13779         PID="$PID $!"
13780         sleep 2
13781         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13782         PID="$PID $!"
13783         wait $PID
13784         etime=`date +%s`
13785         lruresize_delta=$((etime-stime))
13786         log "ls -la time: $lruresize_delta seconds"
13787         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13788
13789         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13790                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13791         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13792                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13793         else
13794                 log "lru resize performs the same with no lru resize"
13795         fi
13796         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13797 }
13798 run_test 124b "lru resize (performance test) ======================="
13799
13800 test_124c() {
13801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13802         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13803                 skip_env "no lru resize on server"
13804
13805         # cache ununsed locks on client
13806         local nr=100
13807         cancel_lru_locks mdc
13808         test_mkdir $DIR/$tdir
13809         createmany -o $DIR/$tdir/f $nr ||
13810                 error "failed to create $nr files in $DIR/$tdir"
13811         ls -l $DIR/$tdir > /dev/null
13812
13813         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13814         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13815         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13816         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13817         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13818
13819         # set lru_max_age to 1 sec
13820         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13821         echo "sleep $((recalc_p * 2)) seconds..."
13822         sleep $((recalc_p * 2))
13823
13824         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13825         # restore lru_max_age
13826         $LCTL set_param -n $nsdir.lru_max_age $max_age
13827         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13828         unlinkmany $DIR/$tdir/f $nr
13829 }
13830 run_test 124c "LRUR cancel very aged locks"
13831
13832 test_124d() {
13833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13834         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13835                 skip_env "no lru resize on server"
13836
13837         # cache ununsed locks on client
13838         local nr=100
13839
13840         lru_resize_disable mdc
13841         stack_trap "lru_resize_enable mdc" EXIT
13842
13843         cancel_lru_locks mdc
13844
13845         # asynchronous object destroy at MDT could cause bl ast to client
13846         test_mkdir $DIR/$tdir
13847         createmany -o $DIR/$tdir/f $nr ||
13848                 error "failed to create $nr files in $DIR/$tdir"
13849         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13850
13851         ls -l $DIR/$tdir > /dev/null
13852
13853         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13854         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13855         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13856         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13857
13858         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13859
13860         # set lru_max_age to 1 sec
13861         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13862         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13863
13864         echo "sleep $((recalc_p * 2)) seconds..."
13865         sleep $((recalc_p * 2))
13866
13867         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13868
13869         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13870 }
13871 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13872
13873 test_125() { # 13358
13874         $LCTL get_param -n llite.*.client_type | grep -q local ||
13875                 skip "must run as local client"
13876         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13877                 skip_env "must have acl enabled"
13878         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13879
13880         test_mkdir $DIR/$tdir
13881         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13882         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13883                 error "setfacl $DIR/$tdir failed"
13884         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13885 }
13886 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13887
13888 test_126() { # bug 12829/13455
13889         $GSS && skip_env "must run as gss disabled"
13890         $LCTL get_param -n llite.*.client_type | grep -q local ||
13891                 skip "must run as local client"
13892         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13893
13894         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13895         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13896         rm -f $DIR/$tfile
13897         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13898 }
13899 run_test 126 "check that the fsgid provided by the client is taken into account"
13900
13901 test_127a() { # bug 15521
13902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13903         local name count samp unit min max sum sumsq
13904         local tmpfile=$TMP/$tfile.tmp
13905
13906         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13907         echo "stats before reset"
13908         stack_trap "rm -f $tmpfile"
13909         local now=$(date +%s)
13910
13911         $LCTL get_param osc.*.stats | tee $tmpfile
13912
13913         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13914         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13915         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13916         local uptime=$(awk '{ print $1 }' /proc/uptime)
13917
13918         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13919         (( ${snapshot_time%\.*} >= $now - 5 &&
13920            ${snapshot_time%\.*} <= $now + 5 )) ||
13921                 error "snapshot_time=$snapshot_time != now=$now"
13922         # elapsed _should_ be from mount, but at least less than uptime
13923         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13924                 error "elapsed=$elapsed > uptime=$uptime"
13925         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13926            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13927                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13928
13929         $LCTL set_param osc.*.stats=0
13930         local reset=$(date +%s)
13931         local fsize=$((2048 * 1024))
13932
13933         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13934         cancel_lru_locks osc
13935         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13936
13937         now=$(date +%s)
13938         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13939         while read name count samp unit min max sum sumsq; do
13940                 [[ "$samp" == "samples" ]] || continue
13941
13942                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13943                 [ ! $min ] && error "Missing min value for $name proc entry"
13944                 eval $name=$count || error "Wrong proc format"
13945
13946                 case $name in
13947                 read_bytes|write_bytes)
13948                         [[ "$unit" =~ "bytes" ]] ||
13949                                 error "unit is not 'bytes': $unit"
13950                         (( $min >= 4096 )) || error "min is too small: $min"
13951                         (( $min <= $fsize )) || error "min is too big: $min"
13952                         (( $max >= 4096 )) || error "max is too small: $max"
13953                         (( $max <= $fsize )) || error "max is too big: $max"
13954                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13955                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13956                                 error "sumsquare is too small: $sumsq"
13957                         (( $sumsq <= $fsize * $fsize )) ||
13958                                 error "sumsquare is too big: $sumsq"
13959                         ;;
13960                 ost_read|ost_write)
13961                         [[ "$unit" =~ "usec" ]] ||
13962                                 error "unit is not 'usec': $unit"
13963                         ;;
13964                 *)      ;;
13965                 esac
13966         done < $tmpfile
13967
13968         #check that we actually got some stats
13969         [ "$read_bytes" ] || error "Missing read_bytes stats"
13970         [ "$write_bytes" ] || error "Missing write_bytes stats"
13971         [ "$read_bytes" != 0 ] || error "no read done"
13972         [ "$write_bytes" != 0 ] || error "no write done"
13973
13974         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13975         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13976         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13977
13978         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13979         (( ${snapshot_time%\.*} >= $now - 5 &&
13980            ${snapshot_time%\.*} <= $now + 5 )) ||
13981                 error "reset snapshot_time=$snapshot_time != now=$now"
13982         # elapsed should be from time of stats reset
13983         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13984            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13985                 error "reset elapsed=$elapsed > $now - $reset"
13986         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13987            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13988                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13989 }
13990 run_test 127a "verify the client stats are sane"
13991
13992 test_127b() { # bug LU-333
13993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13994         local name count samp unit min max sum sumsq
13995
13996         echo "stats before reset"
13997         $LCTL get_param llite.*.stats
13998         $LCTL set_param llite.*.stats=0
13999
14000         # perform 2 reads and writes so MAX is different from SUM.
14001         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14002         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14003         cancel_lru_locks osc
14004         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14005         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14006
14007         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14008         stack_trap "rm -f $TMP/$tfile.tmp"
14009         while read name count samp unit min max sum sumsq; do
14010                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14011                 eval $name=$count || error "Wrong proc format"
14012
14013                 case $name in
14014                 read_bytes|write_bytes)
14015                         [[ "$unit" =~ "bytes" ]] ||
14016                                 error "unit is not 'bytes': $unit"
14017                         (( $count == 2 )) || error "count is not 2: $count"
14018                         (( $min == $PAGE_SIZE )) ||
14019                                 error "min is not $PAGE_SIZE: $min"
14020                         (( $max == $PAGE_SIZE )) ||
14021                                 error "max is not $PAGE_SIZE: $max"
14022                         (( $sum == $PAGE_SIZE * 2 )) ||
14023                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14024                         ;;
14025                 read|write)
14026                         [[ "$unit" =~ "usec" ]] ||
14027                                 error "unit is not 'usec': $unit"
14028                         ;;
14029                 *)      ;;
14030                 esac
14031         done < $TMP/$tfile.tmp
14032
14033         #check that we actually got some stats
14034         [ "$read_bytes" ] || error "Missing read_bytes stats"
14035         [ "$write_bytes" ] || error "Missing write_bytes stats"
14036         [ "$read_bytes" != 0 ] || error "no read done"
14037         [ "$write_bytes" != 0 ] || error "no write done"
14038 }
14039 run_test 127b "verify the llite client stats are sane"
14040
14041 test_127c() { # LU-12394
14042         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14043         local size
14044         local bsize
14045         local reads
14046         local writes
14047         local count
14048
14049         $LCTL set_param llite.*.extents_stats=1
14050         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14051
14052         # Use two stripes so there is enough space in default config
14053         $LFS setstripe -c 2 $DIR/$tfile
14054
14055         # Extent stats start at 0-4K and go in power of two buckets
14056         # LL_HIST_START = 12 --> 2^12 = 4K
14057         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14058         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14059         # small configs
14060         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14061                 do
14062                 # Write and read, 2x each, second time at a non-zero offset
14063                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14064                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14065                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14066                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14067                 rm -f $DIR/$tfile
14068         done
14069
14070         $LCTL get_param llite.*.extents_stats
14071
14072         count=2
14073         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14074                 do
14075                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14076                                 grep -m 1 $bsize)
14077                 reads=$(echo $bucket | awk '{print $5}')
14078                 writes=$(echo $bucket | awk '{print $9}')
14079                 [ "$reads" -eq $count ] ||
14080                         error "$reads reads in < $bsize bucket, expect $count"
14081                 [ "$writes" -eq $count ] ||
14082                         error "$writes writes in < $bsize bucket, expect $count"
14083         done
14084
14085         # Test mmap write and read
14086         $LCTL set_param llite.*.extents_stats=c
14087         size=512
14088         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14089         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14090         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14091
14092         $LCTL get_param llite.*.extents_stats
14093
14094         count=$(((size*1024) / PAGE_SIZE))
14095
14096         bsize=$((2 * PAGE_SIZE / 1024))K
14097
14098         bucket=$($LCTL get_param -n llite.*.extents_stats |
14099                         grep -m 1 $bsize)
14100         reads=$(echo $bucket | awk '{print $5}')
14101         writes=$(echo $bucket | awk '{print $9}')
14102         # mmap writes fault in the page first, creating an additonal read
14103         [ "$reads" -eq $((2 * count)) ] ||
14104                 error "$reads reads in < $bsize bucket, expect $count"
14105         [ "$writes" -eq $count ] ||
14106                 error "$writes writes in < $bsize bucket, expect $count"
14107 }
14108 run_test 127c "test llite extent stats with regular & mmap i/o"
14109
14110 test_128() { # bug 15212
14111         touch $DIR/$tfile
14112         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14113                 find $DIR/$tfile
14114                 find $DIR/$tfile
14115         EOF
14116
14117         result=$(grep error $TMP/$tfile.log)
14118         rm -f $DIR/$tfile $TMP/$tfile.log
14119         [ -z "$result" ] ||
14120                 error "consecutive find's under interactive lfs failed"
14121 }
14122 run_test 128 "interactive lfs for 2 consecutive find's"
14123
14124 set_dir_limits () {
14125         local mntdev
14126         local canondev
14127         local node
14128
14129         local ldproc=/proc/fs/ldiskfs
14130         local facets=$(get_facets MDS)
14131
14132         for facet in ${facets//,/ }; do
14133                 canondev=$(ldiskfs_canon \
14134                            *.$(convert_facet2label $facet).mntdev $facet)
14135                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14136                         ldproc=/sys/fs/ldiskfs
14137                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14138                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14139         done
14140 }
14141
14142 check_mds_dmesg() {
14143         local facets=$(get_facets MDS)
14144         for facet in ${facets//,/ }; do
14145                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14146         done
14147         return 1
14148 }
14149
14150 test_129() {
14151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14152         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14153                 skip "Need MDS version with at least 2.5.56"
14154         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14155                 skip_env "ldiskfs only test"
14156         fi
14157         remote_mds_nodsh && skip "remote MDS with nodsh"
14158
14159         local ENOSPC=28
14160         local has_warning=false
14161
14162         rm -rf $DIR/$tdir
14163         mkdir -p $DIR/$tdir
14164
14165         # block size of mds1
14166         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14167         set_dir_limits $maxsize $((maxsize * 6 / 8))
14168         stack_trap "set_dir_limits 0 0"
14169         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14170         local dirsize=$(stat -c%s "$DIR/$tdir")
14171         local nfiles=0
14172         while (( $dirsize <= $maxsize )); do
14173                 $MCREATE $DIR/$tdir/file_base_$nfiles
14174                 rc=$?
14175                 # check two errors:
14176                 # ENOSPC for ext4 max_dir_size, which has been used since
14177                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14178                 if (( rc == ENOSPC )); then
14179                         set_dir_limits 0 0
14180                         echo "rc=$rc returned as expected after $nfiles files"
14181
14182                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14183                                 error "create failed w/o dir size limit"
14184
14185                         # messages may be rate limited if test is run repeatedly
14186                         check_mds_dmesg '"is approaching max"' ||
14187                                 echo "warning message should be output"
14188                         check_mds_dmesg '"has reached max"' ||
14189                                 echo "reached message should be output"
14190
14191                         dirsize=$(stat -c%s "$DIR/$tdir")
14192
14193                         [[ $dirsize -ge $maxsize ]] && return 0
14194                         error "dirsize $dirsize < $maxsize after $nfiles files"
14195                 elif (( rc != 0 )); then
14196                         break
14197                 fi
14198                 nfiles=$((nfiles + 1))
14199                 dirsize=$(stat -c%s "$DIR/$tdir")
14200         done
14201
14202         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14203 }
14204 run_test 129 "test directory size limit ========================"
14205
14206 OLDIFS="$IFS"
14207 cleanup_130() {
14208         trap 0
14209         IFS="$OLDIFS"
14210 }
14211
14212 test_130a() {
14213         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14214         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14215
14216         trap cleanup_130 EXIT RETURN
14217
14218         local fm_file=$DIR/$tfile
14219         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14220         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14221                 error "dd failed for $fm_file"
14222
14223         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14224         filefrag -ves $fm_file
14225         local rc=$?
14226         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14227                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14228         (( $rc == 0 )) || error "filefrag $fm_file failed"
14229
14230         filefrag_op=$(filefrag -ve -k $fm_file |
14231                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14232         local lun=$($LFS getstripe -i $fm_file)
14233
14234         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14235         IFS=$'\n'
14236         local tot_len=0
14237         for line in $filefrag_op; do
14238                 local frag_lun=$(echo $line | cut -d: -f5)
14239                 local ext_len=$(echo $line | cut -d: -f4)
14240
14241                 if (( $frag_lun != $lun )); then
14242                         error "FIEMAP on 1-stripe file($fm_file) failed"
14243                         return
14244                 fi
14245                 (( tot_len += ext_len ))
14246         done
14247
14248         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14249                 error "FIEMAP on 1-stripe file($fm_file) failed"
14250                 return
14251         fi
14252
14253         echo "FIEMAP on single striped file succeeded"
14254 }
14255 run_test 130a "FIEMAP (1-stripe file)"
14256
14257 test_130b() {
14258         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14259
14260         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14261         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14262         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14263                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14264
14265         trap cleanup_130 EXIT RETURN
14266
14267         local fm_file=$DIR/$tfile
14268         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14269                 error "setstripe on $fm_file"
14270
14271         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14272                 error "dd failed on $fm_file"
14273
14274         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14275         filefrag_op=$(filefrag -ve -k $fm_file |
14276                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14277
14278         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14279                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14280
14281         IFS=$'\n'
14282         local tot_len=0
14283         local num_luns=1
14284
14285         for line in $filefrag_op; do
14286                 local frag_lun=$(echo $line | cut -d: -f5 |
14287                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14288                 local ext_len=$(echo $line | cut -d: -f4)
14289                 if (( $frag_lun != $last_lun )); then
14290                         if (( tot_len != 1024 )); then
14291                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14292                                 return
14293                         else
14294                                 (( num_luns += 1 ))
14295                                 tot_len=0
14296                         fi
14297                 fi
14298                 (( tot_len += ext_len ))
14299                 last_lun=$frag_lun
14300         done
14301         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14302                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14303                 return
14304         fi
14305
14306         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14307 }
14308 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14309
14310 test_130c() {
14311         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14312
14313         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14314         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14315         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14316                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14317
14318         trap cleanup_130 EXIT RETURN
14319
14320         local fm_file=$DIR/$tfile
14321         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14322
14323         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14324                 error "dd failed on $fm_file"
14325
14326         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14327         filefrag_op=$(filefrag -ve -k $fm_file |
14328                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14329
14330         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14331                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14332
14333         IFS=$'\n'
14334         local tot_len=0
14335         local num_luns=1
14336         for line in $filefrag_op; do
14337                 local frag_lun=$(echo $line | cut -d: -f5 |
14338                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14339                 local ext_len=$(echo $line | cut -d: -f4)
14340                 if (( $frag_lun != $last_lun )); then
14341                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14342                         if (( logical != 512 )); then
14343                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14344                                 return
14345                         fi
14346                         if (( tot_len != 512 )); then
14347                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14348                                 return
14349                         else
14350                                 (( num_luns += 1 ))
14351                                 tot_len=0
14352                         fi
14353                 fi
14354                 (( tot_len += ext_len ))
14355                 last_lun=$frag_lun
14356         done
14357         if (( num_luns != 2 || tot_len != 512 )); then
14358                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14359                 return
14360         fi
14361
14362         echo "FIEMAP on 2-stripe file with hole succeeded"
14363 }
14364 run_test 130c "FIEMAP (2-stripe file with hole)"
14365
14366 test_130d() {
14367         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14368
14369         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14370         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14371         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14372                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14373
14374         trap cleanup_130 EXIT RETURN
14375
14376         local fm_file=$DIR/$tfile
14377         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14378                         error "setstripe on $fm_file"
14379
14380         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14381         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14382                 error "dd failed on $fm_file"
14383
14384         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14385         filefrag_op=$(filefrag -ve -k $fm_file |
14386                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14387
14388         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14389                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14390
14391         IFS=$'\n'
14392         local tot_len=0
14393         local num_luns=1
14394         for line in $filefrag_op; do
14395                 local frag_lun=$(echo $line | cut -d: -f5 |
14396                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14397                 local ext_len=$(echo $line | cut -d: -f4)
14398                 if (( $frag_lun != $last_lun )); then
14399                         if (( tot_len != 1024 )); then
14400                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14401                                 return
14402                         else
14403                                 (( num_luns += 1 ))
14404                                 local tot_len=0
14405                         fi
14406                 fi
14407                 (( tot_len += ext_len ))
14408                 last_lun=$frag_lun
14409         done
14410         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14411                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14412                 return
14413         fi
14414
14415         echo "FIEMAP on N-stripe file succeeded"
14416 }
14417 run_test 130d "FIEMAP (N-stripe file)"
14418
14419 test_130e() {
14420         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14421
14422         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14423         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14424         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14425                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14426
14427         trap cleanup_130 EXIT RETURN
14428
14429         local fm_file=$DIR/$tfile
14430         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14431
14432         local num_blks=512
14433         local expected_len=$(( (num_blks / 2) * 64 ))
14434         for ((i = 0; i < $num_blks; i++)); do
14435                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14436                         conv=notrunc > /dev/null 2>&1
14437         done
14438
14439         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14440         filefrag_op=$(filefrag -ve -k $fm_file |
14441                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14442
14443         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14444
14445         IFS=$'\n'
14446         local tot_len=0
14447         local num_luns=1
14448         for line in $filefrag_op; do
14449                 local frag_lun=$(echo $line | cut -d: -f5)
14450                 local ext_len=$(echo $line | cut -d: -f4)
14451                 if (( $frag_lun != $last_lun )); then
14452                         if (( tot_len != $expected_len )); then
14453                                 error "OST$last_lun $tot_len != $expected_len"
14454                         else
14455                                 (( num_luns += 1 ))
14456                                 tot_len=0
14457                         fi
14458                 fi
14459                 (( tot_len += ext_len ))
14460                 last_lun=$frag_lun
14461         done
14462         if (( num_luns != 2 || tot_len != $expected_len )); then
14463                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14464         fi
14465
14466         echo "FIEMAP with continuation calls succeeded"
14467 }
14468 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14469
14470 test_130f() {
14471         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14472         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14473         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14474                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14475
14476         local fm_file=$DIR/$tfile
14477         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14478                 error "multiop create with lov_delay_create on $fm_file"
14479
14480         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14481         filefrag_extents=$(filefrag -vek $fm_file |
14482                            awk '/extents? found/ { print $2 }')
14483         if (( $filefrag_extents != 0 )); then
14484                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14485         fi
14486
14487         rm -f $fm_file
14488 }
14489 run_test 130f "FIEMAP (unstriped file)"
14490
14491 test_130g() {
14492         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14493                 skip "Need MDS version with at least 2.12.53 for overstriping"
14494         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14495         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14496         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14497                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14498
14499         local file=$DIR/$tfile
14500         local nr=$((OSTCOUNT * 100))
14501
14502         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14503
14504         stack_trap "rm -f $file"
14505         dd if=/dev/zero of=$file count=$nr bs=1M
14506         sync
14507         nr=$($LFS getstripe -c $file)
14508
14509         local extents=$(filefrag -v $file |
14510                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14511
14512         echo "filefrag list $extents extents in file with stripecount $nr"
14513         if (( extents < nr )); then
14514                 $LFS getstripe $file
14515                 filefrag -v $file
14516                 error "filefrag printed $extents < $nr extents"
14517         fi
14518 }
14519 run_test 130g "FIEMAP (overstripe file)"
14520
14521 # Test for writev/readv
14522 test_131a() {
14523         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14524                 error "writev test failed"
14525         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14526                 error "readv failed"
14527         rm -f $DIR/$tfile
14528 }
14529 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14530
14531 test_131b() {
14532         local fsize=$((524288 + 1048576 + 1572864))
14533         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14534                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14535                         error "append writev test failed"
14536
14537         ((fsize += 1572864 + 1048576))
14538         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14539                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14540                         error "append writev test failed"
14541         rm -f $DIR/$tfile
14542 }
14543 run_test 131b "test append writev"
14544
14545 test_131c() {
14546         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14547         error "NOT PASS"
14548 }
14549 run_test 131c "test read/write on file w/o objects"
14550
14551 test_131d() {
14552         rwv -f $DIR/$tfile -w -n 1 1572864
14553         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14554         if [ "$NOB" != 1572864 ]; then
14555                 error "Short read filed: read $NOB bytes instead of 1572864"
14556         fi
14557         rm -f $DIR/$tfile
14558 }
14559 run_test 131d "test short read"
14560
14561 test_131e() {
14562         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14563         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14564         error "read hitting hole failed"
14565         rm -f $DIR/$tfile
14566 }
14567 run_test 131e "test read hitting hole"
14568
14569 check_stats() {
14570         local facet=$1
14571         local op=$2
14572         local want=${3:-0}
14573         local res
14574
14575         # open             11 samples [usecs] 468 4793 13658 35791898
14576         case $facet in
14577         mds*) res=($(do_facet $facet \
14578                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14579                  ;;
14580         ost*) res=($(do_facet $facet \
14581                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14582                  ;;
14583         *) error "Wrong facet '$facet'" ;;
14584         esac
14585         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14586         # if $want is zero, it means any stat increment is ok.
14587         if (( $want > 0 )); then
14588                 local count=${res[1]}
14589
14590                 if (( $count != $want )); then
14591                         if [[ $facet =~ "mds" ]]; then
14592                                 do_nodes $(comma_list $(mdts_nodes)) \
14593                                         $LCTL get_param mdt.*.md_stats
14594                         else
14595                                 do_nodes $(comma_list $(osts-nodes)) \
14596                                         $LCTL get_param obdfilter.*.stats
14597                         fi
14598                         error "The $op counter on $facet is $count, not $want"
14599                 fi
14600         fi
14601 }
14602
14603 test_133a() {
14604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14605         remote_ost_nodsh && skip "remote OST with nodsh"
14606         remote_mds_nodsh && skip "remote MDS with nodsh"
14607         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14608                 skip_env "MDS doesn't support rename stats"
14609
14610         local testdir=$DIR/${tdir}/stats_testdir
14611
14612         mkdir -p $DIR/${tdir}
14613
14614         # clear stats.
14615         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14616         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14617
14618         # verify mdt stats first.
14619         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14620         check_stats $SINGLEMDS "mkdir" 1
14621
14622         # clear "open" from "lfs mkdir" above
14623         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14624         touch ${testdir}/${tfile} || error "touch failed"
14625         check_stats $SINGLEMDS "open" 1
14626         check_stats $SINGLEMDS "close" 1
14627         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14628                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14629                 check_stats $SINGLEMDS "mknod" 2
14630         }
14631         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14632         check_stats $SINGLEMDS "unlink" 1
14633         rm -f ${testdir}/${tfile} || error "file remove failed"
14634         check_stats $SINGLEMDS "unlink" 2
14635
14636         # remove working dir and check mdt stats again.
14637         rmdir ${testdir} || error "rmdir failed"
14638         check_stats $SINGLEMDS "rmdir" 1
14639
14640         local testdir1=$DIR/${tdir}/stats_testdir1
14641         mkdir_on_mdt0 -p ${testdir}
14642         mkdir_on_mdt0 -p ${testdir1}
14643         touch ${testdir1}/test1
14644         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14645         check_stats $SINGLEMDS "crossdir_rename" 1
14646
14647         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14648         check_stats $SINGLEMDS "samedir_rename" 1
14649
14650         rm -rf $DIR/${tdir}
14651 }
14652 run_test 133a "Verifying MDT stats ========================================"
14653
14654 test_133b() {
14655         local res
14656
14657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14658         remote_ost_nodsh && skip "remote OST with nodsh"
14659         remote_mds_nodsh && skip "remote MDS with nodsh"
14660
14661         local testdir=$DIR/${tdir}/stats_testdir
14662
14663         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14664         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14665         touch ${testdir}/${tfile} || error "touch failed"
14666         cancel_lru_locks mdc
14667
14668         # clear stats.
14669         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14670         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14671
14672         # extra mdt stats verification.
14673         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14674         check_stats $SINGLEMDS "setattr" 1
14675         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14676         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14677         then            # LU-1740
14678                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14679                 check_stats $SINGLEMDS "getattr" 1
14680         fi
14681         rm -rf $DIR/${tdir}
14682
14683         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14684         # so the check below is not reliable
14685         [ $MDSCOUNT -eq 1 ] || return 0
14686
14687         # Sleep to avoid a cached response.
14688         #define OBD_STATFS_CACHE_SECONDS 1
14689         sleep 2
14690         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14691         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14692         $LFS df || error "lfs failed"
14693         check_stats $SINGLEMDS "statfs" 1
14694
14695         # check aggregated statfs (LU-10018)
14696         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14697                 return 0
14698         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14699                 return 0
14700         sleep 2
14701         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14702         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14703         df $DIR
14704         check_stats $SINGLEMDS "statfs" 1
14705
14706         # We want to check that the client didn't send OST_STATFS to
14707         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14708         # extra care is needed here.
14709         if remote_mds; then
14710                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14711                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14712
14713                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14714                 [ "$res" ] && error "OST got STATFS"
14715         fi
14716
14717         return 0
14718 }
14719 run_test 133b "Verifying extra MDT stats =================================="
14720
14721 test_133c() {
14722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14723         remote_ost_nodsh && skip "remote OST with nodsh"
14724         remote_mds_nodsh && skip "remote MDS with nodsh"
14725
14726         local testdir=$DIR/$tdir/stats_testdir
14727
14728         test_mkdir -p $testdir
14729
14730         # verify obdfilter stats.
14731         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14732         sync
14733         cancel_lru_locks osc
14734         wait_delete_completed
14735
14736         # clear stats.
14737         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14738         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14739
14740         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14741                 error "dd failed"
14742         sync
14743         cancel_lru_locks osc
14744         check_stats ost1 "write" 1
14745
14746         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14747         check_stats ost1 "read" 1
14748
14749         > $testdir/$tfile || error "truncate failed"
14750         check_stats ost1 "punch" 1
14751
14752         rm -f $testdir/$tfile || error "file remove failed"
14753         wait_delete_completed
14754         check_stats ost1 "destroy" 1
14755
14756         rm -rf $DIR/$tdir
14757 }
14758 run_test 133c "Verifying OST stats ========================================"
14759
14760 order_2() {
14761         local value=$1
14762         local orig=$value
14763         local order=1
14764
14765         while [ $value -ge 2 ]; do
14766                 order=$((order*2))
14767                 value=$((value/2))
14768         done
14769
14770         if [ $orig -gt $order ]; then
14771                 order=$((order*2))
14772         fi
14773         echo $order
14774 }
14775
14776 size_in_KMGT() {
14777     local value=$1
14778     local size=('K' 'M' 'G' 'T');
14779     local i=0
14780     local size_string=$value
14781
14782     while [ $value -ge 1024 ]; do
14783         if [ $i -gt 3 ]; then
14784             #T is the biggest unit we get here, if that is bigger,
14785             #just return XXXT
14786             size_string=${value}T
14787             break
14788         fi
14789         value=$((value >> 10))
14790         if [ $value -lt 1024 ]; then
14791             size_string=${value}${size[$i]}
14792             break
14793         fi
14794         i=$((i + 1))
14795     done
14796
14797     echo $size_string
14798 }
14799
14800 get_rename_size() {
14801         local size=$1
14802         local context=${2:-.}
14803         local sample=$(do_facet $SINGLEMDS $LCTL \
14804                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14805                 grep -A1 $context |
14806                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14807         echo $sample
14808 }
14809
14810 test_133d() {
14811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14812         remote_ost_nodsh && skip "remote OST with nodsh"
14813         remote_mds_nodsh && skip "remote MDS with nodsh"
14814         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14815                 skip_env "MDS doesn't support rename stats"
14816
14817         local testdir1=$DIR/${tdir}/stats_testdir1
14818         local testdir2=$DIR/${tdir}/stats_testdir2
14819         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14820
14821         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14822
14823         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14824         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14825
14826         createmany -o $testdir1/test 512 || error "createmany failed"
14827
14828         # check samedir rename size
14829         mv ${testdir1}/test0 ${testdir1}/test_0
14830
14831         local testdir1_size=$(ls -l $DIR/${tdir} |
14832                 awk '/stats_testdir1/ {print $5}')
14833         local testdir2_size=$(ls -l $DIR/${tdir} |
14834                 awk '/stats_testdir2/ {print $5}')
14835
14836         testdir1_size=$(order_2 $testdir1_size)
14837         testdir2_size=$(order_2 $testdir2_size)
14838
14839         testdir1_size=$(size_in_KMGT $testdir1_size)
14840         testdir2_size=$(size_in_KMGT $testdir2_size)
14841
14842         echo "source rename dir size: ${testdir1_size}"
14843         echo "target rename dir size: ${testdir2_size}"
14844
14845         local cmd="do_facet $SINGLEMDS $LCTL "
14846         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14847
14848         eval $cmd || error "$cmd failed"
14849         local samedir=$($cmd | grep 'same_dir')
14850         local same_sample=$(get_rename_size $testdir1_size)
14851         [ -z "$samedir" ] && error "samedir_rename_size count error"
14852         [[ $same_sample -eq 1 ]] ||
14853                 error "samedir_rename_size error $same_sample"
14854         echo "Check same dir rename stats success"
14855
14856         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14857
14858         # check crossdir rename size
14859         mv ${testdir1}/test_0 ${testdir2}/test_0
14860
14861         testdir1_size=$(ls -l $DIR/${tdir} |
14862                 awk '/stats_testdir1/ {print $5}')
14863         testdir2_size=$(ls -l $DIR/${tdir} |
14864                 awk '/stats_testdir2/ {print $5}')
14865
14866         testdir1_size=$(order_2 $testdir1_size)
14867         testdir2_size=$(order_2 $testdir2_size)
14868
14869         testdir1_size=$(size_in_KMGT $testdir1_size)
14870         testdir2_size=$(size_in_KMGT $testdir2_size)
14871
14872         echo "source rename dir size: ${testdir1_size}"
14873         echo "target rename dir size: ${testdir2_size}"
14874
14875         eval $cmd || error "$cmd failed"
14876         local crossdir=$($cmd | grep 'crossdir')
14877         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14878         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14879         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14880         [[ $src_sample -eq 1 ]] ||
14881                 error "crossdir_rename_size error $src_sample"
14882         [[ $tgt_sample -eq 1 ]] ||
14883                 error "crossdir_rename_size error $tgt_sample"
14884         echo "Check cross dir rename stats success"
14885         rm -rf $DIR/${tdir}
14886 }
14887 run_test 133d "Verifying rename_stats ========================================"
14888
14889 test_133e() {
14890         remote_mds_nodsh && skip "remote MDS with nodsh"
14891         remote_ost_nodsh && skip "remote OST with nodsh"
14892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14893
14894         local testdir=$DIR/${tdir}/stats_testdir
14895         local ctr f0 f1 bs=32768 count=42 sum
14896
14897         mkdir -p ${testdir} || error "mkdir failed"
14898
14899         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14900
14901         for ctr in {write,read}_bytes; do
14902                 sync
14903                 cancel_lru_locks osc
14904
14905                 do_facet ost1 $LCTL set_param -n \
14906                         "obdfilter.*.exports.clear=clear"
14907
14908                 if [ $ctr = write_bytes ]; then
14909                         f0=/dev/zero
14910                         f1=${testdir}/${tfile}
14911                 else
14912                         f0=${testdir}/${tfile}
14913                         f1=/dev/null
14914                 fi
14915
14916                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14917                         error "dd failed"
14918                 sync
14919                 cancel_lru_locks osc
14920
14921                 sum=$(do_facet ost1 $LCTL get_param \
14922                         "obdfilter.*.exports.*.stats" |
14923                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14924                                 $1 == ctr { sum += $7 }
14925                                 END { printf("%0.0f", sum) }')
14926
14927                 if ((sum != bs * count)); then
14928                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14929                 fi
14930         done
14931
14932         rm -rf $DIR/${tdir}
14933 }
14934 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14935
14936 test_133f() {
14937         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14938                 skip "too old lustre for get_param -R ($facet_ver)"
14939
14940         # verifying readability.
14941         $LCTL get_param -R '*' &> /dev/null
14942
14943         # Verifing writability with badarea_io.
14944         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14945         local skipped_params='force_lbug|changelog_mask|daemon_file'
14946         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14947                 egrep -v "$skipped_params" |
14948                 xargs -n 1 find $proc_dirs -name |
14949                 xargs -n 1 badarea_io ||
14950                 error "client badarea_io failed"
14951
14952         # remount the FS in case writes/reads /proc break the FS
14953         cleanup || error "failed to unmount"
14954         setup || error "failed to setup"
14955 }
14956 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14957
14958 test_133g() {
14959         remote_mds_nodsh && skip "remote MDS with nodsh"
14960         remote_ost_nodsh && skip "remote OST with nodsh"
14961
14962         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14963         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14964         local facet
14965         for facet in mds1 ost1; do
14966                 local facet_ver=$(lustre_version_code $facet)
14967                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14968                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14969                 else
14970                         log "$facet: too old lustre for get_param -R"
14971                 fi
14972                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14973                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14974                                 tr -d = | egrep -v $skipped_params |
14975                                 xargs -n 1 find $proc_dirs -name |
14976                                 xargs -n 1 badarea_io" ||
14977                                         error "$facet badarea_io failed"
14978                 else
14979                         skip_noexit "$facet: too old lustre for get_param -R"
14980                 fi
14981         done
14982
14983         # remount the FS in case writes/reads /proc break the FS
14984         cleanup || error "failed to unmount"
14985         setup || error "failed to setup"
14986 }
14987 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14988
14989 test_133h() {
14990         remote_mds_nodsh && skip "remote MDS with nodsh"
14991         remote_ost_nodsh && skip "remote OST with nodsh"
14992         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14993                 skip "Need MDS version at least 2.9.54"
14994
14995         local facet
14996         for facet in client mds1 ost1; do
14997                 # Get the list of files that are missing the terminating newline
14998                 local plist=$(do_facet $facet
14999                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15000                 local ent
15001                 for ent in $plist; do
15002                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15003                                 awk -v FS='\v' -v RS='\v\v' \
15004                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15005                                         print FILENAME}'" 2>/dev/null)
15006                         [ -z $missing ] || {
15007                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15008                                 error "file does not end with newline: $facet-$ent"
15009                         }
15010                 done
15011         done
15012 }
15013 run_test 133h "Proc files should end with newlines"
15014
15015 test_134a() {
15016         remote_mds_nodsh && skip "remote MDS with nodsh"
15017         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15018                 skip "Need MDS version at least 2.7.54"
15019
15020         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15021         cancel_lru_locks mdc
15022
15023         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15024         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15025         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15026
15027         local nr=1000
15028         createmany -o $DIR/$tdir/f $nr ||
15029                 error "failed to create $nr files in $DIR/$tdir"
15030         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15031
15032         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15033         do_facet mds1 $LCTL set_param fail_loc=0x327
15034         do_facet mds1 $LCTL set_param fail_val=500
15035         touch $DIR/$tdir/m
15036
15037         echo "sleep 10 seconds ..."
15038         sleep 10
15039         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15040
15041         do_facet mds1 $LCTL set_param fail_loc=0
15042         do_facet mds1 $LCTL set_param fail_val=0
15043         [ $lck_cnt -lt $unused ] ||
15044                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15045
15046         rm $DIR/$tdir/m
15047         unlinkmany $DIR/$tdir/f $nr
15048 }
15049 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15050
15051 test_134b() {
15052         remote_mds_nodsh && skip "remote MDS with nodsh"
15053         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15054                 skip "Need MDS version at least 2.7.54"
15055
15056         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15057         cancel_lru_locks mdc
15058
15059         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15060                         ldlm.lock_reclaim_threshold_mb)
15061         # disable reclaim temporarily
15062         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15063
15064         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15065         do_facet mds1 $LCTL set_param fail_loc=0x328
15066         do_facet mds1 $LCTL set_param fail_val=500
15067
15068         $LCTL set_param debug=+trace
15069
15070         local nr=600
15071         createmany -o $DIR/$tdir/f $nr &
15072         local create_pid=$!
15073
15074         echo "Sleep $TIMEOUT seconds ..."
15075         sleep $TIMEOUT
15076         if ! ps -p $create_pid  > /dev/null 2>&1; then
15077                 do_facet mds1 $LCTL set_param fail_loc=0
15078                 do_facet mds1 $LCTL set_param fail_val=0
15079                 do_facet mds1 $LCTL set_param \
15080                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15081                 error "createmany finished incorrectly!"
15082         fi
15083         do_facet mds1 $LCTL set_param fail_loc=0
15084         do_facet mds1 $LCTL set_param fail_val=0
15085         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15086         wait $create_pid || return 1
15087
15088         unlinkmany $DIR/$tdir/f $nr
15089 }
15090 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15091
15092 test_135() {
15093         remote_mds_nodsh && skip "remote MDS with nodsh"
15094         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15095                 skip "Need MDS version at least 2.13.50"
15096         local fname
15097
15098         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15099
15100 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15101         #set only one record at plain llog
15102         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15103
15104         #fill already existed plain llog each 64767
15105         #wrapping whole catalog
15106         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15107
15108         createmany -o $DIR/$tdir/$tfile_ 64700
15109         for (( i = 0; i < 64700; i = i + 2 ))
15110         do
15111                 rm $DIR/$tdir/$tfile_$i &
15112                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15113                 local pid=$!
15114                 wait $pid
15115         done
15116
15117         #waiting osp synchronization
15118         wait_delete_completed
15119 }
15120 run_test 135 "Race catalog processing"
15121
15122 test_136() {
15123         remote_mds_nodsh && skip "remote MDS with nodsh"
15124         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15125                 skip "Need MDS version at least 2.13.50"
15126         local fname
15127
15128         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15129         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15130         #set only one record at plain llog
15131 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15132         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15133
15134         #fill already existed 2 plain llogs each 64767
15135         #wrapping whole catalog
15136         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15137         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15138         wait_delete_completed
15139
15140         createmany -o $DIR/$tdir/$tfile_ 10
15141         sleep 25
15142
15143         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15144         for (( i = 0; i < 10; i = i + 3 ))
15145         do
15146                 rm $DIR/$tdir/$tfile_$i &
15147                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15148                 local pid=$!
15149                 wait $pid
15150                 sleep 7
15151                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15152         done
15153
15154         #waiting osp synchronization
15155         wait_delete_completed
15156 }
15157 run_test 136 "Race catalog processing 2"
15158
15159 test_140() { #bug-17379
15160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15161
15162         test_mkdir $DIR/$tdir
15163         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15164         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15165
15166         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15167         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15168         local i=0
15169         while i=$((i + 1)); do
15170                 test_mkdir $i
15171                 cd $i || error "Changing to $i"
15172                 ln -s ../stat stat || error "Creating stat symlink"
15173                 # Read the symlink until ELOOP present,
15174                 # not LBUGing the system is considered success,
15175                 # we didn't overrun the stack.
15176                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15177                 if [ $ret -ne 0 ]; then
15178                         if [ $ret -eq 40 ]; then
15179                                 break  # -ELOOP
15180                         else
15181                                 error "Open stat symlink"
15182                                         return
15183                         fi
15184                 fi
15185         done
15186         i=$((i - 1))
15187         echo "The symlink depth = $i"
15188         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15189                 error "Invalid symlink depth"
15190
15191         # Test recursive symlink
15192         ln -s symlink_self symlink_self
15193         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15194         echo "open symlink_self returns $ret"
15195         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15196 }
15197 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15198
15199 test_150a() {
15200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15201
15202         local TF="$TMP/$tfile"
15203
15204         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15205         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15206         cp $TF $DIR/$tfile
15207         cancel_lru_locks $OSC
15208         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15209         remount_client $MOUNT
15210         df -P $MOUNT
15211         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15212
15213         $TRUNCATE $TF 6000
15214         $TRUNCATE $DIR/$tfile 6000
15215         cancel_lru_locks $OSC
15216         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15217
15218         echo "12345" >>$TF
15219         echo "12345" >>$DIR/$tfile
15220         cancel_lru_locks $OSC
15221         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15222
15223         echo "12345" >>$TF
15224         echo "12345" >>$DIR/$tfile
15225         cancel_lru_locks $OSC
15226         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15227 }
15228 run_test 150a "truncate/append tests"
15229
15230 test_150b() {
15231         check_set_fallocate_or_skip
15232         local out
15233
15234         touch $DIR/$tfile
15235         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15236         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15237                 skip_eopnotsupp "$out|check_fallocate failed"
15238 }
15239 run_test 150b "Verify fallocate (prealloc) functionality"
15240
15241 test_150bb() {
15242         check_set_fallocate_or_skip
15243
15244         touch $DIR/$tfile
15245         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15246         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15247         > $DIR/$tfile
15248         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15249         # precomputed md5sum for 20MB of zeroes
15250         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15251         local sum=($(md5sum $DIR/$tfile))
15252
15253         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15254
15255         check_set_fallocate 1
15256
15257         > $DIR/$tfile
15258         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15259         sum=($(md5sum $DIR/$tfile))
15260
15261         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15262 }
15263 run_test 150bb "Verify fallocate modes both zero space"
15264
15265 test_150c() {
15266         check_set_fallocate_or_skip
15267         local striping="-c2"
15268
15269         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15270         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15271         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15272         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15273         local want=$((OSTCOUNT * 1048576))
15274
15275         # Must allocate all requested space, not more than 5% extra
15276         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15277                 error "bytes $bytes is not $want"
15278
15279         rm -f $DIR/$tfile
15280
15281         echo "verify fallocate on PFL file"
15282
15283         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15284
15285         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15286                 error "Create $DIR/$tfile failed"
15287         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15288         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15289         want=$((512 * 1048576))
15290
15291         # Must allocate all requested space, not more than 5% extra
15292         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15293                 error "bytes $bytes is not $want"
15294 }
15295 run_test 150c "Verify fallocate Size and Blocks"
15296
15297 test_150d() {
15298         check_set_fallocate_or_skip
15299         local striping="-c2"
15300
15301         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15302
15303         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15304         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15305                 error "setstripe failed"
15306         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15307         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15308         local want=$((OSTCOUNT * 1048576))
15309
15310         # Must allocate all requested space, not more than 5% extra
15311         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15312                 error "bytes $bytes is not $want"
15313 }
15314 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15315
15316 test_150e() {
15317         check_set_fallocate_or_skip
15318
15319         echo "df before:"
15320         $LFS df
15321         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15322         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15323                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15324
15325         # Find OST with Minimum Size
15326         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15327                        sort -un | head -1)
15328
15329         # Get 100MB per OST of the available space to reduce run time
15330         # else 60% of the available space if we are running SLOW tests
15331         if [ $SLOW == "no" ]; then
15332                 local space=$((1024 * 100 * OSTCOUNT))
15333         else
15334                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15335         fi
15336
15337         fallocate -l${space}k $DIR/$tfile ||
15338                 error "fallocate ${space}k $DIR/$tfile failed"
15339         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15340
15341         # get size immediately after fallocate. This should be correctly
15342         # updated
15343         local size=$(stat -c '%s' $DIR/$tfile)
15344         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15345
15346         # Sleep for a while for statfs to get updated. And not pull from cache.
15347         sleep 2
15348
15349         echo "df after fallocate:"
15350         $LFS df
15351
15352         (( size / 1024 == space )) || error "size $size != requested $space"
15353         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15354                 error "used $used < space $space"
15355
15356         rm $DIR/$tfile || error "rm failed"
15357         sync
15358         wait_delete_completed
15359
15360         echo "df after unlink:"
15361         $LFS df
15362 }
15363 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15364
15365 test_150f() {
15366         local size
15367         local blocks
15368         local want_size_before=20480 # in bytes
15369         local want_blocks_before=40 # 512 sized blocks
15370         local want_blocks_after=24  # 512 sized blocks
15371         local length=$(((want_blocks_before - want_blocks_after) * 512))
15372
15373         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15374                 skip "need at least 2.14.0 for fallocate punch"
15375
15376         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15377                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15378         fi
15379
15380         check_set_fallocate_or_skip
15381         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15382
15383         [[ "x$DOM" == "xyes" ]] &&
15384                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15385
15386         echo "Verify fallocate punch: Range within the file range"
15387         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15388                 error "dd failed for bs 4096 and count 5"
15389
15390         # Call fallocate with punch range which is within the file range
15391         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15392                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15393         # client must see changes immediately after fallocate
15394         size=$(stat -c '%s' $DIR/$tfile)
15395         blocks=$(stat -c '%b' $DIR/$tfile)
15396
15397         # Verify punch worked.
15398         (( blocks == want_blocks_after )) ||
15399                 error "punch failed: blocks $blocks != $want_blocks_after"
15400
15401         (( size == want_size_before )) ||
15402                 error "punch failed: size $size != $want_size_before"
15403
15404         # Verify there is hole in file
15405         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15406         # precomputed md5sum
15407         local expect="4a9a834a2db02452929c0a348273b4aa"
15408
15409         cksum=($(md5sum $DIR/$tfile))
15410         [[ "${cksum[0]}" == "$expect" ]] ||
15411                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15412
15413         # Start second sub-case for fallocate punch.
15414         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15415         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15416                 error "dd failed for bs 4096 and count 5"
15417
15418         # Punch range less than block size will have no change in block count
15419         want_blocks_after=40  # 512 sized blocks
15420
15421         # Punch overlaps two blocks and less than blocksize
15422         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15423                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15424         size=$(stat -c '%s' $DIR/$tfile)
15425         blocks=$(stat -c '%b' $DIR/$tfile)
15426
15427         # Verify punch worked.
15428         (( blocks == want_blocks_after )) ||
15429                 error "punch failed: blocks $blocks != $want_blocks_after"
15430
15431         (( size == want_size_before )) ||
15432                 error "punch failed: size $size != $want_size_before"
15433
15434         # Verify if range is really zero'ed out. We expect Zeros.
15435         # precomputed md5sum
15436         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15437         cksum=($(md5sum $DIR/$tfile))
15438         [[ "${cksum[0]}" == "$expect" ]] ||
15439                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15440 }
15441 run_test 150f "Verify fallocate punch functionality"
15442
15443 test_150g() {
15444         local space
15445         local size
15446         local blocks
15447         local blocks_after
15448         local size_after
15449         local BS=4096 # Block size in bytes
15450
15451         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15452                 skip "need at least 2.14.0 for fallocate punch"
15453
15454         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15455                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15456         fi
15457
15458         check_set_fallocate_or_skip
15459         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15460
15461         if [[ "x$DOM" == "xyes" ]]; then
15462                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15463                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15464         else
15465                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15466                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15467         fi
15468
15469         # Get 100MB per OST of the available space to reduce run time
15470         # else 60% of the available space if we are running SLOW tests
15471         if [ $SLOW == "no" ]; then
15472                 space=$((1024 * 100 * OSTCOUNT))
15473         else
15474                 # Find OST with Minimum Size
15475                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15476                         sort -un | head -1)
15477                 echo "min size OST: $space"
15478                 space=$(((space * 60)/100 * OSTCOUNT))
15479         fi
15480         # space in 1k units, round to 4k blocks
15481         local blkcount=$((space * 1024 / $BS))
15482
15483         echo "Verify fallocate punch: Very large Range"
15484         fallocate -l${space}k $DIR/$tfile ||
15485                 error "fallocate ${space}k $DIR/$tfile failed"
15486         # write 1M at the end, start and in the middle
15487         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15488                 error "dd failed: bs $BS count 256"
15489         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15490                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15491         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15492                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15493
15494         # Gather stats.
15495         size=$(stat -c '%s' $DIR/$tfile)
15496
15497         # gather punch length.
15498         local punch_size=$((size - (BS * 2)))
15499
15500         echo "punch_size = $punch_size"
15501         echo "size - punch_size: $((size - punch_size))"
15502         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15503
15504         # Call fallocate to punch all except 2 blocks. We leave the
15505         # first and the last block
15506         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15507         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15508                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15509
15510         size_after=$(stat -c '%s' $DIR/$tfile)
15511         blocks_after=$(stat -c '%b' $DIR/$tfile)
15512
15513         # Verify punch worked.
15514         # Size should be kept
15515         (( size == size_after )) ||
15516                 error "punch failed: size $size != $size_after"
15517
15518         # two 4k data blocks to remain plus possible 1 extra extent block
15519         (( blocks_after <= ((BS / 512) * 3) )) ||
15520                 error "too many blocks remains: $blocks_after"
15521
15522         # Verify that file has hole between the first and the last blocks
15523         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15524         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15525
15526         echo "Hole at [$hole_start, $hole_end)"
15527         (( hole_start == BS )) ||
15528                 error "no hole at offset $BS after punch"
15529
15530         (( hole_end == BS + punch_size )) ||
15531                 error "data at offset $hole_end < $((BS + punch_size))"
15532 }
15533 run_test 150g "Verify fallocate punch on large range"
15534
15535 test_150h() {
15536         local file=$DIR/$tfile
15537         local size
15538
15539         check_set_fallocate_or_skip
15540         statx_supported || skip_env "Test must be statx() syscall supported"
15541
15542         # fallocate() does not update the size information on the MDT
15543         fallocate -l 16K $file || error "failed to fallocate $file"
15544         cancel_lru_locks $OSC
15545         # STATX with cached-always mode will not send glimpse RPCs to OST,
15546         # it uses the caching attrs on the client side as much as possible.
15547         size=$($STATX --cached=always -c %s $file)
15548         [ $size == 16384 ] ||
15549                 error "size after fallocate() is $size, expected 16384"
15550 }
15551 run_test 150h "Verify extend fallocate updates the file size"
15552
15553 #LU-2902 roc_hit was not able to read all values from lproc
15554 function roc_hit_init() {
15555         local list=$(comma_list $(osts_nodes))
15556         local dir=$DIR/$tdir-check
15557         local file=$dir/$tfile
15558         local BEFORE
15559         local AFTER
15560         local idx
15561
15562         test_mkdir $dir
15563         #use setstripe to do a write to every ost
15564         for i in $(seq 0 $((OSTCOUNT-1))); do
15565                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15566                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15567                 idx=$(printf %04x $i)
15568                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15569                         awk '$1 == "cache_access" {sum += $7}
15570                                 END { printf("%0.0f", sum) }')
15571
15572                 cancel_lru_locks osc
15573                 cat $file >/dev/null
15574
15575                 AFTER=$(get_osd_param $list *OST*$idx stats |
15576                         awk '$1 == "cache_access" {sum += $7}
15577                                 END { printf("%0.0f", sum) }')
15578
15579                 echo BEFORE:$BEFORE AFTER:$AFTER
15580                 if ! let "AFTER - BEFORE == 4"; then
15581                         rm -rf $dir
15582                         error "roc_hit is not safe to use"
15583                 fi
15584                 rm $file
15585         done
15586
15587         rm -rf $dir
15588 }
15589
15590 function roc_hit() {
15591         local list=$(comma_list $(osts_nodes))
15592         echo $(get_osd_param $list '' stats |
15593                 awk '$1 == "cache_hit" {sum += $7}
15594                         END { printf("%0.0f", sum) }')
15595 }
15596
15597 function set_cache() {
15598         local on=1
15599
15600         if [ "$2" == "off" ]; then
15601                 on=0;
15602         fi
15603         local list=$(comma_list $(osts_nodes))
15604         set_osd_param $list '' $1_cache_enable $on
15605
15606         cancel_lru_locks osc
15607 }
15608
15609 test_151() {
15610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15611         remote_ost_nodsh && skip "remote OST with nodsh"
15612
15613         local CPAGES=3
15614         local list=$(comma_list $(osts_nodes))
15615
15616         # check whether obdfilter is cache capable at all
15617         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15618                 skip "not cache-capable obdfilter"
15619         fi
15620
15621         # check cache is enabled on all obdfilters
15622         if get_osd_param $list '' read_cache_enable | grep 0; then
15623                 skip "oss cache is disabled"
15624         fi
15625
15626         set_osd_param $list '' writethrough_cache_enable 1
15627
15628         # check write cache is enabled on all obdfilters
15629         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15630                 skip "oss write cache is NOT enabled"
15631         fi
15632
15633         roc_hit_init
15634
15635         #define OBD_FAIL_OBD_NO_LRU  0x609
15636         do_nodes $list $LCTL set_param fail_loc=0x609
15637
15638         # pages should be in the case right after write
15639         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15640                 error "dd failed"
15641
15642         local BEFORE=$(roc_hit)
15643         cancel_lru_locks osc
15644         cat $DIR/$tfile >/dev/null
15645         local AFTER=$(roc_hit)
15646
15647         do_nodes $list $LCTL set_param fail_loc=0
15648
15649         if ! let "AFTER - BEFORE == CPAGES"; then
15650                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15651         fi
15652
15653         cancel_lru_locks osc
15654         # invalidates OST cache
15655         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15656         set_osd_param $list '' read_cache_enable 0
15657         cat $DIR/$tfile >/dev/null
15658
15659         # now data shouldn't be found in the cache
15660         BEFORE=$(roc_hit)
15661         cancel_lru_locks osc
15662         cat $DIR/$tfile >/dev/null
15663         AFTER=$(roc_hit)
15664         if let "AFTER - BEFORE != 0"; then
15665                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15666         fi
15667
15668         set_osd_param $list '' read_cache_enable 1
15669         rm -f $DIR/$tfile
15670 }
15671 run_test 151 "test cache on oss and controls ==============================="
15672
15673 test_152() {
15674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15675
15676         local TF="$TMP/$tfile"
15677
15678         # simulate ENOMEM during write
15679 #define OBD_FAIL_OST_NOMEM      0x226
15680         lctl set_param fail_loc=0x80000226
15681         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15682         cp $TF $DIR/$tfile
15683         sync || error "sync failed"
15684         lctl set_param fail_loc=0
15685
15686         # discard client's cache
15687         cancel_lru_locks osc
15688
15689         # simulate ENOMEM during read
15690         lctl set_param fail_loc=0x80000226
15691         cmp $TF $DIR/$tfile || error "cmp failed"
15692         lctl set_param fail_loc=0
15693
15694         rm -f $TF
15695 }
15696 run_test 152 "test read/write with enomem ============================"
15697
15698 test_153() {
15699         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15700 }
15701 run_test 153 "test if fdatasync does not crash ======================="
15702
15703 dot_lustre_fid_permission_check() {
15704         local fid=$1
15705         local ffid=$MOUNT/.lustre/fid/$fid
15706         local test_dir=$2
15707
15708         echo "stat fid $fid"
15709         stat $ffid || error "stat $ffid failed."
15710         echo "touch fid $fid"
15711         touch $ffid || error "touch $ffid failed."
15712         echo "write to fid $fid"
15713         cat /etc/hosts > $ffid || error "write $ffid failed."
15714         echo "read fid $fid"
15715         diff /etc/hosts $ffid || error "read $ffid failed."
15716         echo "append write to fid $fid"
15717         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15718         echo "rename fid $fid"
15719         mv $ffid $test_dir/$tfile.1 &&
15720                 error "rename $ffid to $tfile.1 should fail."
15721         touch $test_dir/$tfile.1
15722         mv $test_dir/$tfile.1 $ffid &&
15723                 error "rename $tfile.1 to $ffid should fail."
15724         rm -f $test_dir/$tfile.1
15725         echo "truncate fid $fid"
15726         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15727         echo "link fid $fid"
15728         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15729         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15730                 echo "setfacl fid $fid"
15731                 setfacl -R -m u:$USER0:rwx $ffid ||
15732                         error "setfacl $ffid failed"
15733                 echo "getfacl fid $fid"
15734                 getfacl $ffid || error "getfacl $ffid failed."
15735         fi
15736         echo "unlink fid $fid"
15737         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15738         echo "mknod fid $fid"
15739         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15740
15741         fid=[0xf00000400:0x1:0x0]
15742         ffid=$MOUNT/.lustre/fid/$fid
15743
15744         echo "stat non-exist fid $fid"
15745         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15746         echo "write to non-exist fid $fid"
15747         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15748         echo "link new fid $fid"
15749         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15750
15751         mkdir -p $test_dir/$tdir
15752         touch $test_dir/$tdir/$tfile
15753         fid=$($LFS path2fid $test_dir/$tdir)
15754         rc=$?
15755         [ $rc -ne 0 ] &&
15756                 error "error: could not get fid for $test_dir/$dir/$tfile."
15757
15758         ffid=$MOUNT/.lustre/fid/$fid
15759
15760         echo "ls $fid"
15761         ls $ffid || error "ls $ffid failed."
15762         echo "touch $fid/$tfile.1"
15763         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15764
15765         echo "touch $MOUNT/.lustre/fid/$tfile"
15766         touch $MOUNT/.lustre/fid/$tfile && \
15767                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15768
15769         echo "setxattr to $MOUNT/.lustre/fid"
15770         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15771
15772         echo "listxattr for $MOUNT/.lustre/fid"
15773         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15774
15775         echo "delxattr from $MOUNT/.lustre/fid"
15776         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15777
15778         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15779         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15780                 error "touch invalid fid should fail."
15781
15782         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15783         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15784                 error "touch non-normal fid should fail."
15785
15786         echo "rename $tdir to $MOUNT/.lustre/fid"
15787         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15788                 error "rename to $MOUNT/.lustre/fid should fail."
15789
15790         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15791         then            # LU-3547
15792                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15793                 local new_obf_mode=777
15794
15795                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15796                 chmod $new_obf_mode $DIR/.lustre/fid ||
15797                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15798
15799                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15800                 [ $obf_mode -eq $new_obf_mode ] ||
15801                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15802
15803                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15804                 chmod $old_obf_mode $DIR/.lustre/fid ||
15805                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15806         fi
15807
15808         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15809         fid=$($LFS path2fid $test_dir/$tfile-2)
15810
15811         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15812         then # LU-5424
15813                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15814                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15815                         error "create lov data thru .lustre failed"
15816         fi
15817         echo "cp /etc/passwd $test_dir/$tfile-2"
15818         cp /etc/passwd $test_dir/$tfile-2 ||
15819                 error "copy to $test_dir/$tfile-2 failed."
15820         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15821         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15822                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15823
15824         rm -rf $test_dir/tfile.lnk
15825         rm -rf $test_dir/$tfile-2
15826 }
15827
15828 test_154A() {
15829         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15830                 skip "Need MDS version at least 2.4.1"
15831
15832         local tf=$DIR/$tfile
15833         touch $tf
15834
15835         local fid=$($LFS path2fid $tf)
15836         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15837
15838         # check that we get the same pathname back
15839         local rootpath
15840         local found
15841         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15842                 echo "$rootpath $fid"
15843                 found=$($LFS fid2path $rootpath "$fid")
15844                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15845                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15846         done
15847
15848         # check wrong root path format
15849         rootpath=$MOUNT"_wrong"
15850         found=$($LFS fid2path $rootpath "$fid")
15851         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15852 }
15853 run_test 154A "lfs path2fid and fid2path basic checks"
15854
15855 test_154B() {
15856         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15857                 skip "Need MDS version at least 2.4.1"
15858
15859         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15860         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15861         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15862         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15863
15864         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15865         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15866
15867         # check that we get the same pathname
15868         echo "PFID: $PFID, name: $name"
15869         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15870         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15871         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15872                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15873
15874         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15875 }
15876 run_test 154B "verify the ll_decode_linkea tool"
15877
15878 test_154a() {
15879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15880         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15881         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15882                 skip "Need MDS version at least 2.2.51"
15883         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15884
15885         cp /etc/hosts $DIR/$tfile
15886
15887         fid=$($LFS path2fid $DIR/$tfile)
15888         rc=$?
15889         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15890
15891         dot_lustre_fid_permission_check "$fid" $DIR ||
15892                 error "dot lustre permission check $fid failed"
15893
15894         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15895
15896         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15897
15898         touch $MOUNT/.lustre/file &&
15899                 error "creation is not allowed under .lustre"
15900
15901         mkdir $MOUNT/.lustre/dir &&
15902                 error "mkdir is not allowed under .lustre"
15903
15904         rm -rf $DIR/$tfile
15905 }
15906 run_test 154a "Open-by-FID"
15907
15908 test_154b() {
15909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15910         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15912         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15913                 skip "Need MDS version at least 2.2.51"
15914
15915         local remote_dir=$DIR/$tdir/remote_dir
15916         local MDTIDX=1
15917         local rc=0
15918
15919         mkdir -p $DIR/$tdir
15920         $LFS mkdir -i $MDTIDX $remote_dir ||
15921                 error "create remote directory failed"
15922
15923         cp /etc/hosts $remote_dir/$tfile
15924
15925         fid=$($LFS path2fid $remote_dir/$tfile)
15926         rc=$?
15927         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15928
15929         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15930                 error "dot lustre permission check $fid failed"
15931         rm -rf $DIR/$tdir
15932 }
15933 run_test 154b "Open-by-FID for remote directory"
15934
15935 test_154c() {
15936         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15937                 skip "Need MDS version at least 2.4.1"
15938
15939         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15940         local FID1=$($LFS path2fid $DIR/$tfile.1)
15941         local FID2=$($LFS path2fid $DIR/$tfile.2)
15942         local FID3=$($LFS path2fid $DIR/$tfile.3)
15943
15944         local N=1
15945         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15946                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15947                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15948                 local want=FID$N
15949                 [ "$FID" = "${!want}" ] ||
15950                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15951                 N=$((N + 1))
15952         done
15953
15954         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15955         do
15956                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15957                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15958                 N=$((N + 1))
15959         done
15960 }
15961 run_test 154c "lfs path2fid and fid2path multiple arguments"
15962
15963 test_154d() {
15964         remote_mds_nodsh && skip "remote MDS with nodsh"
15965         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15966                 skip "Need MDS version at least 2.5.53"
15967
15968         if remote_mds; then
15969                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15970         else
15971                 nid="0@lo"
15972         fi
15973         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15974         local fd
15975         local cmd
15976
15977         rm -f $DIR/$tfile
15978         touch $DIR/$tfile
15979
15980         local fid=$($LFS path2fid $DIR/$tfile)
15981         # Open the file
15982         fd=$(free_fd)
15983         cmd="exec $fd<$DIR/$tfile"
15984         eval $cmd
15985         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15986         echo "$fid_list" | grep "$fid"
15987         rc=$?
15988
15989         cmd="exec $fd>/dev/null"
15990         eval $cmd
15991         if [ $rc -ne 0 ]; then
15992                 error "FID $fid not found in open files list $fid_list"
15993         fi
15994 }
15995 run_test 154d "Verify open file fid"
15996
15997 test_154e()
15998 {
15999         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16000                 skip "Need MDS version at least 2.6.50"
16001
16002         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16003                 error ".lustre returned by readdir"
16004         fi
16005 }
16006 run_test 154e ".lustre is not returned by readdir"
16007
16008 test_154f() {
16009         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16010
16011         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16012         mkdir_on_mdt0 $DIR/$tdir
16013         # test dirs inherit from its stripe
16014         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16015         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16016         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16017         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16018         touch $DIR/f
16019
16020         # get fid of parents
16021         local FID0=$($LFS path2fid $DIR/$tdir)
16022         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16023         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16024         local FID3=$($LFS path2fid $DIR)
16025
16026         # check that path2fid --parents returns expected <parent_fid>/name
16027         # 1) test for a directory (single parent)
16028         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16029         [ "$parent" == "$FID0/foo1" ] ||
16030                 error "expected parent: $FID0/foo1, got: $parent"
16031
16032         # 2) test for a file with nlink > 1 (multiple parents)
16033         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16034         echo "$parent" | grep -F "$FID1/$tfile" ||
16035                 error "$FID1/$tfile not returned in parent list"
16036         echo "$parent" | grep -F "$FID2/link" ||
16037                 error "$FID2/link not returned in parent list"
16038
16039         # 3) get parent by fid
16040         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16041         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16042         echo "$parent" | grep -F "$FID1/$tfile" ||
16043                 error "$FID1/$tfile not returned in parent list (by fid)"
16044         echo "$parent" | grep -F "$FID2/link" ||
16045                 error "$FID2/link not returned in parent list (by fid)"
16046
16047         # 4) test for entry in root directory
16048         parent=$($LFS path2fid --parents $DIR/f)
16049         echo "$parent" | grep -F "$FID3/f" ||
16050                 error "$FID3/f not returned in parent list"
16051
16052         # 5) test it on root directory
16053         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16054                 error "$MOUNT should not have parents"
16055
16056         # enable xattr caching and check that linkea is correctly updated
16057         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16058         save_lustre_params client "llite.*.xattr_cache" > $save
16059         lctl set_param llite.*.xattr_cache 1
16060
16061         # 6.1) linkea update on rename
16062         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16063
16064         # get parents by fid
16065         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16066         # foo1 should no longer be returned in parent list
16067         echo "$parent" | grep -F "$FID1" &&
16068                 error "$FID1 should no longer be in parent list"
16069         # the new path should appear
16070         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16071                 error "$FID2/$tfile.moved is not in parent list"
16072
16073         # 6.2) linkea update on unlink
16074         rm -f $DIR/$tdir/foo2/link
16075         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16076         # foo2/link should no longer be returned in parent list
16077         echo "$parent" | grep -F "$FID2/link" &&
16078                 error "$FID2/link should no longer be in parent list"
16079         true
16080
16081         rm -f $DIR/f
16082         restore_lustre_params < $save
16083         rm -f $save
16084 }
16085 run_test 154f "get parent fids by reading link ea"
16086
16087 test_154g()
16088 {
16089         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16090            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16091                 skip "Need MDS version at least 2.6.92"
16092
16093         mkdir_on_mdt0 $DIR/$tdir
16094         llapi_fid_test -d $DIR/$tdir
16095 }
16096 run_test 154g "various llapi FID tests"
16097
16098 test_155_small_load() {
16099     local temp=$TMP/$tfile
16100     local file=$DIR/$tfile
16101
16102     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16103         error "dd of=$temp bs=6096 count=1 failed"
16104     cp $temp $file
16105     cancel_lru_locks $OSC
16106     cmp $temp $file || error "$temp $file differ"
16107
16108     $TRUNCATE $temp 6000
16109     $TRUNCATE $file 6000
16110     cmp $temp $file || error "$temp $file differ (truncate1)"
16111
16112     echo "12345" >>$temp
16113     echo "12345" >>$file
16114     cmp $temp $file || error "$temp $file differ (append1)"
16115
16116     echo "12345" >>$temp
16117     echo "12345" >>$file
16118     cmp $temp $file || error "$temp $file differ (append2)"
16119
16120     rm -f $temp $file
16121     true
16122 }
16123
16124 test_155_big_load() {
16125         remote_ost_nodsh && skip "remote OST with nodsh"
16126
16127         local temp=$TMP/$tfile
16128         local file=$DIR/$tfile
16129
16130         free_min_max
16131         local cache_size=$(do_facet ost$((MAXI+1)) \
16132                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16133
16134         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16135         # pre-set value
16136         if [ -z "$cache_size" ]; then
16137                 cache_size=256
16138         fi
16139         local large_file_size=$((cache_size * 2))
16140
16141         echo "OSS cache size: $cache_size KB"
16142         echo "Large file size: $large_file_size KB"
16143
16144         [ $MAXV -le $large_file_size ] &&
16145                 skip_env "max available OST size needs > $large_file_size KB"
16146
16147         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16148
16149         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16150                 error "dd of=$temp bs=$large_file_size count=1k failed"
16151         cp $temp $file
16152         ls -lh $temp $file
16153         cancel_lru_locks osc
16154         cmp $temp $file || error "$temp $file differ"
16155
16156         rm -f $temp $file
16157         true
16158 }
16159
16160 save_writethrough() {
16161         local facets=$(get_facets OST)
16162
16163         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16164 }
16165
16166 test_155a() {
16167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16168
16169         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16170
16171         save_writethrough $p
16172
16173         set_cache read on
16174         set_cache writethrough on
16175         test_155_small_load
16176         restore_lustre_params < $p
16177         rm -f $p
16178 }
16179 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16180
16181 test_155b() {
16182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16183
16184         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16185
16186         save_writethrough $p
16187
16188         set_cache read on
16189         set_cache writethrough off
16190         test_155_small_load
16191         restore_lustre_params < $p
16192         rm -f $p
16193 }
16194 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16195
16196 test_155c() {
16197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16198
16199         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16200
16201         save_writethrough $p
16202
16203         set_cache read off
16204         set_cache writethrough on
16205         test_155_small_load
16206         restore_lustre_params < $p
16207         rm -f $p
16208 }
16209 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16210
16211 test_155d() {
16212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16213
16214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16215
16216         save_writethrough $p
16217
16218         set_cache read off
16219         set_cache writethrough off
16220         test_155_small_load
16221         restore_lustre_params < $p
16222         rm -f $p
16223 }
16224 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16225
16226 test_155e() {
16227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16228
16229         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16230
16231         save_writethrough $p
16232
16233         set_cache read on
16234         set_cache writethrough on
16235         test_155_big_load
16236         restore_lustre_params < $p
16237         rm -f $p
16238 }
16239 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16240
16241 test_155f() {
16242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16243
16244         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16245
16246         save_writethrough $p
16247
16248         set_cache read on
16249         set_cache writethrough off
16250         test_155_big_load
16251         restore_lustre_params < $p
16252         rm -f $p
16253 }
16254 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16255
16256 test_155g() {
16257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16258
16259         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16260
16261         save_writethrough $p
16262
16263         set_cache read off
16264         set_cache writethrough on
16265         test_155_big_load
16266         restore_lustre_params < $p
16267         rm -f $p
16268 }
16269 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16270
16271 test_155h() {
16272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16273
16274         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16275
16276         save_writethrough $p
16277
16278         set_cache read off
16279         set_cache writethrough off
16280         test_155_big_load
16281         restore_lustre_params < $p
16282         rm -f $p
16283 }
16284 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16285
16286 test_156() {
16287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16288         remote_ost_nodsh && skip "remote OST with nodsh"
16289         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16290                 skip "stats not implemented on old servers"
16291         [ "$ost1_FSTYPE" = "zfs" ] &&
16292                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16293
16294         local CPAGES=3
16295         local BEFORE
16296         local AFTER
16297         local file="$DIR/$tfile"
16298         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16299
16300         save_writethrough $p
16301         roc_hit_init
16302
16303         log "Turn on read and write cache"
16304         set_cache read on
16305         set_cache writethrough on
16306
16307         log "Write data and read it back."
16308         log "Read should be satisfied from the cache."
16309         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16310         BEFORE=$(roc_hit)
16311         cancel_lru_locks osc
16312         cat $file >/dev/null
16313         AFTER=$(roc_hit)
16314         if ! let "AFTER - BEFORE == CPAGES"; then
16315                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16316         else
16317                 log "cache hits: before: $BEFORE, after: $AFTER"
16318         fi
16319
16320         log "Read again; it should be satisfied from the cache."
16321         BEFORE=$AFTER
16322         cancel_lru_locks osc
16323         cat $file >/dev/null
16324         AFTER=$(roc_hit)
16325         if ! let "AFTER - BEFORE == CPAGES"; then
16326                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16327         else
16328                 log "cache hits:: before: $BEFORE, after: $AFTER"
16329         fi
16330
16331         log "Turn off the read cache and turn on the write cache"
16332         set_cache read off
16333         set_cache writethrough on
16334
16335         log "Read again; it should be satisfied from the cache."
16336         BEFORE=$(roc_hit)
16337         cancel_lru_locks osc
16338         cat $file >/dev/null
16339         AFTER=$(roc_hit)
16340         if ! let "AFTER - BEFORE == CPAGES"; then
16341                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16342         else
16343                 log "cache hits:: before: $BEFORE, after: $AFTER"
16344         fi
16345
16346         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16347                 # > 2.12.56 uses pagecache if cached
16348                 log "Read again; it should not be satisfied from the cache."
16349                 BEFORE=$AFTER
16350                 cancel_lru_locks osc
16351                 cat $file >/dev/null
16352                 AFTER=$(roc_hit)
16353                 if ! let "AFTER - BEFORE == 0"; then
16354                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16355                 else
16356                         log "cache hits:: before: $BEFORE, after: $AFTER"
16357                 fi
16358         fi
16359
16360         log "Write data and read it back."
16361         log "Read should be satisfied from the cache."
16362         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16363         BEFORE=$(roc_hit)
16364         cancel_lru_locks osc
16365         cat $file >/dev/null
16366         AFTER=$(roc_hit)
16367         if ! let "AFTER - BEFORE == CPAGES"; then
16368                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16369         else
16370                 log "cache hits:: before: $BEFORE, after: $AFTER"
16371         fi
16372
16373         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16374                 # > 2.12.56 uses pagecache if cached
16375                 log "Read again; it should not be satisfied from the cache."
16376                 BEFORE=$AFTER
16377                 cancel_lru_locks osc
16378                 cat $file >/dev/null
16379                 AFTER=$(roc_hit)
16380                 if ! let "AFTER - BEFORE == 0"; then
16381                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16382                 else
16383                         log "cache hits:: before: $BEFORE, after: $AFTER"
16384                 fi
16385         fi
16386
16387         log "Turn off read and write cache"
16388         set_cache read off
16389         set_cache writethrough off
16390
16391         log "Write data and read it back"
16392         log "It should not be satisfied from the cache."
16393         rm -f $file
16394         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16395         cancel_lru_locks osc
16396         BEFORE=$(roc_hit)
16397         cat $file >/dev/null
16398         AFTER=$(roc_hit)
16399         if ! let "AFTER - BEFORE == 0"; then
16400                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16401         else
16402                 log "cache hits:: before: $BEFORE, after: $AFTER"
16403         fi
16404
16405         log "Turn on the read cache and turn off the write cache"
16406         set_cache read on
16407         set_cache writethrough off
16408
16409         log "Write data and read it back"
16410         log "It should not be satisfied from the cache."
16411         rm -f $file
16412         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16413         BEFORE=$(roc_hit)
16414         cancel_lru_locks osc
16415         cat $file >/dev/null
16416         AFTER=$(roc_hit)
16417         if ! let "AFTER - BEFORE == 0"; then
16418                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16419         else
16420                 log "cache hits:: before: $BEFORE, after: $AFTER"
16421         fi
16422
16423         log "Read again; it should be satisfied from the cache."
16424         BEFORE=$(roc_hit)
16425         cancel_lru_locks osc
16426         cat $file >/dev/null
16427         AFTER=$(roc_hit)
16428         if ! let "AFTER - BEFORE == CPAGES"; then
16429                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16430         else
16431                 log "cache hits:: before: $BEFORE, after: $AFTER"
16432         fi
16433
16434         restore_lustre_params < $p
16435         rm -f $p $file
16436 }
16437 run_test 156 "Verification of tunables"
16438
16439 test_160a() {
16440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16441         remote_mds_nodsh && skip "remote MDS with nodsh"
16442         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16443                 skip "Need MDS version at least 2.2.0"
16444
16445         changelog_register || error "changelog_register failed"
16446         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16447         changelog_users $SINGLEMDS | grep -q $cl_user ||
16448                 error "User $cl_user not found in changelog_users"
16449
16450         mkdir_on_mdt0 $DIR/$tdir
16451
16452         # change something
16453         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16454         changelog_clear 0 || error "changelog_clear failed"
16455         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16456         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16457         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16458         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16459         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16460         rm $DIR/$tdir/pics/desktop.jpg
16461
16462         echo "verifying changelog mask"
16463         changelog_chmask "-MKDIR"
16464         changelog_chmask "-CLOSE"
16465
16466         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16467         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16468
16469         changelog_chmask "+MKDIR"
16470         changelog_chmask "+CLOSE"
16471
16472         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16473         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16474
16475         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16476         CLOSES=$(changelog_dump | grep -c "CLOSE")
16477         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16478         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16479
16480         # verify contents
16481         echo "verifying target fid"
16482         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16483         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16484         [ "$fidc" == "$fidf" ] ||
16485                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16486         echo "verifying parent fid"
16487         # The FID returned from the Changelog may be the directory shard on
16488         # a different MDT, and not the FID returned by path2fid on the parent.
16489         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16490         # since this is what will matter when recreating this file in the tree.
16491         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16492         local pathp=$($LFS fid2path $MOUNT "$fidp")
16493         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16494                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16495
16496         echo "getting records for $cl_user"
16497         changelog_users $SINGLEMDS
16498         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16499         local nclr=3
16500         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16501                 error "changelog_clear failed"
16502         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16503         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16504         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16505                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16506
16507         local min0_rec=$(changelog_users $SINGLEMDS |
16508                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16509         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16510                           awk '{ print $1; exit; }')
16511
16512         changelog_dump | tail -n 5
16513         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16514         [ $first_rec == $((min0_rec + 1)) ] ||
16515                 error "first index should be $min0_rec + 1 not $first_rec"
16516
16517         # LU-3446 changelog index reset on MDT restart
16518         local cur_rec1=$(changelog_users $SINGLEMDS |
16519                          awk '/^current.index:/ { print $NF }')
16520         changelog_clear 0 ||
16521                 error "clear all changelog records for $cl_user failed"
16522         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16523         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16524                 error "Fail to start $SINGLEMDS"
16525         local cur_rec2=$(changelog_users $SINGLEMDS |
16526                          awk '/^current.index:/ { print $NF }')
16527         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16528         [ $cur_rec1 == $cur_rec2 ] ||
16529                 error "current index should be $cur_rec1 not $cur_rec2"
16530
16531         echo "verifying users from this test are deregistered"
16532         changelog_deregister || error "changelog_deregister failed"
16533         changelog_users $SINGLEMDS | grep -q $cl_user &&
16534                 error "User '$cl_user' still in changelog_users"
16535
16536         # lctl get_param -n mdd.*.changelog_users
16537         # current_index: 144
16538         # ID    index (idle seconds)
16539         # cl3   144   (2) mask=<list>
16540         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16541                 # this is the normal case where all users were deregistered
16542                 # make sure no new records are added when no users are present
16543                 local last_rec1=$(changelog_users $SINGLEMDS |
16544                                   awk '/^current.index:/ { print $NF }')
16545                 touch $DIR/$tdir/chloe
16546                 local last_rec2=$(changelog_users $SINGLEMDS |
16547                                   awk '/^current.index:/ { print $NF }')
16548                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16549                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16550         else
16551                 # any changelog users must be leftovers from a previous test
16552                 changelog_users $SINGLEMDS
16553                 echo "other changelog users; can't verify off"
16554         fi
16555 }
16556 run_test 160a "changelog sanity"
16557
16558 test_160b() { # LU-3587
16559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16560         remote_mds_nodsh && skip "remote MDS with nodsh"
16561         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16562                 skip "Need MDS version at least 2.2.0"
16563
16564         changelog_register || error "changelog_register failed"
16565         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16566         changelog_users $SINGLEMDS | grep -q $cl_user ||
16567                 error "User '$cl_user' not found in changelog_users"
16568
16569         local longname1=$(str_repeat a 255)
16570         local longname2=$(str_repeat b 255)
16571
16572         cd $DIR
16573         echo "creating very long named file"
16574         touch $longname1 || error "create of '$longname1' failed"
16575         echo "renaming very long named file"
16576         mv $longname1 $longname2
16577
16578         changelog_dump | grep RENME | tail -n 5
16579         rm -f $longname2
16580 }
16581 run_test 160b "Verify that very long rename doesn't crash in changelog"
16582
16583 test_160c() {
16584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16585         remote_mds_nodsh && skip "remote MDS with nodsh"
16586
16587         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16588                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16589                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16590                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16591
16592         local rc=0
16593
16594         # Registration step
16595         changelog_register || error "changelog_register failed"
16596
16597         rm -rf $DIR/$tdir
16598         mkdir -p $DIR/$tdir
16599         $MCREATE $DIR/$tdir/foo_160c
16600         changelog_chmask "-TRUNC"
16601         $TRUNCATE $DIR/$tdir/foo_160c 200
16602         changelog_chmask "+TRUNC"
16603         $TRUNCATE $DIR/$tdir/foo_160c 199
16604         changelog_dump | tail -n 5
16605         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16606         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16607 }
16608 run_test 160c "verify that changelog log catch the truncate event"
16609
16610 test_160d() {
16611         remote_mds_nodsh && skip "remote MDS with nodsh"
16612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16614         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16615                 skip "Need MDS version at least 2.7.60"
16616
16617         # Registration step
16618         changelog_register || error "changelog_register failed"
16619
16620         mkdir -p $DIR/$tdir/migrate_dir
16621         changelog_clear 0 || error "changelog_clear failed"
16622
16623         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16624         changelog_dump | tail -n 5
16625         local migrates=$(changelog_dump | grep -c "MIGRT")
16626         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16627 }
16628 run_test 160d "verify that changelog log catch the migrate event"
16629
16630 test_160e() {
16631         remote_mds_nodsh && skip "remote MDS with nodsh"
16632
16633         # Create a user
16634         changelog_register || error "changelog_register failed"
16635
16636         local MDT0=$(facet_svc $SINGLEMDS)
16637         local rc
16638
16639         # No user (expect fail)
16640         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16641         rc=$?
16642         if [ $rc -eq 0 ]; then
16643                 error "Should fail without user"
16644         elif [ $rc -ne 4 ]; then
16645                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16646         fi
16647
16648         # Delete a future user (expect fail)
16649         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16650         rc=$?
16651         if [ $rc -eq 0 ]; then
16652                 error "Deleted non-existant user cl77"
16653         elif [ $rc -ne 2 ]; then
16654                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16655         fi
16656
16657         # Clear to a bad index (1 billion should be safe)
16658         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16659         rc=$?
16660
16661         if [ $rc -eq 0 ]; then
16662                 error "Successfully cleared to invalid CL index"
16663         elif [ $rc -ne 22 ]; then
16664                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16665         fi
16666 }
16667 run_test 160e "changelog negative testing (should return errors)"
16668
16669 test_160f() {
16670         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16671         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16672                 skip "Need MDS version at least 2.10.56"
16673
16674         local mdts=$(comma_list $(mdts_nodes))
16675
16676         # Create a user
16677         changelog_register || error "first changelog_register failed"
16678         changelog_register || error "second changelog_register failed"
16679         local cl_users
16680         declare -A cl_user1
16681         declare -A cl_user2
16682         local user_rec1
16683         local user_rec2
16684         local i
16685
16686         # generate some changelog records to accumulate on each MDT
16687         # use all_char because created files should be evenly distributed
16688         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16689                 error "test_mkdir $tdir failed"
16690         log "$(date +%s): creating first files"
16691         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16692                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16693                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16694         done
16695
16696         # check changelogs have been generated
16697         local start=$SECONDS
16698         local idle_time=$((MDSCOUNT * 5 + 5))
16699         local nbcl=$(changelog_dump | wc -l)
16700         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16701
16702         for param in "changelog_max_idle_time=$idle_time" \
16703                      "changelog_gc=1" \
16704                      "changelog_min_gc_interval=2" \
16705                      "changelog_min_free_cat_entries=3"; do
16706                 local MDT0=$(facet_svc $SINGLEMDS)
16707                 local var="${param%=*}"
16708                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16709
16710                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16711                 do_nodes $mdts $LCTL set_param mdd.*.$param
16712         done
16713
16714         # force cl_user2 to be idle (1st part), but also cancel the
16715         # cl_user1 records so that it is not evicted later in the test.
16716         local sleep1=$((idle_time / 2))
16717         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16718         sleep $sleep1
16719
16720         # simulate changelog catalog almost full
16721         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16722         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16723
16724         for i in $(seq $MDSCOUNT); do
16725                 cl_users=(${CL_USERS[mds$i]})
16726                 cl_user1[mds$i]="${cl_users[0]}"
16727                 cl_user2[mds$i]="${cl_users[1]}"
16728
16729                 [ -n "${cl_user1[mds$i]}" ] ||
16730                         error "mds$i: no user registered"
16731                 [ -n "${cl_user2[mds$i]}" ] ||
16732                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16733
16734                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16735                 [ -n "$user_rec1" ] ||
16736                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16737                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16738                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16739                 [ -n "$user_rec2" ] ||
16740                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16741                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16742                      "$user_rec1 + 2 == $user_rec2"
16743                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16744                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16745                               "$user_rec1 + 2, but is $user_rec2"
16746                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16747                 [ -n "$user_rec2" ] ||
16748                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16749                 [ $user_rec1 == $user_rec2 ] ||
16750                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16751                               "$user_rec1, but is $user_rec2"
16752         done
16753
16754         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16755         local sleep2=$((idle_time - (SECONDS - start) + 1))
16756         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16757         sleep $sleep2
16758
16759         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16760         # cl_user1 should be OK because it recently processed records.
16761         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16762         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16763                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16764                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16765         done
16766
16767         # ensure gc thread is done
16768         for i in $(mdts_nodes); do
16769                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16770                         error "$i: GC-thread not done"
16771         done
16772
16773         local first_rec
16774         for (( i = 1; i <= MDSCOUNT; i++ )); do
16775                 # check cl_user1 still registered
16776                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16777                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16778                 # check cl_user2 unregistered
16779                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16780                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16781
16782                 # check changelogs are present and starting at $user_rec1 + 1
16783                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16784                 [ -n "$user_rec1" ] ||
16785                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16786                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16787                             awk '{ print $1; exit; }')
16788
16789                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16790                 [ $((user_rec1 + 1)) == $first_rec ] ||
16791                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16792         done
16793 }
16794 run_test 160f "changelog garbage collect (timestamped users)"
16795
16796 test_160g() {
16797         remote_mds_nodsh && skip "remote MDS with nodsh"
16798         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16799                 skip "Need MDS version at least 2.14.55"
16800
16801         local mdts=$(comma_list $(mdts_nodes))
16802
16803         # Create a user
16804         changelog_register || error "first changelog_register failed"
16805         changelog_register || error "second changelog_register failed"
16806         local cl_users
16807         declare -A cl_user1
16808         declare -A cl_user2
16809         local user_rec1
16810         local user_rec2
16811         local i
16812
16813         # generate some changelog records to accumulate on each MDT
16814         # use all_char because created files should be evenly distributed
16815         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16816                 error "test_mkdir $tdir failed"
16817         for ((i = 0; i < MDSCOUNT; i++)); do
16818                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16819                         error "create $DIR/$tdir/d$i.1 failed"
16820         done
16821
16822         # check changelogs have been generated
16823         local nbcl=$(changelog_dump | wc -l)
16824         (( $nbcl > 0 )) || error "no changelogs found"
16825
16826         # reduce the max_idle_indexes value to make sure we exceed it
16827         for param in "changelog_max_idle_indexes=2" \
16828                      "changelog_gc=1" \
16829                      "changelog_min_gc_interval=2"; do
16830                 local MDT0=$(facet_svc $SINGLEMDS)
16831                 local var="${param%=*}"
16832                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16833
16834                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16835                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16836                         error "unable to set mdd.*.$param"
16837         done
16838
16839         local start=$SECONDS
16840         for i in $(seq $MDSCOUNT); do
16841                 cl_users=(${CL_USERS[mds$i]})
16842                 cl_user1[mds$i]="${cl_users[0]}"
16843                 cl_user2[mds$i]="${cl_users[1]}"
16844
16845                 [ -n "${cl_user1[mds$i]}" ] ||
16846                         error "mds$i: user1 is not registered"
16847                 [ -n "${cl_user2[mds$i]}" ] ||
16848                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16849
16850                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16851                 [ -n "$user_rec1" ] ||
16852                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16853                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16854                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16855                 [ -n "$user_rec2" ] ||
16856                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16857                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16858                      "$user_rec1 + 2 == $user_rec2"
16859                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16860                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16861                               "expected $user_rec1 + 2, but is $user_rec2"
16862                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16863                 [ -n "$user_rec2" ] ||
16864                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16865                 [ $user_rec1 == $user_rec2 ] ||
16866                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16867                               "expected $user_rec1, but is $user_rec2"
16868         done
16869
16870         # ensure we are past the previous changelog_min_gc_interval set above
16871         local sleep2=$((start + 2 - SECONDS))
16872         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16873         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16874         # cl_user1 should be OK because it recently processed records.
16875         for ((i = 0; i < MDSCOUNT; i++)); do
16876                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16877                         error "create $DIR/$tdir/d$i.3 failed"
16878         done
16879
16880         # ensure gc thread is done
16881         for i in $(mdts_nodes); do
16882                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16883                         error "$i: GC-thread not done"
16884         done
16885
16886         local first_rec
16887         for (( i = 1; i <= MDSCOUNT; i++ )); do
16888                 # check cl_user1 still registered
16889                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16890                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16891                 # check cl_user2 unregistered
16892                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16893                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16894
16895                 # check changelogs are present and starting at $user_rec1 + 1
16896                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16897                 [ -n "$user_rec1" ] ||
16898                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16899                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16900                             awk '{ print $1; exit; }')
16901
16902                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16903                 [ $((user_rec1 + 1)) == $first_rec ] ||
16904                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16905         done
16906 }
16907 run_test 160g "changelog garbage collect on idle records"
16908
16909 test_160h() {
16910         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16911         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16912                 skip "Need MDS version at least 2.10.56"
16913
16914         local mdts=$(comma_list $(mdts_nodes))
16915
16916         # Create a user
16917         changelog_register || error "first changelog_register failed"
16918         changelog_register || error "second changelog_register failed"
16919         local cl_users
16920         declare -A cl_user1
16921         declare -A cl_user2
16922         local user_rec1
16923         local user_rec2
16924         local i
16925
16926         # generate some changelog records to accumulate on each MDT
16927         # use all_char because created files should be evenly distributed
16928         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16929                 error "test_mkdir $tdir failed"
16930         for ((i = 0; i < MDSCOUNT; i++)); do
16931                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16932                         error "create $DIR/$tdir/d$i.1 failed"
16933         done
16934
16935         # check changelogs have been generated
16936         local nbcl=$(changelog_dump | wc -l)
16937         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16938
16939         for param in "changelog_max_idle_time=10" \
16940                      "changelog_gc=1" \
16941                      "changelog_min_gc_interval=2"; do
16942                 local MDT0=$(facet_svc $SINGLEMDS)
16943                 local var="${param%=*}"
16944                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16945
16946                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16947                 do_nodes $mdts $LCTL set_param mdd.*.$param
16948         done
16949
16950         # force cl_user2 to be idle (1st part)
16951         sleep 9
16952
16953         for i in $(seq $MDSCOUNT); do
16954                 cl_users=(${CL_USERS[mds$i]})
16955                 cl_user1[mds$i]="${cl_users[0]}"
16956                 cl_user2[mds$i]="${cl_users[1]}"
16957
16958                 [ -n "${cl_user1[mds$i]}" ] ||
16959                         error "mds$i: no user registered"
16960                 [ -n "${cl_user2[mds$i]}" ] ||
16961                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16962
16963                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16964                 [ -n "$user_rec1" ] ||
16965                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16966                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16967                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16968                 [ -n "$user_rec2" ] ||
16969                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16970                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16971                      "$user_rec1 + 2 == $user_rec2"
16972                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16973                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16974                               "$user_rec1 + 2, but is $user_rec2"
16975                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16976                 [ -n "$user_rec2" ] ||
16977                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16978                 [ $user_rec1 == $user_rec2 ] ||
16979                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16980                               "$user_rec1, but is $user_rec2"
16981         done
16982
16983         # force cl_user2 to be idle (2nd part) and to reach
16984         # changelog_max_idle_time
16985         sleep 2
16986
16987         # force each GC-thread start and block then
16988         # one per MDT/MDD, set fail_val accordingly
16989         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16990         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16991
16992         # generate more changelogs to trigger fail_loc
16993         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16994                 error "create $DIR/$tdir/${tfile}bis failed"
16995
16996         # stop MDT to stop GC-thread, should be done in back-ground as it will
16997         # block waiting for the thread to be released and exit
16998         declare -A stop_pids
16999         for i in $(seq $MDSCOUNT); do
17000                 stop mds$i &
17001                 stop_pids[mds$i]=$!
17002         done
17003
17004         for i in $(mdts_nodes); do
17005                 local facet
17006                 local nb=0
17007                 local facets=$(facets_up_on_host $i)
17008
17009                 for facet in ${facets//,/ }; do
17010                         if [[ $facet == mds* ]]; then
17011                                 nb=$((nb + 1))
17012                         fi
17013                 done
17014                 # ensure each MDS's gc threads are still present and all in "R"
17015                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17016                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17017                         error "$i: expected $nb GC-thread"
17018                 wait_update $i \
17019                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17020                         "R" 20 ||
17021                         error "$i: GC-thread not found in R-state"
17022                 # check umounts of each MDT on MDS have reached kthread_stop()
17023                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17024                         error "$i: expected $nb umount"
17025                 wait_update $i \
17026                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17027                         error "$i: umount not found in D-state"
17028         done
17029
17030         # release all GC-threads
17031         do_nodes $mdts $LCTL set_param fail_loc=0
17032
17033         # wait for MDT stop to complete
17034         for i in $(seq $MDSCOUNT); do
17035                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17036         done
17037
17038         # XXX
17039         # may try to check if any orphan changelog records are present
17040         # via ldiskfs/zfs and llog_reader...
17041
17042         # re-start/mount MDTs
17043         for i in $(seq $MDSCOUNT); do
17044                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17045                         error "Fail to start mds$i"
17046         done
17047
17048         local first_rec
17049         for i in $(seq $MDSCOUNT); do
17050                 # check cl_user1 still registered
17051                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17052                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17053                 # check cl_user2 unregistered
17054                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17055                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17056
17057                 # check changelogs are present and starting at $user_rec1 + 1
17058                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17059                 [ -n "$user_rec1" ] ||
17060                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17061                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17062                             awk '{ print $1; exit; }')
17063
17064                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17065                 [ $((user_rec1 + 1)) == $first_rec ] ||
17066                         error "mds$i: first index should be $user_rec1 + 1, " \
17067                               "but is $first_rec"
17068         done
17069 }
17070 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17071               "during mount"
17072
17073 test_160i() {
17074
17075         local mdts=$(comma_list $(mdts_nodes))
17076
17077         changelog_register || error "first changelog_register failed"
17078
17079         # generate some changelog records to accumulate on each MDT
17080         # use all_char because created files should be evenly distributed
17081         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17082                 error "test_mkdir $tdir failed"
17083         for ((i = 0; i < MDSCOUNT; i++)); do
17084                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17085                         error "create $DIR/$tdir/d$i.1 failed"
17086         done
17087
17088         # check changelogs have been generated
17089         local nbcl=$(changelog_dump | wc -l)
17090         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17091
17092         # simulate race between register and unregister
17093         # XXX as fail_loc is set per-MDS, with DNE configs the race
17094         # simulation will only occur for one MDT per MDS and for the
17095         # others the normal race scenario will take place
17096         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17097         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17098         do_nodes $mdts $LCTL set_param fail_val=1
17099
17100         # unregister 1st user
17101         changelog_deregister &
17102         local pid1=$!
17103         # wait some time for deregister work to reach race rdv
17104         sleep 2
17105         # register 2nd user
17106         changelog_register || error "2nd user register failed"
17107
17108         wait $pid1 || error "1st user deregister failed"
17109
17110         local i
17111         local last_rec
17112         declare -A LAST_REC
17113         for i in $(seq $MDSCOUNT); do
17114                 if changelog_users mds$i | grep "^cl"; then
17115                         # make sure new records are added with one user present
17116                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17117                                           awk '/^current.index:/ { print $NF }')
17118                 else
17119                         error "mds$i has no user registered"
17120                 fi
17121         done
17122
17123         # generate more changelog records to accumulate on each MDT
17124         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17125                 error "create $DIR/$tdir/${tfile}bis failed"
17126
17127         for i in $(seq $MDSCOUNT); do
17128                 last_rec=$(changelog_users $SINGLEMDS |
17129                            awk '/^current.index:/ { print $NF }')
17130                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17131                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17132                         error "changelogs are off on mds$i"
17133         done
17134 }
17135 run_test 160i "changelog user register/unregister race"
17136
17137 test_160j() {
17138         remote_mds_nodsh && skip "remote MDS with nodsh"
17139         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17140                 skip "Need MDS version at least 2.12.56"
17141
17142         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17143         stack_trap "umount $MOUNT2" EXIT
17144
17145         changelog_register || error "first changelog_register failed"
17146         stack_trap "changelog_deregister" EXIT
17147
17148         # generate some changelog
17149         # use all_char because created files should be evenly distributed
17150         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17151                 error "mkdir $tdir failed"
17152         for ((i = 0; i < MDSCOUNT; i++)); do
17153                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17154                         error "create $DIR/$tdir/d$i.1 failed"
17155         done
17156
17157         # open the changelog device
17158         exec 3>/dev/changelog-$FSNAME-MDT0000
17159         stack_trap "exec 3>&-" EXIT
17160         exec 4</dev/changelog-$FSNAME-MDT0000
17161         stack_trap "exec 4<&-" EXIT
17162
17163         # umount the first lustre mount
17164         umount $MOUNT
17165         stack_trap "mount_client $MOUNT" EXIT
17166
17167         # read changelog, which may or may not fail, but should not crash
17168         cat <&4 >/dev/null
17169
17170         # clear changelog
17171         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17172         changelog_users $SINGLEMDS | grep -q $cl_user ||
17173                 error "User $cl_user not found in changelog_users"
17174
17175         printf 'clear:'$cl_user':0' >&3
17176 }
17177 run_test 160j "client can be umounted while its chanangelog is being used"
17178
17179 test_160k() {
17180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17181         remote_mds_nodsh && skip "remote MDS with nodsh"
17182
17183         mkdir -p $DIR/$tdir/1/1
17184
17185         changelog_register || error "changelog_register failed"
17186         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17187
17188         changelog_users $SINGLEMDS | grep -q $cl_user ||
17189                 error "User '$cl_user' not found in changelog_users"
17190 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17191         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17192         rmdir $DIR/$tdir/1/1 & sleep 1
17193         mkdir $DIR/$tdir/2
17194         touch $DIR/$tdir/2/2
17195         rm -rf $DIR/$tdir/2
17196
17197         wait
17198         sleep 4
17199
17200         changelog_dump | grep rmdir || error "rmdir not recorded"
17201 }
17202 run_test 160k "Verify that changelog records are not lost"
17203
17204 # Verifies that a file passed as a parameter has recently had an operation
17205 # performed on it that has generated an MTIME changelog which contains the
17206 # correct parent FID. As files might reside on a different MDT from the
17207 # parent directory in DNE configurations, the FIDs are translated to paths
17208 # before being compared, which should be identical
17209 compare_mtime_changelog() {
17210         local file="${1}"
17211         local mdtidx
17212         local mtime
17213         local cl_fid
17214         local pdir
17215         local dir
17216
17217         mdtidx=$($LFS getstripe --mdt-index $file)
17218         mdtidx=$(printf "%04x" $mdtidx)
17219
17220         # Obtain the parent FID from the MTIME changelog
17221         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17222         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17223
17224         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17225         [ -z "$cl_fid" ] && error "parent FID not present"
17226
17227         # Verify that the path for the parent FID is the same as the path for
17228         # the test directory
17229         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17230
17231         dir=$(dirname $1)
17232
17233         [[ "${pdir%/}" == "$dir" ]] ||
17234                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17235 }
17236
17237 test_160l() {
17238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17239
17240         remote_mds_nodsh && skip "remote MDS with nodsh"
17241         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17242                 skip "Need MDS version at least 2.13.55"
17243
17244         local cl_user
17245
17246         changelog_register || error "changelog_register failed"
17247         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17248
17249         changelog_users $SINGLEMDS | grep -q $cl_user ||
17250                 error "User '$cl_user' not found in changelog_users"
17251
17252         # Clear some types so that MTIME changelogs are generated
17253         changelog_chmask "-CREAT"
17254         changelog_chmask "-CLOSE"
17255
17256         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17257
17258         # Test CL_MTIME during setattr
17259         touch $DIR/$tdir/$tfile
17260         compare_mtime_changelog $DIR/$tdir/$tfile
17261
17262         # Test CL_MTIME during close
17263         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17264         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17265 }
17266 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17267
17268 test_160m() {
17269         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17270         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17271                 skip "Need MDS version at least 2.14.51"
17272         local cl_users
17273         local cl_user1
17274         local cl_user2
17275         local pid1
17276
17277         # Create a user
17278         changelog_register || error "first changelog_register failed"
17279         changelog_register || error "second changelog_register failed"
17280
17281         cl_users=(${CL_USERS[mds1]})
17282         cl_user1="${cl_users[0]}"
17283         cl_user2="${cl_users[1]}"
17284         # generate some changelog records to accumulate on MDT0
17285         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17286         createmany -m $DIR/$tdir/$tfile 50 ||
17287                 error "create $DIR/$tdir/$tfile failed"
17288         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17289         rm -f $DIR/$tdir
17290
17291         # check changelogs have been generated
17292         local nbcl=$(changelog_dump | wc -l)
17293         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17294
17295 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17296         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17297
17298         __changelog_clear mds1 $cl_user1 +10
17299         __changelog_clear mds1 $cl_user2 0 &
17300         pid1=$!
17301         sleep 2
17302         __changelog_clear mds1 $cl_user1 0 ||
17303                 error "fail to cancel record for $cl_user1"
17304         wait $pid1
17305         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17306 }
17307 run_test 160m "Changelog clear race"
17308
17309 test_160n() {
17310         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17311         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17312                 skip "Need MDS version at least 2.14.51"
17313         local cl_users
17314         local cl_user1
17315         local cl_user2
17316         local pid1
17317         local first_rec
17318         local last_rec=0
17319
17320         # Create a user
17321         changelog_register || error "first changelog_register failed"
17322
17323         cl_users=(${CL_USERS[mds1]})
17324         cl_user1="${cl_users[0]}"
17325
17326         # generate some changelog records to accumulate on MDT0
17327         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17328         first_rec=$(changelog_users $SINGLEMDS |
17329                         awk '/^current.index:/ { print $NF }')
17330         while (( last_rec < (( first_rec + 65000)) )); do
17331                 createmany -m $DIR/$tdir/$tfile 10000 ||
17332                         error "create $DIR/$tdir/$tfile failed"
17333
17334                 for i in $(seq 0 10000); do
17335                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17336                                 > /dev/null
17337                 done
17338
17339                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17340                         error "unlinkmany failed unlink"
17341                 last_rec=$(changelog_users $SINGLEMDS |
17342                         awk '/^current.index:/ { print $NF }')
17343                 echo last record $last_rec
17344                 (( last_rec == 0 )) && error "no changelog found"
17345         done
17346
17347 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17348         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17349
17350         __changelog_clear mds1 $cl_user1 0 &
17351         pid1=$!
17352         sleep 2
17353         __changelog_clear mds1 $cl_user1 0 ||
17354                 error "fail to cancel record for $cl_user1"
17355         wait $pid1
17356         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17357 }
17358 run_test 160n "Changelog destroy race"
17359
17360 test_160o() {
17361         local mdt="$(facet_svc $SINGLEMDS)"
17362
17363         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17364         remote_mds_nodsh && skip "remote MDS with nodsh"
17365         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17366                 skip "Need MDS version at least 2.14.52"
17367
17368         changelog_register --user test_160o -m unlnk+close+open ||
17369                 error "changelog_register failed"
17370
17371         do_facet $SINGLEMDS $LCTL --device $mdt \
17372                                 changelog_register -u "Tt3_-#" &&
17373                 error "bad symbols in name should fail"
17374
17375         do_facet $SINGLEMDS $LCTL --device $mdt \
17376                                 changelog_register -u test_160o &&
17377                 error "the same name registration should fail"
17378
17379         do_facet $SINGLEMDS $LCTL --device $mdt \
17380                         changelog_register -u test_160toolongname &&
17381                 error "too long name registration should fail"
17382
17383         changelog_chmask "MARK+HSM"
17384         lctl get_param mdd.*.changelog*mask
17385         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17386         changelog_users $SINGLEMDS | grep -q $cl_user ||
17387                 error "User $cl_user not found in changelog_users"
17388         #verify username
17389         echo $cl_user | grep -q test_160o ||
17390                 error "User $cl_user has no specific name 'test160o'"
17391
17392         # change something
17393         changelog_clear 0 || error "changelog_clear failed"
17394         # generate some changelog records to accumulate on MDT0
17395         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17396         touch $DIR/$tdir/$tfile                 # open 1
17397
17398         OPENS=$(changelog_dump | grep -c "OPEN")
17399         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17400
17401         # must be no MKDIR it wasn't set as user mask
17402         MKDIR=$(changelog_dump | grep -c "MKDIR")
17403         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17404
17405         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17406                                 mdd.$mdt.changelog_current_mask -n)
17407         # register maskless user
17408         changelog_register || error "changelog_register failed"
17409         # effective mask should be not changed because it is not minimal
17410         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17411                                 mdd.$mdt.changelog_current_mask -n)
17412         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17413         # set server mask to minimal value
17414         changelog_chmask "MARK"
17415         # check effective mask again, should be treated as DEFMASK now
17416         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17417                                 mdd.$mdt.changelog_current_mask -n)
17418         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17419
17420         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17421                 # set server mask back to some value
17422                 changelog_chmask "CLOSE,UNLNK"
17423                 # check effective mask again, should not remain as DEFMASK
17424                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17425                                 mdd.$mdt.changelog_current_mask -n)
17426                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17427         fi
17428
17429         do_facet $SINGLEMDS $LCTL --device $mdt \
17430                                 changelog_deregister -u test_160o ||
17431                 error "cannot deregister by name"
17432 }
17433 run_test 160o "changelog user name and mask"
17434
17435 test_160p() {
17436         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17437         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17438                 skip "Need MDS version at least 2.14.51"
17439         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17440         local cl_users
17441         local cl_user1
17442         local entry_count
17443
17444         # Create a user
17445         changelog_register || error "first changelog_register failed"
17446
17447         cl_users=(${CL_USERS[mds1]})
17448         cl_user1="${cl_users[0]}"
17449
17450         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17451         createmany -m $DIR/$tdir/$tfile 50 ||
17452                 error "create $DIR/$tdir/$tfile failed"
17453         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17454         rm -rf $DIR/$tdir
17455
17456         # check changelogs have been generated
17457         entry_count=$(changelog_dump | wc -l)
17458         ((entry_count != 0)) || error "no changelog entries found"
17459
17460         # remove changelog_users and check that orphan entries are removed
17461         stop mds1
17462         local dev=$(mdsdevname 1)
17463         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17464         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17465         entry_count=$(changelog_dump | wc -l)
17466         ((entry_count == 0)) ||
17467                 error "found $entry_count changelog entries, expected none"
17468 }
17469 run_test 160p "Changelog orphan cleanup with no users"
17470
17471 test_160q() {
17472         local mdt="$(facet_svc $SINGLEMDS)"
17473         local clu
17474
17475         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17476         remote_mds_nodsh && skip "remote MDS with nodsh"
17477         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17478                 skip "Need MDS version at least 2.14.54"
17479
17480         # set server mask to minimal value like server init does
17481         changelog_chmask "MARK"
17482         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17483                 error "changelog_register failed"
17484         # check effective mask again, should be treated as DEFMASK now
17485         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17486                                 mdd.$mdt.changelog_current_mask -n)
17487         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17488                 error "changelog_deregister failed"
17489         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17490 }
17491 run_test 160q "changelog effective mask is DEFMASK if not set"
17492
17493 test_160s() {
17494         remote_mds_nodsh && skip "remote MDS with nodsh"
17495         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17496                 skip "Need MDS version at least 2.14.55"
17497
17498         local mdts=$(comma_list $(mdts_nodes))
17499
17500         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17501         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17502                                        fail_val=$((24 * 3600 * 10))
17503
17504         # Create a user which is 10 days old
17505         changelog_register || error "first changelog_register failed"
17506         local cl_users
17507         declare -A cl_user1
17508         local i
17509
17510         # generate some changelog records to accumulate on each MDT
17511         # use all_char because created files should be evenly distributed
17512         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17513                 error "test_mkdir $tdir failed"
17514         for ((i = 0; i < MDSCOUNT; i++)); do
17515                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17516                         error "create $DIR/$tdir/d$i.1 failed"
17517         done
17518
17519         # check changelogs have been generated
17520         local nbcl=$(changelog_dump | wc -l)
17521         (( nbcl > 0 )) || error "no changelogs found"
17522
17523         # reduce the max_idle_indexes value to make sure we exceed it
17524         for param in "changelog_max_idle_indexes=2097446912" \
17525                      "changelog_max_idle_time=2592000" \
17526                      "changelog_gc=1" \
17527                      "changelog_min_gc_interval=2"; do
17528                 local MDT0=$(facet_svc $SINGLEMDS)
17529                 local var="${param%=*}"
17530                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17531
17532                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17533                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17534                         error "unable to set mdd.*.$param"
17535         done
17536
17537         local start=$SECONDS
17538         for i in $(seq $MDSCOUNT); do
17539                 cl_users=(${CL_USERS[mds$i]})
17540                 cl_user1[mds$i]="${cl_users[0]}"
17541
17542                 [[ -n "${cl_user1[mds$i]}" ]] ||
17543                         error "mds$i: no user registered"
17544         done
17545
17546         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17547         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17548
17549         # ensure we are past the previous changelog_min_gc_interval set above
17550         local sleep2=$((start + 2 - SECONDS))
17551         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17552
17553         # Generate one more changelog to trigger GC
17554         for ((i = 0; i < MDSCOUNT; i++)); do
17555                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17556                         error "create $DIR/$tdir/d$i.3 failed"
17557         done
17558
17559         # ensure gc thread is done
17560         for node in $(mdts_nodes); do
17561                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17562                         error "$node: GC-thread not done"
17563         done
17564
17565         do_nodes $mdts $LCTL set_param fail_loc=0
17566
17567         for (( i = 1; i <= MDSCOUNT; i++ )); do
17568                 # check cl_user1 is purged
17569                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17570                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17571         done
17572         return 0
17573 }
17574 run_test 160s "changelog garbage collect on idle records * time"
17575
17576 test_160t() {
17577         remote_mds_nodsh && skip "remote MDS with nodsh"
17578         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17579                 skip "Need MDS version at least 2.15.50"
17580
17581         local MDT0=$(facet_svc $SINGLEMDS)
17582         local cl_users
17583         local cl_user1
17584         local cl_user2
17585         local start
17586
17587         changelog_register --user user1 -m all ||
17588                 error "user1 failed to register"
17589
17590         mkdir_on_mdt0 $DIR/$tdir
17591         # create default overstripe to maximize changelog size
17592         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17593         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17594         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17595
17596         # user2 consumes less records so less space
17597         changelog_register --user user2 || error "user2 failed to register"
17598         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17599         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17600
17601         # check changelogs have been generated
17602         local nbcl=$(changelog_dump | wc -l)
17603         (( nbcl > 0 )) || error "no changelogs found"
17604
17605         # reduce the changelog_min_gc_interval to force check
17606         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17607                 local var="${param%=*}"
17608                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17609
17610                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17611                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17612                         error "unable to set mdd.*.$param"
17613         done
17614
17615         start=$SECONDS
17616         cl_users=(${CL_USERS[mds1]})
17617         cl_user1="${cl_users[0]}"
17618         cl_user2="${cl_users[1]}"
17619
17620         [[ -n $cl_user1 ]] ||
17621                 error "mds1: user #1 isn't registered"
17622         [[ -n $cl_user2 ]] ||
17623                 error "mds1: user #2 isn't registered"
17624
17625         # ensure we are past the previous changelog_min_gc_interval set above
17626         local sleep2=$((start + 2 - SECONDS))
17627         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17628
17629         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17630         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17631                         fail_val=$(((llog_size1 + llog_size2) / 2))
17632
17633         # Generate more changelog to trigger GC
17634         createmany -o $DIR/$tdir/u3_ 4 ||
17635                 error "create failed for more files"
17636
17637         # ensure gc thread is done
17638         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17639                 error "mds1: GC-thread not done"
17640
17641         do_facet mds1 $LCTL set_param fail_loc=0
17642
17643         # check cl_user1 is purged
17644         changelog_users mds1 | grep -q "$cl_user1" &&
17645                 error "User $cl_user1 is registered"
17646         # check cl_user2 is not purged
17647         changelog_users mds1 | grep -q "$cl_user2" ||
17648                 error "User $cl_user2 is not registered"
17649 }
17650 run_test 160t "changelog garbage collect on lack of space"
17651
17652 test_161a() {
17653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17654
17655         test_mkdir -c1 $DIR/$tdir
17656         cp /etc/hosts $DIR/$tdir/$tfile
17657         test_mkdir -c1 $DIR/$tdir/foo1
17658         test_mkdir -c1 $DIR/$tdir/foo2
17659         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17660         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17661         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17662         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17663         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17664         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17665                 $LFS fid2path $DIR $FID
17666                 error "bad link ea"
17667         fi
17668         # middle
17669         rm $DIR/$tdir/foo2/zachary
17670         # last
17671         rm $DIR/$tdir/foo2/thor
17672         # first
17673         rm $DIR/$tdir/$tfile
17674         # rename
17675         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17676         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17677                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17678         rm $DIR/$tdir/foo2/maggie
17679
17680         # overflow the EA
17681         local longname=$tfile.avg_len_is_thirty_two_
17682         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17683                 error_noexit 'failed to unlink many hardlinks'" EXIT
17684         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17685                 error "failed to hardlink many files"
17686         links=$($LFS fid2path $DIR $FID | wc -l)
17687         echo -n "${links}/1000 links in link EA"
17688         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17689 }
17690 run_test 161a "link ea sanity"
17691
17692 test_161b() {
17693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17694         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17695
17696         local MDTIDX=1
17697         local remote_dir=$DIR/$tdir/remote_dir
17698
17699         mkdir -p $DIR/$tdir
17700         $LFS mkdir -i $MDTIDX $remote_dir ||
17701                 error "create remote directory failed"
17702
17703         cp /etc/hosts $remote_dir/$tfile
17704         mkdir -p $remote_dir/foo1
17705         mkdir -p $remote_dir/foo2
17706         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17707         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17708         ln $remote_dir/$tfile $remote_dir/foo1/luna
17709         ln $remote_dir/$tfile $remote_dir/foo2/thor
17710
17711         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17712                      tr -d ']')
17713         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17714                 $LFS fid2path $DIR $FID
17715                 error "bad link ea"
17716         fi
17717         # middle
17718         rm $remote_dir/foo2/zachary
17719         # last
17720         rm $remote_dir/foo2/thor
17721         # first
17722         rm $remote_dir/$tfile
17723         # rename
17724         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17725         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17726         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17727                 $LFS fid2path $DIR $FID
17728                 error "bad link rename"
17729         fi
17730         rm $remote_dir/foo2/maggie
17731
17732         # overflow the EA
17733         local longname=filename_avg_len_is_thirty_two_
17734         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17735                 error "failed to hardlink many files"
17736         links=$($LFS fid2path $DIR $FID | wc -l)
17737         echo -n "${links}/1000 links in link EA"
17738         [[ ${links} -gt 60 ]] ||
17739                 error "expected at least 60 links in link EA"
17740         unlinkmany $remote_dir/foo2/$longname 1000 ||
17741         error "failed to unlink many hardlinks"
17742 }
17743 run_test 161b "link ea sanity under remote directory"
17744
17745 test_161c() {
17746         remote_mds_nodsh && skip "remote MDS with nodsh"
17747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17748         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17749                 skip "Need MDS version at least 2.1.5"
17750
17751         # define CLF_RENAME_LAST 0x0001
17752         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17753         changelog_register || error "changelog_register failed"
17754
17755         rm -rf $DIR/$tdir
17756         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17757         touch $DIR/$tdir/foo_161c
17758         touch $DIR/$tdir/bar_161c
17759         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17760         changelog_dump | grep RENME | tail -n 5
17761         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17762         changelog_clear 0 || error "changelog_clear failed"
17763         if [ x$flags != "x0x1" ]; then
17764                 error "flag $flags is not 0x1"
17765         fi
17766
17767         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17768         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17769         touch $DIR/$tdir/foo_161c
17770         touch $DIR/$tdir/bar_161c
17771         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17772         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17773         changelog_dump | grep RENME | tail -n 5
17774         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17775         changelog_clear 0 || error "changelog_clear failed"
17776         if [ x$flags != "x0x0" ]; then
17777                 error "flag $flags is not 0x0"
17778         fi
17779         echo "rename overwrite a target having nlink > 1," \
17780                 "changelog record has flags of $flags"
17781
17782         # rename doesn't overwrite a target (changelog flag 0x0)
17783         touch $DIR/$tdir/foo_161c
17784         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17785         changelog_dump | grep RENME | tail -n 5
17786         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17787         changelog_clear 0 || error "changelog_clear failed"
17788         if [ x$flags != "x0x0" ]; then
17789                 error "flag $flags is not 0x0"
17790         fi
17791         echo "rename doesn't overwrite a target," \
17792                 "changelog record has flags of $flags"
17793
17794         # define CLF_UNLINK_LAST 0x0001
17795         # unlink a file having nlink = 1 (changelog flag 0x1)
17796         rm -f $DIR/$tdir/foo2_161c
17797         changelog_dump | grep UNLNK | tail -n 5
17798         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17799         changelog_clear 0 || error "changelog_clear failed"
17800         if [ x$flags != "x0x1" ]; then
17801                 error "flag $flags is not 0x1"
17802         fi
17803         echo "unlink a file having nlink = 1," \
17804                 "changelog record has flags of $flags"
17805
17806         # unlink a file having nlink > 1 (changelog flag 0x0)
17807         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17808         rm -f $DIR/$tdir/foobar_161c
17809         changelog_dump | grep UNLNK | tail -n 5
17810         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17811         changelog_clear 0 || error "changelog_clear failed"
17812         if [ x$flags != "x0x0" ]; then
17813                 error "flag $flags is not 0x0"
17814         fi
17815         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17816 }
17817 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17818
17819 test_161d() {
17820         remote_mds_nodsh && skip "remote MDS with nodsh"
17821         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17822
17823         local pid
17824         local fid
17825
17826         changelog_register || error "changelog_register failed"
17827
17828         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17829         # interfer with $MOUNT/.lustre/fid/ access
17830         mkdir $DIR/$tdir
17831         [[ $? -eq 0 ]] || error "mkdir failed"
17832
17833         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17834         $LCTL set_param fail_loc=0x8000140c
17835         # 5s pause
17836         $LCTL set_param fail_val=5
17837
17838         # create file
17839         echo foofoo > $DIR/$tdir/$tfile &
17840         pid=$!
17841
17842         # wait for create to be delayed
17843         sleep 2
17844
17845         ps -p $pid
17846         [[ $? -eq 0 ]] || error "create should be blocked"
17847
17848         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17849         stack_trap "rm -f $tempfile"
17850         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17851         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17852         # some delay may occur during ChangeLog publishing and file read just
17853         # above, that could allow file write to happen finally
17854         [[ -s $tempfile ]] && echo "file should be empty"
17855
17856         $LCTL set_param fail_loc=0
17857
17858         wait $pid
17859         [[ $? -eq 0 ]] || error "create failed"
17860 }
17861 run_test 161d "create with concurrent .lustre/fid access"
17862
17863 check_path() {
17864         local expected="$1"
17865         shift
17866         local fid="$2"
17867
17868         local path
17869         path=$($LFS fid2path "$@")
17870         local rc=$?
17871
17872         if [ $rc -ne 0 ]; then
17873                 error "path looked up of '$expected' failed: rc=$rc"
17874         elif [ "$path" != "$expected" ]; then
17875                 error "path looked up '$path' instead of '$expected'"
17876         else
17877                 echo "FID '$fid' resolves to path '$path' as expected"
17878         fi
17879 }
17880
17881 test_162a() { # was test_162
17882         test_mkdir -p -c1 $DIR/$tdir/d2
17883         touch $DIR/$tdir/d2/$tfile
17884         touch $DIR/$tdir/d2/x1
17885         touch $DIR/$tdir/d2/x2
17886         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17887         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17888         # regular file
17889         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17890         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17891
17892         # softlink
17893         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17894         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17895         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17896
17897         # softlink to wrong file
17898         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17899         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17900         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17901
17902         # hardlink
17903         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17904         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17905         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17906         # fid2path dir/fsname should both work
17907         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17908         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17909
17910         # hardlink count: check that there are 2 links
17911         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17912         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17913
17914         # hardlink indexing: remove the first link
17915         rm $DIR/$tdir/d2/p/q/r/hlink
17916         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17917 }
17918 run_test 162a "path lookup sanity"
17919
17920 test_162b() {
17921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17922         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17923
17924         mkdir $DIR/$tdir
17925         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17926                                 error "create striped dir failed"
17927
17928         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17929                                         tail -n 1 | awk '{print $2}')
17930         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17931
17932         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17933         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17934
17935         # regular file
17936         for ((i=0;i<5;i++)); do
17937                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17938                         error "get fid for f$i failed"
17939                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17940
17941                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17942                         error "get fid for d$i failed"
17943                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17944         done
17945
17946         return 0
17947 }
17948 run_test 162b "striped directory path lookup sanity"
17949
17950 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17951 test_162c() {
17952         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17953                 skip "Need MDS version at least 2.7.51"
17954
17955         local lpath=$tdir.local
17956         local rpath=$tdir.remote
17957
17958         test_mkdir $DIR/$lpath
17959         test_mkdir $DIR/$rpath
17960
17961         for ((i = 0; i <= 101; i++)); do
17962                 lpath="$lpath/$i"
17963                 mkdir $DIR/$lpath
17964                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17965                         error "get fid for local directory $DIR/$lpath failed"
17966                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17967
17968                 rpath="$rpath/$i"
17969                 test_mkdir $DIR/$rpath
17970                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17971                         error "get fid for remote directory $DIR/$rpath failed"
17972                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17973         done
17974
17975         return 0
17976 }
17977 run_test 162c "fid2path works with paths 100 or more directories deep"
17978
17979 oalr_event_count() {
17980         local event="${1}"
17981         local trace="${2}"
17982
17983         awk -v name="${FSNAME}-OST0000" \
17984             -v event="${event}" \
17985             '$1 == "TRACE" && $2 == event && $3 == name' \
17986             "${trace}" |
17987         wc -l
17988 }
17989
17990 oalr_expect_event_count() {
17991         local event="${1}"
17992         local trace="${2}"
17993         local expect="${3}"
17994         local count
17995
17996         count=$(oalr_event_count "${event}" "${trace}")
17997         if ((count == expect)); then
17998                 return 0
17999         fi
18000
18001         error_noexit "${event} event count was '${count}', expected ${expect}"
18002         cat "${trace}" >&2
18003         exit 1
18004 }
18005
18006 cleanup_165() {
18007         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18008         stop ost1
18009         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18010 }
18011
18012 setup_165() {
18013         sync # Flush previous IOs so we can count log entries.
18014         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18015         stack_trap cleanup_165 EXIT
18016 }
18017
18018 test_165a() {
18019         local trace="/tmp/${tfile}.trace"
18020         local rc
18021         local count
18022
18023         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18024                 skip "OFD access log unsupported"
18025
18026         setup_165
18027         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18028         sleep 5
18029
18030         do_facet ost1 ofd_access_log_reader --list
18031         stop ost1
18032
18033         do_facet ost1 killall -TERM ofd_access_log_reader
18034         wait
18035         rc=$?
18036
18037         if ((rc != 0)); then
18038                 error "ofd_access_log_reader exited with rc = '${rc}'"
18039         fi
18040
18041         # Parse trace file for discovery events:
18042         oalr_expect_event_count alr_log_add "${trace}" 1
18043         oalr_expect_event_count alr_log_eof "${trace}" 1
18044         oalr_expect_event_count alr_log_free "${trace}" 1
18045 }
18046 run_test 165a "ofd access log discovery"
18047
18048 test_165b() {
18049         local trace="/tmp/${tfile}.trace"
18050         local file="${DIR}/${tfile}"
18051         local pfid1
18052         local pfid2
18053         local -a entry
18054         local rc
18055         local count
18056         local size
18057         local flags
18058
18059         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18060                 skip "OFD access log unsupported"
18061
18062         setup_165
18063         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18064         sleep 5
18065
18066         do_facet ost1 ofd_access_log_reader --list
18067
18068         lfs setstripe -c 1 -i 0 "${file}"
18069         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18070                 error "cannot create '${file}'"
18071
18072         sleep 5
18073         do_facet ost1 killall -TERM ofd_access_log_reader
18074         wait
18075         rc=$?
18076
18077         if ((rc != 0)); then
18078                 error "ofd_access_log_reader exited with rc = '${rc}'"
18079         fi
18080
18081         oalr_expect_event_count alr_log_entry "${trace}" 1
18082
18083         pfid1=$($LFS path2fid "${file}")
18084
18085         # 1     2             3   4    5     6   7    8    9     10
18086         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18087         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18088
18089         echo "entry = '${entry[*]}'" >&2
18090
18091         pfid2=${entry[4]}
18092         if [[ "${pfid1}" != "${pfid2}" ]]; then
18093                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18094         fi
18095
18096         size=${entry[8]}
18097         if ((size != 1048576)); then
18098                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18099         fi
18100
18101         flags=${entry[10]}
18102         if [[ "${flags}" != "w" ]]; then
18103                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18104         fi
18105
18106         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18107         sleep 5
18108
18109         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18110                 error "cannot read '${file}'"
18111         sleep 5
18112
18113         do_facet ost1 killall -TERM ofd_access_log_reader
18114         wait
18115         rc=$?
18116
18117         if ((rc != 0)); then
18118                 error "ofd_access_log_reader exited with rc = '${rc}'"
18119         fi
18120
18121         oalr_expect_event_count alr_log_entry "${trace}" 1
18122
18123         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18124         echo "entry = '${entry[*]}'" >&2
18125
18126         pfid2=${entry[4]}
18127         if [[ "${pfid1}" != "${pfid2}" ]]; then
18128                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18129         fi
18130
18131         size=${entry[8]}
18132         if ((size != 524288)); then
18133                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18134         fi
18135
18136         flags=${entry[10]}
18137         if [[ "${flags}" != "r" ]]; then
18138                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18139         fi
18140 }
18141 run_test 165b "ofd access log entries are produced and consumed"
18142
18143 test_165c() {
18144         local trace="/tmp/${tfile}.trace"
18145         local file="${DIR}/${tdir}/${tfile}"
18146
18147         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18148                 skip "OFD access log unsupported"
18149
18150         test_mkdir "${DIR}/${tdir}"
18151
18152         setup_165
18153         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18154         sleep 5
18155
18156         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18157
18158         # 4096 / 64 = 64. Create twice as many entries.
18159         for ((i = 0; i < 128; i++)); do
18160                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18161                         error "cannot create file"
18162         done
18163
18164         sync
18165
18166         do_facet ost1 killall -TERM ofd_access_log_reader
18167         wait
18168         rc=$?
18169         if ((rc != 0)); then
18170                 error "ofd_access_log_reader exited with rc = '${rc}'"
18171         fi
18172
18173         unlinkmany  "${file}-%d" 128
18174 }
18175 run_test 165c "full ofd access logs do not block IOs"
18176
18177 oal_get_read_count() {
18178         local stats="$1"
18179
18180         # STATS lustre-OST0001 alr_read_count 1
18181
18182         do_facet ost1 cat "${stats}" |
18183         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18184              END { print count; }'
18185 }
18186
18187 oal_expect_read_count() {
18188         local stats="$1"
18189         local count
18190         local expect="$2"
18191
18192         # Ask ofd_access_log_reader to write stats.
18193         do_facet ost1 killall -USR1 ofd_access_log_reader
18194
18195         # Allow some time for things to happen.
18196         sleep 1
18197
18198         count=$(oal_get_read_count "${stats}")
18199         if ((count == expect)); then
18200                 return 0
18201         fi
18202
18203         error_noexit "bad read count, got ${count}, expected ${expect}"
18204         do_facet ost1 cat "${stats}" >&2
18205         exit 1
18206 }
18207
18208 test_165d() {
18209         local stats="/tmp/${tfile}.stats"
18210         local file="${DIR}/${tdir}/${tfile}"
18211         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18212
18213         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18214                 skip "OFD access log unsupported"
18215
18216         test_mkdir "${DIR}/${tdir}"
18217
18218         setup_165
18219         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18220         sleep 5
18221
18222         lfs setstripe -c 1 -i 0 "${file}"
18223
18224         do_facet ost1 lctl set_param "${param}=rw"
18225         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18226                 error "cannot create '${file}'"
18227         oal_expect_read_count "${stats}" 1
18228
18229         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18230                 error "cannot read '${file}'"
18231         oal_expect_read_count "${stats}" 2
18232
18233         do_facet ost1 lctl set_param "${param}=r"
18234         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18235                 error "cannot create '${file}'"
18236         oal_expect_read_count "${stats}" 2
18237
18238         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18239                 error "cannot read '${file}'"
18240         oal_expect_read_count "${stats}" 3
18241
18242         do_facet ost1 lctl set_param "${param}=w"
18243         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18244                 error "cannot create '${file}'"
18245         oal_expect_read_count "${stats}" 4
18246
18247         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18248                 error "cannot read '${file}'"
18249         oal_expect_read_count "${stats}" 4
18250
18251         do_facet ost1 lctl set_param "${param}=0"
18252         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18253                 error "cannot create '${file}'"
18254         oal_expect_read_count "${stats}" 4
18255
18256         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18257                 error "cannot read '${file}'"
18258         oal_expect_read_count "${stats}" 4
18259
18260         do_facet ost1 killall -TERM ofd_access_log_reader
18261         wait
18262         rc=$?
18263         if ((rc != 0)); then
18264                 error "ofd_access_log_reader exited with rc = '${rc}'"
18265         fi
18266 }
18267 run_test 165d "ofd_access_log mask works"
18268
18269 test_165e() {
18270         local stats="/tmp/${tfile}.stats"
18271         local file0="${DIR}/${tdir}-0/${tfile}"
18272         local file1="${DIR}/${tdir}-1/${tfile}"
18273
18274         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18275                 skip "OFD access log unsupported"
18276
18277         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18278
18279         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18280         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18281
18282         lfs setstripe -c 1 -i 0 "${file0}"
18283         lfs setstripe -c 1 -i 0 "${file1}"
18284
18285         setup_165
18286         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18287         sleep 5
18288
18289         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18290                 error "cannot create '${file0}'"
18291         sync
18292         oal_expect_read_count "${stats}" 0
18293
18294         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18295                 error "cannot create '${file1}'"
18296         sync
18297         oal_expect_read_count "${stats}" 1
18298
18299         do_facet ost1 killall -TERM ofd_access_log_reader
18300         wait
18301         rc=$?
18302         if ((rc != 0)); then
18303                 error "ofd_access_log_reader exited with rc = '${rc}'"
18304         fi
18305 }
18306 run_test 165e "ofd_access_log MDT index filter works"
18307
18308 test_165f() {
18309         local trace="/tmp/${tfile}.trace"
18310         local rc
18311         local count
18312
18313         setup_165
18314         do_facet ost1 timeout 60 ofd_access_log_reader \
18315                 --exit-on-close --debug=- --trace=- > "${trace}" &
18316         sleep 5
18317         stop ost1
18318
18319         wait
18320         rc=$?
18321
18322         if ((rc != 0)); then
18323                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18324                 cat "${trace}"
18325                 exit 1
18326         fi
18327 }
18328 run_test 165f "ofd_access_log_reader --exit-on-close works"
18329
18330 test_169() {
18331         # do directio so as not to populate the page cache
18332         log "creating a 10 Mb file"
18333         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18334                 error "multiop failed while creating a file"
18335         log "starting reads"
18336         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18337         log "truncating the file"
18338         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18339                 error "multiop failed while truncating the file"
18340         log "killing dd"
18341         kill %+ || true # reads might have finished
18342         echo "wait until dd is finished"
18343         wait
18344         log "removing the temporary file"
18345         rm -rf $DIR/$tfile || error "tmp file removal failed"
18346 }
18347 run_test 169 "parallel read and truncate should not deadlock"
18348
18349 test_170() {
18350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18351
18352         $LCTL clear     # bug 18514
18353         $LCTL debug_daemon start $TMP/${tfile}_log_good
18354         touch $DIR/$tfile
18355         $LCTL debug_daemon stop
18356         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18357                 error "sed failed to read log_good"
18358
18359         $LCTL debug_daemon start $TMP/${tfile}_log_good
18360         rm -rf $DIR/$tfile
18361         $LCTL debug_daemon stop
18362
18363         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18364                error "lctl df log_bad failed"
18365
18366         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18367         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18368
18369         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18370         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18371
18372         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18373                 error "bad_line good_line1 good_line2 are empty"
18374
18375         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18376         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18377         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18378
18379         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18380         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18381         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18382
18383         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18384                 error "bad_line_new good_line_new are empty"
18385
18386         local expected_good=$((good_line1 + good_line2*2))
18387
18388         rm -f $TMP/${tfile}*
18389         # LU-231, short malformed line may not be counted into bad lines
18390         if [ $bad_line -ne $bad_line_new ] &&
18391                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18392                 error "expected $bad_line bad lines, but got $bad_line_new"
18393                 return 1
18394         fi
18395
18396         if [ $expected_good -ne $good_line_new ]; then
18397                 error "expected $expected_good good lines, but got $good_line_new"
18398                 return 2
18399         fi
18400         true
18401 }
18402 run_test 170 "test lctl df to handle corrupted log ====================="
18403
18404 test_171() { # bug20592
18405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18406
18407         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18408         $LCTL set_param fail_loc=0x50e
18409         $LCTL set_param fail_val=3000
18410         multiop_bg_pause $DIR/$tfile O_s || true
18411         local MULTIPID=$!
18412         kill -USR1 $MULTIPID
18413         # cause log dump
18414         sleep 3
18415         wait $MULTIPID
18416         if dmesg | grep "recursive fault"; then
18417                 error "caught a recursive fault"
18418         fi
18419         $LCTL set_param fail_loc=0
18420         true
18421 }
18422 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18423
18424 test_172() {
18425
18426         #define OBD_FAIL_OBD_CLEANUP  0x60e
18427         $LCTL set_param fail_loc=0x60e
18428         umount $MOUNT || error "umount $MOUNT failed"
18429         stack_trap "mount_client $MOUNT"
18430
18431         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18432                 error "no client OBDs are remained"
18433
18434         $LCTL dl | while read devno state type name foo; do
18435                 case $type in
18436                 lov|osc|lmv|mdc)
18437                         $LCTL --device $name cleanup
18438                         $LCTL --device $name detach
18439                         ;;
18440                 *)
18441                         # skip server devices
18442                         ;;
18443                 esac
18444         done
18445
18446         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18447                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18448                 error "some client OBDs are still remained"
18449         fi
18450
18451 }
18452 run_test 172 "manual device removal with lctl cleanup/detach ======"
18453
18454 # it would be good to share it with obdfilter-survey/iokit-libecho code
18455 setup_obdecho_osc () {
18456         local rc=0
18457         local ost_nid=$1
18458         local obdfilter_name=$2
18459         echo "Creating new osc for $obdfilter_name on $ost_nid"
18460         # make sure we can find loopback nid
18461         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18462
18463         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18464                            ${obdfilter_name}_osc_UUID || rc=2; }
18465         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18466                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18467         return $rc
18468 }
18469
18470 cleanup_obdecho_osc () {
18471         local obdfilter_name=$1
18472         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18473         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18474         return 0
18475 }
18476
18477 obdecho_test() {
18478         local OBD=$1
18479         local node=$2
18480         local pages=${3:-64}
18481         local rc=0
18482         local id
18483
18484         local count=10
18485         local obd_size=$(get_obd_size $node $OBD)
18486         local page_size=$(get_page_size $node)
18487         if [[ -n "$obd_size" ]]; then
18488                 local new_count=$((obd_size / (pages * page_size / 1024)))
18489                 [[ $new_count -ge $count ]] || count=$new_count
18490         fi
18491
18492         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18493         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18494                            rc=2; }
18495         if [ $rc -eq 0 ]; then
18496             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18497             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18498         fi
18499         echo "New object id is $id"
18500         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18501                            rc=4; }
18502         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18503                            "test_brw $count w v $pages $id" || rc=4; }
18504         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18505                            rc=4; }
18506         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18507                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18508         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18509                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18510         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18511         return $rc
18512 }
18513
18514 test_180a() {
18515         skip "obdecho on osc is no longer supported"
18516 }
18517 run_test 180a "test obdecho on osc"
18518
18519 test_180b() {
18520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18521         remote_ost_nodsh && skip "remote OST with nodsh"
18522
18523         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18524                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18525                 error "failed to load module obdecho"
18526
18527         local target=$(do_facet ost1 $LCTL dl |
18528                        awk '/obdfilter/ { print $4; exit; }')
18529
18530         if [ -n "$target" ]; then
18531                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18532         else
18533                 do_facet ost1 $LCTL dl
18534                 error "there is no obdfilter target on ost1"
18535         fi
18536 }
18537 run_test 180b "test obdecho directly on obdfilter"
18538
18539 test_180c() { # LU-2598
18540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18541         remote_ost_nodsh && skip "remote OST with nodsh"
18542         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18543                 skip "Need MDS version at least 2.4.0"
18544
18545         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18546                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18547                 error "failed to load module obdecho"
18548
18549         local target=$(do_facet ost1 $LCTL dl |
18550                        awk '/obdfilter/ { print $4; exit; }')
18551
18552         if [ -n "$target" ]; then
18553                 local pages=16384 # 64MB bulk I/O RPC size
18554
18555                 obdecho_test "$target" ost1 "$pages" ||
18556                         error "obdecho_test with pages=$pages failed with $?"
18557         else
18558                 do_facet ost1 $LCTL dl
18559                 error "there is no obdfilter target on ost1"
18560         fi
18561 }
18562 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18563
18564 test_181() { # bug 22177
18565         test_mkdir $DIR/$tdir
18566         # create enough files to index the directory
18567         createmany -o $DIR/$tdir/foobar 4000
18568         # print attributes for debug purpose
18569         lsattr -d .
18570         # open dir
18571         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18572         MULTIPID=$!
18573         # remove the files & current working dir
18574         unlinkmany $DIR/$tdir/foobar 4000
18575         rmdir $DIR/$tdir
18576         kill -USR1 $MULTIPID
18577         wait $MULTIPID
18578         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18579         return 0
18580 }
18581 run_test 181 "Test open-unlinked dir ========================"
18582
18583 test_182a() {
18584         local fcount=1000
18585         local tcount=10
18586
18587         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18588
18589         $LCTL set_param mdc.*.rpc_stats=clear
18590
18591         for (( i = 0; i < $tcount; i++ )) ; do
18592                 mkdir $DIR/$tdir/$i
18593         done
18594
18595         for (( i = 0; i < $tcount; i++ )) ; do
18596                 createmany -o $DIR/$tdir/$i/f- $fcount &
18597         done
18598         wait
18599
18600         for (( i = 0; i < $tcount; i++ )) ; do
18601                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18602         done
18603         wait
18604
18605         $LCTL get_param mdc.*.rpc_stats
18606
18607         rm -rf $DIR/$tdir
18608 }
18609 run_test 182a "Test parallel modify metadata operations from mdc"
18610
18611 test_182b() {
18612         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18613         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18614         local dcount=1000
18615         local tcount=10
18616         local stime
18617         local etime
18618         local delta
18619
18620         do_facet mds1 $LCTL list_param \
18621                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18622                 skip "MDS lacks parallel RPC handling"
18623
18624         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18625
18626         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18627                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18628
18629         stime=$(date +%s)
18630         createmany -i 0 -d $DIR/$tdir/t- $tcount
18631
18632         for (( i = 0; i < $tcount; i++ )) ; do
18633                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18634         done
18635         wait
18636         etime=$(date +%s)
18637         delta=$((etime - stime))
18638         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18639
18640         stime=$(date +%s)
18641         for (( i = 0; i < $tcount; i++ )) ; do
18642                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18643         done
18644         wait
18645         etime=$(date +%s)
18646         delta=$((etime - stime))
18647         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18648
18649         rm -rf $DIR/$tdir
18650
18651         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18652
18653         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18654
18655         stime=$(date +%s)
18656         createmany -i 0 -d $DIR/$tdir/t- $tcount
18657
18658         for (( i = 0; i < $tcount; i++ )) ; do
18659                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18660         done
18661         wait
18662         etime=$(date +%s)
18663         delta=$((etime - stime))
18664         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18665
18666         stime=$(date +%s)
18667         for (( i = 0; i < $tcount; i++ )) ; do
18668                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18669         done
18670         wait
18671         etime=$(date +%s)
18672         delta=$((etime - stime))
18673         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18674
18675         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18676 }
18677 run_test 182b "Test parallel modify metadata operations from osp"
18678
18679 test_183() { # LU-2275
18680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18681         remote_mds_nodsh && skip "remote MDS with nodsh"
18682         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18683                 skip "Need MDS version at least 2.3.56"
18684
18685         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18686         echo aaa > $DIR/$tdir/$tfile
18687
18688 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18689         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18690
18691         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18692         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18693
18694         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18695
18696         # Flush negative dentry cache
18697         touch $DIR/$tdir/$tfile
18698
18699         # We are not checking for any leaked references here, they'll
18700         # become evident next time we do cleanup with module unload.
18701         rm -rf $DIR/$tdir
18702 }
18703 run_test 183 "No crash or request leak in case of strange dispositions ========"
18704
18705 # test suite 184 is for LU-2016, LU-2017
18706 test_184a() {
18707         check_swap_layouts_support
18708
18709         dir0=$DIR/$tdir/$testnum
18710         test_mkdir -p -c1 $dir0
18711         ref1=/etc/passwd
18712         ref2=/etc/group
18713         file1=$dir0/f1
18714         file2=$dir0/f2
18715         $LFS setstripe -c1 $file1
18716         cp $ref1 $file1
18717         $LFS setstripe -c2 $file2
18718         cp $ref2 $file2
18719         gen1=$($LFS getstripe -g $file1)
18720         gen2=$($LFS getstripe -g $file2)
18721
18722         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18723         gen=$($LFS getstripe -g $file1)
18724         [[ $gen1 != $gen ]] ||
18725                 error "Layout generation on $file1 does not change"
18726         gen=$($LFS getstripe -g $file2)
18727         [[ $gen2 != $gen ]] ||
18728                 error "Layout generation on $file2 does not change"
18729
18730         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18731         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18732
18733         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18734 }
18735 run_test 184a "Basic layout swap"
18736
18737 test_184b() {
18738         check_swap_layouts_support
18739
18740         dir0=$DIR/$tdir/$testnum
18741         mkdir -p $dir0 || error "creating dir $dir0"
18742         file1=$dir0/f1
18743         file2=$dir0/f2
18744         file3=$dir0/f3
18745         dir1=$dir0/d1
18746         dir2=$dir0/d2
18747         mkdir $dir1 $dir2
18748         $LFS setstripe -c1 $file1
18749         $LFS setstripe -c2 $file2
18750         $LFS setstripe -c1 $file3
18751         chown $RUNAS_ID $file3
18752         gen1=$($LFS getstripe -g $file1)
18753         gen2=$($LFS getstripe -g $file2)
18754
18755         $LFS swap_layouts $dir1 $dir2 &&
18756                 error "swap of directories layouts should fail"
18757         $LFS swap_layouts $dir1 $file1 &&
18758                 error "swap of directory and file layouts should fail"
18759         $RUNAS $LFS swap_layouts $file1 $file2 &&
18760                 error "swap of file we cannot write should fail"
18761         $LFS swap_layouts $file1 $file3 &&
18762                 error "swap of file with different owner should fail"
18763         /bin/true # to clear error code
18764 }
18765 run_test 184b "Forbidden layout swap (will generate errors)"
18766
18767 test_184c() {
18768         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18769         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18770         check_swap_layouts_support
18771         check_swap_layout_no_dom $DIR
18772
18773         local dir0=$DIR/$tdir/$testnum
18774         mkdir -p $dir0 || error "creating dir $dir0"
18775
18776         local ref1=$dir0/ref1
18777         local ref2=$dir0/ref2
18778         local file1=$dir0/file1
18779         local file2=$dir0/file2
18780         # create a file large enough for the concurrent test
18781         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18782         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18783         echo "ref file size: ref1($(stat -c %s $ref1))," \
18784              "ref2($(stat -c %s $ref2))"
18785
18786         cp $ref2 $file2
18787         dd if=$ref1 of=$file1 bs=16k &
18788         local DD_PID=$!
18789
18790         # Make sure dd starts to copy file, but wait at most 5 seconds
18791         local loops=0
18792         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18793
18794         $LFS swap_layouts $file1 $file2
18795         local rc=$?
18796         wait $DD_PID
18797         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18798         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18799
18800         # how many bytes copied before swapping layout
18801         local copied=$(stat -c %s $file2)
18802         local remaining=$(stat -c %s $ref1)
18803         remaining=$((remaining - copied))
18804         echo "Copied $copied bytes before swapping layout..."
18805
18806         cmp -n $copied $file1 $ref2 | grep differ &&
18807                 error "Content mismatch [0, $copied) of ref2 and file1"
18808         cmp -n $copied $file2 $ref1 ||
18809                 error "Content mismatch [0, $copied) of ref1 and file2"
18810         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18811                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18812
18813         # clean up
18814         rm -f $ref1 $ref2 $file1 $file2
18815 }
18816 run_test 184c "Concurrent write and layout swap"
18817
18818 test_184d() {
18819         check_swap_layouts_support
18820         check_swap_layout_no_dom $DIR
18821         [ -z "$(which getfattr 2>/dev/null)" ] &&
18822                 skip_env "no getfattr command"
18823
18824         local file1=$DIR/$tdir/$tfile-1
18825         local file2=$DIR/$tdir/$tfile-2
18826         local file3=$DIR/$tdir/$tfile-3
18827         local lovea1
18828         local lovea2
18829
18830         mkdir -p $DIR/$tdir
18831         touch $file1 || error "create $file1 failed"
18832         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18833                 error "create $file2 failed"
18834         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18835                 error "create $file3 failed"
18836         lovea1=$(get_layout_param $file1)
18837
18838         $LFS swap_layouts $file2 $file3 ||
18839                 error "swap $file2 $file3 layouts failed"
18840         $LFS swap_layouts $file1 $file2 ||
18841                 error "swap $file1 $file2 layouts failed"
18842
18843         lovea2=$(get_layout_param $file2)
18844         echo "$lovea1"
18845         echo "$lovea2"
18846         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18847
18848         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18849         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18850 }
18851 run_test 184d "allow stripeless layouts swap"
18852
18853 test_184e() {
18854         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18855                 skip "Need MDS version at least 2.6.94"
18856         check_swap_layouts_support
18857         check_swap_layout_no_dom $DIR
18858         [ -z "$(which getfattr 2>/dev/null)" ] &&
18859                 skip_env "no getfattr command"
18860
18861         local file1=$DIR/$tdir/$tfile-1
18862         local file2=$DIR/$tdir/$tfile-2
18863         local file3=$DIR/$tdir/$tfile-3
18864         local lovea
18865
18866         mkdir -p $DIR/$tdir
18867         touch $file1 || error "create $file1 failed"
18868         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18869                 error "create $file2 failed"
18870         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18871                 error "create $file3 failed"
18872
18873         $LFS swap_layouts $file1 $file2 ||
18874                 error "swap $file1 $file2 layouts failed"
18875
18876         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18877         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18878
18879         echo 123 > $file1 || error "Should be able to write into $file1"
18880
18881         $LFS swap_layouts $file1 $file3 ||
18882                 error "swap $file1 $file3 layouts failed"
18883
18884         echo 123 > $file1 || error "Should be able to write into $file1"
18885
18886         rm -rf $file1 $file2 $file3
18887 }
18888 run_test 184e "Recreate layout after stripeless layout swaps"
18889
18890 test_184f() {
18891         # Create a file with name longer than sizeof(struct stat) ==
18892         # 144 to see if we can get chars from the file name to appear
18893         # in the returned striping. Note that 'f' == 0x66.
18894         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18895
18896         mkdir -p $DIR/$tdir
18897         mcreate $DIR/$tdir/$file
18898         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18899                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18900         fi
18901 }
18902 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18903
18904 test_185() { # LU-2441
18905         # LU-3553 - no volatile file support in old servers
18906         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18907                 skip "Need MDS version at least 2.3.60"
18908
18909         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18910         touch $DIR/$tdir/spoo
18911         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18912         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18913                 error "cannot create/write a volatile file"
18914         [ "$FILESET" == "" ] &&
18915         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18916                 error "FID is still valid after close"
18917
18918         multiop_bg_pause $DIR/$tdir vVw4096_c
18919         local multi_pid=$!
18920
18921         local OLD_IFS=$IFS
18922         IFS=":"
18923         local fidv=($fid)
18924         IFS=$OLD_IFS
18925         # assume that the next FID for this client is sequential, since stdout
18926         # is unfortunately eaten by multiop_bg_pause
18927         local n=$((${fidv[1]} + 1))
18928         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18929         if [ "$FILESET" == "" ]; then
18930                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18931                         error "FID is missing before close"
18932         fi
18933         kill -USR1 $multi_pid
18934         # 1 second delay, so if mtime change we will see it
18935         sleep 1
18936         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18937         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18938 }
18939 run_test 185 "Volatile file support"
18940
18941 function create_check_volatile() {
18942         local idx=$1
18943         local tgt
18944
18945         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18946         local PID=$!
18947         sleep 1
18948         local FID=$(cat /tmp/${tfile}.fid)
18949         [ "$FID" == "" ] && error "can't get FID for volatile"
18950         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18951         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18952         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18953         kill -USR1 $PID
18954         wait
18955         sleep 1
18956         cancel_lru_locks mdc # flush opencache
18957         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18958         return 0
18959 }
18960
18961 test_185a(){
18962         # LU-12516 - volatile creation via .lustre
18963         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18964                 skip "Need MDS version at least 2.3.55"
18965
18966         create_check_volatile 0
18967         [ $MDSCOUNT -lt 2 ] && return 0
18968
18969         # DNE case
18970         create_check_volatile 1
18971
18972         return 0
18973 }
18974 run_test 185a "Volatile file creation in .lustre/fid/"
18975
18976 test_187a() {
18977         remote_mds_nodsh && skip "remote MDS with nodsh"
18978         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18979                 skip "Need MDS version at least 2.3.0"
18980
18981         local dir0=$DIR/$tdir/$testnum
18982         mkdir -p $dir0 || error "creating dir $dir0"
18983
18984         local file=$dir0/file1
18985         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18986         local dv1=$($LFS data_version $file)
18987         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18988         local dv2=$($LFS data_version $file)
18989         [[ $dv1 != $dv2 ]] ||
18990                 error "data version did not change on write $dv1 == $dv2"
18991
18992         # clean up
18993         rm -f $file1
18994 }
18995 run_test 187a "Test data version change"
18996
18997 test_187b() {
18998         remote_mds_nodsh && skip "remote MDS with nodsh"
18999         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19000                 skip "Need MDS version at least 2.3.0"
19001
19002         local dir0=$DIR/$tdir/$testnum
19003         mkdir -p $dir0 || error "creating dir $dir0"
19004
19005         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19006         [[ ${DV[0]} != ${DV[1]} ]] ||
19007                 error "data version did not change on write"\
19008                       " ${DV[0]} == ${DV[1]}"
19009
19010         # clean up
19011         rm -f $file1
19012 }
19013 run_test 187b "Test data version change on volatile file"
19014
19015 test_200() {
19016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19017         remote_mgs_nodsh && skip "remote MGS with nodsh"
19018         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19019
19020         local POOL=${POOL:-cea1}
19021         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19022         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19023         # Pool OST targets
19024         local first_ost=0
19025         local last_ost=$(($OSTCOUNT - 1))
19026         local ost_step=2
19027         local ost_list=$(seq $first_ost $ost_step $last_ost)
19028         local ost_range="$first_ost $last_ost $ost_step"
19029         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19030         local file_dir=$POOL_ROOT/file_tst
19031         local subdir=$test_path/subdir
19032         local rc=0
19033
19034         while : ; do
19035                 # former test_200a test_200b
19036                 pool_add $POOL                          || { rc=$? ; break; }
19037                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19038                 # former test_200c test_200d
19039                 mkdir -p $test_path
19040                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19041                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19042                 mkdir -p $subdir
19043                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19044                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19045                                                         || { rc=$? ; break; }
19046                 # former test_200e test_200f
19047                 local files=$((OSTCOUNT*3))
19048                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19049                                                         || { rc=$? ; break; }
19050                 pool_create_files $POOL $file_dir $files "$ost_list" \
19051                                                         || { rc=$? ; break; }
19052                 # former test_200g test_200h
19053                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19054                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19055
19056                 # former test_201a test_201b test_201c
19057                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19058
19059                 local f=$test_path/$tfile
19060                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19061                 pool_remove $POOL $f                    || { rc=$? ; break; }
19062                 break
19063         done
19064
19065         destroy_test_pools
19066
19067         return $rc
19068 }
19069 run_test 200 "OST pools"
19070
19071 # usage: default_attr <count | size | offset>
19072 default_attr() {
19073         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19074 }
19075
19076 # usage: check_default_stripe_attr
19077 check_default_stripe_attr() {
19078         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19079         case $1 in
19080         --stripe-count|-c)
19081                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19082         --stripe-size|-S)
19083                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19084         --stripe-index|-i)
19085                 EXPECTED=-1;;
19086         *)
19087                 error "unknown getstripe attr '$1'"
19088         esac
19089
19090         [ $ACTUAL == $EXPECTED ] ||
19091                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19092 }
19093
19094 test_204a() {
19095         test_mkdir $DIR/$tdir
19096         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19097
19098         check_default_stripe_attr --stripe-count
19099         check_default_stripe_attr --stripe-size
19100         check_default_stripe_attr --stripe-index
19101 }
19102 run_test 204a "Print default stripe attributes"
19103
19104 test_204b() {
19105         test_mkdir $DIR/$tdir
19106         $LFS setstripe --stripe-count 1 $DIR/$tdir
19107
19108         check_default_stripe_attr --stripe-size
19109         check_default_stripe_attr --stripe-index
19110 }
19111 run_test 204b "Print default stripe size and offset"
19112
19113 test_204c() {
19114         test_mkdir $DIR/$tdir
19115         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19116
19117         check_default_stripe_attr --stripe-count
19118         check_default_stripe_attr --stripe-index
19119 }
19120 run_test 204c "Print default stripe count and offset"
19121
19122 test_204d() {
19123         test_mkdir $DIR/$tdir
19124         $LFS setstripe --stripe-index 0 $DIR/$tdir
19125
19126         check_default_stripe_attr --stripe-count
19127         check_default_stripe_attr --stripe-size
19128 }
19129 run_test 204d "Print default stripe count and size"
19130
19131 test_204e() {
19132         test_mkdir $DIR/$tdir
19133         $LFS setstripe -d $DIR/$tdir
19134
19135         check_default_stripe_attr --stripe-count --raw
19136         check_default_stripe_attr --stripe-size --raw
19137         check_default_stripe_attr --stripe-index --raw
19138 }
19139 run_test 204e "Print raw stripe attributes"
19140
19141 test_204f() {
19142         test_mkdir $DIR/$tdir
19143         $LFS setstripe --stripe-count 1 $DIR/$tdir
19144
19145         check_default_stripe_attr --stripe-size --raw
19146         check_default_stripe_attr --stripe-index --raw
19147 }
19148 run_test 204f "Print raw stripe size and offset"
19149
19150 test_204g() {
19151         test_mkdir $DIR/$tdir
19152         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19153
19154         check_default_stripe_attr --stripe-count --raw
19155         check_default_stripe_attr --stripe-index --raw
19156 }
19157 run_test 204g "Print raw stripe count and offset"
19158
19159 test_204h() {
19160         test_mkdir $DIR/$tdir
19161         $LFS setstripe --stripe-index 0 $DIR/$tdir
19162
19163         check_default_stripe_attr --stripe-count --raw
19164         check_default_stripe_attr --stripe-size --raw
19165 }
19166 run_test 204h "Print raw stripe count and size"
19167
19168 # Figure out which job scheduler is being used, if any,
19169 # or use a fake one
19170 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19171         JOBENV=SLURM_JOB_ID
19172 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19173         JOBENV=LSB_JOBID
19174 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19175         JOBENV=PBS_JOBID
19176 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19177         JOBENV=LOADL_STEP_ID
19178 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19179         JOBENV=JOB_ID
19180 else
19181         $LCTL list_param jobid_name > /dev/null 2>&1
19182         if [ $? -eq 0 ]; then
19183                 JOBENV=nodelocal
19184         else
19185                 JOBENV=FAKE_JOBID
19186         fi
19187 fi
19188 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19189
19190 verify_jobstats() {
19191         local cmd=($1)
19192         shift
19193         local facets="$@"
19194
19195 # we don't really need to clear the stats for this test to work, since each
19196 # command has a unique jobid, but it makes debugging easier if needed.
19197 #       for facet in $facets; do
19198 #               local dev=$(convert_facet2label $facet)
19199 #               # clear old jobstats
19200 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19201 #       done
19202
19203         # use a new JobID for each test, or we might see an old one
19204         [ "$JOBENV" = "FAKE_JOBID" ] &&
19205                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19206
19207         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19208
19209         [ "$JOBENV" = "nodelocal" ] && {
19210                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19211                 $LCTL set_param jobid_name=$FAKE_JOBID
19212                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19213         }
19214
19215         log "Test: ${cmd[*]}"
19216         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19217
19218         if [ $JOBENV = "FAKE_JOBID" ]; then
19219                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19220         else
19221                 ${cmd[*]}
19222         fi
19223
19224         # all files are created on OST0000
19225         for facet in $facets; do
19226                 local stats="*.$(convert_facet2label $facet).job_stats"
19227
19228                 # strip out libtool wrappers for in-tree executables
19229                 if (( $(do_facet $facet lctl get_param $stats |
19230                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19231                         do_facet $facet lctl get_param $stats
19232                         error "No jobstats for $JOBVAL found on $facet::$stats"
19233                 fi
19234         done
19235 }
19236
19237 jobstats_set() {
19238         local new_jobenv=$1
19239
19240         set_persistent_param_and_check client "jobid_var" \
19241                 "$FSNAME.sys.jobid_var" $new_jobenv
19242 }
19243
19244 test_205a() { # Job stats
19245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19246         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19247                 skip "Need MDS version with at least 2.7.1"
19248         remote_mgs_nodsh && skip "remote MGS with nodsh"
19249         remote_mds_nodsh && skip "remote MDS with nodsh"
19250         remote_ost_nodsh && skip "remote OST with nodsh"
19251         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19252                 skip "Server doesn't support jobstats"
19253         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19254
19255         local old_jobenv=$($LCTL get_param -n jobid_var)
19256         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19257
19258         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19259                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19260         else
19261                 stack_trap "do_facet mgs $PERM_CMD \
19262                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19263         fi
19264         changelog_register
19265
19266         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19267                                 mdt.*.job_cleanup_interval | head -n 1)
19268         local new_interval=5
19269         do_facet $SINGLEMDS \
19270                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19271         stack_trap "do_facet $SINGLEMDS \
19272                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19273         local start=$SECONDS
19274
19275         local cmd
19276         # mkdir
19277         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19278         verify_jobstats "$cmd" "$SINGLEMDS"
19279         # rmdir
19280         cmd="rmdir $DIR/$tdir"
19281         verify_jobstats "$cmd" "$SINGLEMDS"
19282         # mkdir on secondary MDT
19283         if [ $MDSCOUNT -gt 1 ]; then
19284                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19285                 verify_jobstats "$cmd" "mds2"
19286         fi
19287         # mknod
19288         cmd="mknod $DIR/$tfile c 1 3"
19289         verify_jobstats "$cmd" "$SINGLEMDS"
19290         # unlink
19291         cmd="rm -f $DIR/$tfile"
19292         verify_jobstats "$cmd" "$SINGLEMDS"
19293         # create all files on OST0000 so verify_jobstats can find OST stats
19294         # open & close
19295         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19296         verify_jobstats "$cmd" "$SINGLEMDS"
19297         # setattr
19298         cmd="touch $DIR/$tfile"
19299         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19300         # write
19301         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19302         verify_jobstats "$cmd" "ost1"
19303         # read
19304         cancel_lru_locks osc
19305         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19306         verify_jobstats "$cmd" "ost1"
19307         # truncate
19308         cmd="$TRUNCATE $DIR/$tfile 0"
19309         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19310         # rename
19311         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19312         verify_jobstats "$cmd" "$SINGLEMDS"
19313         # jobstats expiry - sleep until old stats should be expired
19314         local left=$((new_interval + 5 - (SECONDS - start)))
19315         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19316                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19317                         "0" $left
19318         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19319         verify_jobstats "$cmd" "$SINGLEMDS"
19320         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19321             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19322
19323         # Ensure that jobid are present in changelog (if supported by MDS)
19324         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19325                 changelog_dump | tail -10
19326                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19327                 [ $jobids -eq 9 ] ||
19328                         error "Wrong changelog jobid count $jobids != 9"
19329
19330                 # LU-5862
19331                 JOBENV="disable"
19332                 jobstats_set $JOBENV
19333                 touch $DIR/$tfile
19334                 changelog_dump | grep $tfile
19335                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19336                 [ $jobids -eq 0 ] ||
19337                         error "Unexpected jobids when jobid_var=$JOBENV"
19338         fi
19339
19340         # test '%j' access to environment variable - if supported
19341         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19342                 JOBENV="JOBCOMPLEX"
19343                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19344
19345                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19346         fi
19347
19348         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19349                 JOBENV="JOBCOMPLEX"
19350                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19351
19352                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19353         fi
19354
19355         # test '%j' access to per-session jobid - if supported
19356         if lctl list_param jobid_this_session > /dev/null 2>&1
19357         then
19358                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19359                 lctl set_param jobid_this_session=$USER
19360
19361                 JOBENV="JOBCOMPLEX"
19362                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19363
19364                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19365         fi
19366 }
19367 run_test 205a "Verify job stats"
19368
19369 # LU-13117, LU-13597
19370 test_205b() {
19371         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19372                 skip "Need MDS version at least 2.13.54.91"
19373
19374         local job_stats="mdt.*.job_stats"
19375         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19376
19377         do_facet mds1 $LCTL set_param $job_stats=clear
19378
19379         # Setting jobid_var to USER might not be supported
19380         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19381         $LCTL set_param jobid_var=USER || true
19382         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19383         $LCTL set_param jobid_name="%j.%e.%u"
19384
19385         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19386         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19387                 { do_facet mds1 $LCTL get_param $job_stats;
19388                   error "Unexpected jobid found"; }
19389         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19390                 { do_facet mds1 $LCTL get_param $job_stats;
19391                   error "wrong job_stats format found"; }
19392
19393         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19394                 echo "MDS does not yet escape jobid" && return 0
19395         $LCTL set_param jobid_var=TEST205b
19396         env -i TEST205b="has sp" touch $DIR/$tfile.2
19397         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19398                 { do_facet mds1 $LCTL get_param $job_stats;
19399                   error "jobid not escaped"; }
19400 }
19401 run_test 205b "Verify job stats jobid and output format"
19402
19403 # LU-13733
19404 test_205c() {
19405         $LCTL set_param llite.*.stats=0
19406         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19407         $LCTL get_param llite.*.stats
19408         $LCTL get_param llite.*.stats | grep \
19409                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19410                         error "wrong client stats format found"
19411 }
19412 run_test 205c "Verify client stats format"
19413
19414 test_205d() {
19415         local file=$DIR/$tdir/$tfile
19416
19417         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19418                 skip "need lustre >= 2.15.53 for lljobstat"
19419         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19420                 skip "need lustre >= 2.15.53 for lljobstat"
19421         verify_yaml_available || skip_env "YAML verification not installed"
19422
19423         test_mkdir -i 0 $DIR/$tdir
19424         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19425
19426         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19427                 error "failed to write data to $file"
19428         mv $file $file.2
19429
19430         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19431         echo -n 'verify rename_stats...'
19432         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19433                 verify_yaml || error "rename_stats is not valid YAML"
19434         echo " OK"
19435
19436         echo -n 'verify mdt job_stats...'
19437         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19438                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19439         echo " OK"
19440
19441         echo -n 'verify ost job_stats...'
19442         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19443                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19444         echo " OK"
19445 }
19446 run_test 205d "verify the format of some stats files"
19447
19448 test_205e() {
19449         local ops_comma
19450         local file=$DIR/$tdir/$tfile
19451
19452         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19453                 skip "need lustre >= 2.15.53 for lljobstat"
19454         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19455                 skip "need lustre >= 2.15.53 for lljobstat"
19456         verify_yaml_available || skip_env "YAML verification not installed"
19457
19458         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19459
19460         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19461                 error "failed to create $file on ost1"
19462         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19463                 error "failed to write data to $file"
19464
19465         do_facet mds1 "$LCTL get_param *.*.job_stats"
19466         do_facet ost1 "$LCTL get_param *.*.job_stats"
19467
19468         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19469         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19470                 error "The output of lljobstat is not an valid YAML"
19471
19472         # verify that job dd.0 does exist and has some ops on ost1
19473         # typically this line is like:
19474         # - dd.0:            {ops: 20, ...}
19475         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19476                     awk '$2=="dd.0:" {print $4}')
19477
19478         (( ${ops_comma%,} >= 10 )) ||
19479                 error "cannot find job dd.0 with ops >= 10"
19480 }
19481 run_test 205e "verify the output of lljobstat"
19482
19483 # LU-1480, LU-1773 and LU-1657
19484 test_206() {
19485         mkdir -p $DIR/$tdir
19486         $LFS setstripe -c -1 $DIR/$tdir
19487 #define OBD_FAIL_LOV_INIT 0x1403
19488         $LCTL set_param fail_loc=0xa0001403
19489         $LCTL set_param fail_val=1
19490         touch $DIR/$tdir/$tfile || true
19491 }
19492 run_test 206 "fail lov_init_raid0() doesn't lbug"
19493
19494 test_207a() {
19495         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19496         local fsz=`stat -c %s $DIR/$tfile`
19497         cancel_lru_locks mdc
19498
19499         # do not return layout in getattr intent
19500 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19501         $LCTL set_param fail_loc=0x170
19502         local sz=`stat -c %s $DIR/$tfile`
19503
19504         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19505
19506         rm -rf $DIR/$tfile
19507 }
19508 run_test 207a "can refresh layout at glimpse"
19509
19510 test_207b() {
19511         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19512         local cksum=`md5sum $DIR/$tfile`
19513         local fsz=`stat -c %s $DIR/$tfile`
19514         cancel_lru_locks mdc
19515         cancel_lru_locks osc
19516
19517         # do not return layout in getattr intent
19518 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19519         $LCTL set_param fail_loc=0x171
19520
19521         # it will refresh layout after the file is opened but before read issues
19522         echo checksum is "$cksum"
19523         echo "$cksum" |md5sum -c --quiet || error "file differs"
19524
19525         rm -rf $DIR/$tfile
19526 }
19527 run_test 207b "can refresh layout at open"
19528
19529 test_208() {
19530         # FIXME: in this test suite, only RD lease is used. This is okay
19531         # for now as only exclusive open is supported. After generic lease
19532         # is done, this test suite should be revised. - Jinshan
19533
19534         remote_mds_nodsh && skip "remote MDS with nodsh"
19535         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19536                 skip "Need MDS version at least 2.4.52"
19537
19538         echo "==== test 1: verify get lease work"
19539         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19540
19541         echo "==== test 2: verify lease can be broken by upcoming open"
19542         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19543         local PID=$!
19544         sleep 2
19545
19546         $MULTIOP $DIR/$tfile oO_RDWR:c
19547         kill -USR1 $PID && wait $PID || error "break lease error"
19548
19549         echo "==== test 3: verify lease can't be granted if an open already exists"
19550         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19551         local PID=$!
19552         sleep 2
19553
19554         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19555         kill -USR1 $PID && wait $PID || error "open file error"
19556
19557         echo "==== test 4: lease can sustain over recovery"
19558         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19559         PID=$!
19560         sleep 2
19561
19562         fail mds1
19563
19564         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19565
19566         echo "==== test 5: lease broken can't be regained by replay"
19567         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19568         PID=$!
19569         sleep 2
19570
19571         # open file to break lease and then recovery
19572         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19573         fail mds1
19574
19575         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19576
19577         rm -f $DIR/$tfile
19578 }
19579 run_test 208 "Exclusive open"
19580
19581 test_209() {
19582         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19583                 skip_env "must have disp_stripe"
19584
19585         touch $DIR/$tfile
19586         sync; sleep 5; sync;
19587
19588         echo 3 > /proc/sys/vm/drop_caches
19589         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19590                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19591         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19592
19593         # open/close 500 times
19594         for i in $(seq 500); do
19595                 cat $DIR/$tfile
19596         done
19597
19598         echo 3 > /proc/sys/vm/drop_caches
19599         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19600                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19601         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19602
19603         echo "before: $req_before, after: $req_after"
19604         [ $((req_after - req_before)) -ge 300 ] &&
19605                 error "open/close requests are not freed"
19606         return 0
19607 }
19608 run_test 209 "read-only open/close requests should be freed promptly"
19609
19610 test_210() {
19611         local pid
19612
19613         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19614         pid=$!
19615         sleep 1
19616
19617         $LFS getstripe $DIR/$tfile
19618         kill -USR1 $pid
19619         wait $pid || error "multiop failed"
19620
19621         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19622         pid=$!
19623         sleep 1
19624
19625         $LFS getstripe $DIR/$tfile
19626         kill -USR1 $pid
19627         wait $pid || error "multiop failed"
19628 }
19629 run_test 210 "lfs getstripe does not break leases"
19630
19631 test_212() {
19632         size=`date +%s`
19633         size=$((size % 8192 + 1))
19634         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19635         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19636         rm -f $DIR/f212 $DIR/f212.xyz
19637 }
19638 run_test 212 "Sendfile test ============================================"
19639
19640 test_213() {
19641         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19642         cancel_lru_locks osc
19643         lctl set_param fail_loc=0x8000040f
19644         # generate a read lock
19645         cat $DIR/$tfile > /dev/null
19646         # write to the file, it will try to cancel the above read lock.
19647         cat /etc/hosts >> $DIR/$tfile
19648 }
19649 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19650
19651 test_214() { # for bug 20133
19652         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19653         for (( i=0; i < 340; i++ )) ; do
19654                 touch $DIR/$tdir/d214c/a$i
19655         done
19656
19657         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19658         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19659         ls $DIR/d214c || error "ls $DIR/d214c failed"
19660         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19661         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19662 }
19663 run_test 214 "hash-indexed directory test - bug 20133"
19664
19665 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19666 create_lnet_proc_files() {
19667         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19668 }
19669
19670 # counterpart of create_lnet_proc_files
19671 remove_lnet_proc_files() {
19672         rm -f $TMP/lnet_$1.sys
19673 }
19674
19675 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19676 # 3rd arg as regexp for body
19677 check_lnet_proc_stats() {
19678         local l=$(cat "$TMP/lnet_$1" |wc -l)
19679         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19680
19681         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19682 }
19683
19684 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19685 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19686 # optional and can be regexp for 2nd line (lnet.routes case)
19687 check_lnet_proc_entry() {
19688         local blp=2          # blp stands for 'position of 1st line of body'
19689         [ -z "$5" ] || blp=3 # lnet.routes case
19690
19691         local l=$(cat "$TMP/lnet_$1" |wc -l)
19692         # subtracting one from $blp because the body can be empty
19693         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19694
19695         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19696                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19697
19698         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19699                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19700
19701         # bail out if any unexpected line happened
19702         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19703         [ "$?" != 0 ] || error "$2 misformatted"
19704 }
19705
19706 test_215() { # for bugs 18102, 21079, 21517
19707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19708
19709         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19710         local P='[1-9][0-9]*'           # positive numeric
19711         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19712         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19713         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19714         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19715
19716         local L1 # regexp for 1st line
19717         local L2 # regexp for 2nd line (optional)
19718         local BR # regexp for the rest (body)
19719
19720         # lnet.stats should look as 11 space-separated non-negative numerics
19721         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19722         create_lnet_proc_files "stats"
19723         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19724         remove_lnet_proc_files "stats"
19725
19726         # lnet.routes should look like this:
19727         # Routing disabled/enabled
19728         # net hops priority state router
19729         # where net is a string like tcp0, hops > 0, priority >= 0,
19730         # state is up/down,
19731         # router is a string like 192.168.1.1@tcp2
19732         L1="^Routing (disabled|enabled)$"
19733         L2="^net +hops +priority +state +router$"
19734         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19735         create_lnet_proc_files "routes"
19736         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19737         remove_lnet_proc_files "routes"
19738
19739         # lnet.routers should look like this:
19740         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19741         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19742         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19743         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19744         L1="^ref +rtr_ref +alive +router$"
19745         BR="^$P +$P +(up|down) +$NID$"
19746         create_lnet_proc_files "routers"
19747         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19748         remove_lnet_proc_files "routers"
19749
19750         # lnet.peers should look like this:
19751         # nid refs state last max rtr min tx min queue
19752         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19753         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19754         # numeric (0 or >0 or <0), queue >= 0.
19755         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19756         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19757         create_lnet_proc_files "peers"
19758         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19759         remove_lnet_proc_files "peers"
19760
19761         # lnet.buffers  should look like this:
19762         # pages count credits min
19763         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19764         L1="^pages +count +credits +min$"
19765         BR="^ +$N +$N +$I +$I$"
19766         create_lnet_proc_files "buffers"
19767         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19768         remove_lnet_proc_files "buffers"
19769
19770         # lnet.nis should look like this:
19771         # nid status alive refs peer rtr max tx min
19772         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19773         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19774         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19775         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19776         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19777         create_lnet_proc_files "nis"
19778         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19779         remove_lnet_proc_files "nis"
19780
19781         # can we successfully write to lnet.stats?
19782         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19783 }
19784 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19785
19786 test_216() { # bug 20317
19787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19788         remote_ost_nodsh && skip "remote OST with nodsh"
19789
19790         local node
19791         local facets=$(get_facets OST)
19792         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19793
19794         save_lustre_params client "osc.*.contention_seconds" > $p
19795         save_lustre_params $facets \
19796                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19797         save_lustre_params $facets \
19798                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19799         save_lustre_params $facets \
19800                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19801         clear_stats osc.*.osc_stats
19802
19803         # agressive lockless i/o settings
19804         do_nodes $(comma_list $(osts_nodes)) \
19805                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19806                         ldlm.namespaces.filter-*.contended_locks=0 \
19807                         ldlm.namespaces.filter-*.contention_seconds=60"
19808         lctl set_param -n osc.*.contention_seconds=60
19809
19810         $DIRECTIO write $DIR/$tfile 0 10 4096
19811         $CHECKSTAT -s 40960 $DIR/$tfile
19812
19813         # disable lockless i/o
19814         do_nodes $(comma_list $(osts_nodes)) \
19815                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19816                         ldlm.namespaces.filter-*.contended_locks=32 \
19817                         ldlm.namespaces.filter-*.contention_seconds=0"
19818         lctl set_param -n osc.*.contention_seconds=0
19819         clear_stats osc.*.osc_stats
19820
19821         dd if=/dev/zero of=$DIR/$tfile count=0
19822         $CHECKSTAT -s 0 $DIR/$tfile
19823
19824         restore_lustre_params <$p
19825         rm -f $p
19826         rm $DIR/$tfile
19827 }
19828 run_test 216 "check lockless direct write updates file size and kms correctly"
19829
19830 test_217() { # bug 22430
19831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19832
19833         local node
19834         local nid
19835
19836         for node in $(nodes_list); do
19837                 nid=$(host_nids_address $node $NETTYPE)
19838                 if [[ $nid = *-* ]] ; then
19839                         echo "lctl ping $(h2nettype $nid)"
19840                         lctl ping $(h2nettype $nid)
19841                 else
19842                         echo "skipping $node (no hyphen detected)"
19843                 fi
19844         done
19845 }
19846 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19847
19848 test_218() {
19849        # do directio so as not to populate the page cache
19850        log "creating a 10 Mb file"
19851        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19852        log "starting reads"
19853        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19854        log "truncating the file"
19855        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19856        log "killing dd"
19857        kill %+ || true # reads might have finished
19858        echo "wait until dd is finished"
19859        wait
19860        log "removing the temporary file"
19861        rm -rf $DIR/$tfile || error "tmp file removal failed"
19862 }
19863 run_test 218 "parallel read and truncate should not deadlock"
19864
19865 test_219() {
19866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19867
19868         # write one partial page
19869         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19870         # set no grant so vvp_io_commit_write will do sync write
19871         $LCTL set_param fail_loc=0x411
19872         # write a full page at the end of file
19873         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19874
19875         $LCTL set_param fail_loc=0
19876         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19877         $LCTL set_param fail_loc=0x411
19878         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19879
19880         # LU-4201
19881         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19882         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19883 }
19884 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19885
19886 test_220() { #LU-325
19887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19888         remote_ost_nodsh && skip "remote OST with nodsh"
19889         remote_mds_nodsh && skip "remote MDS with nodsh"
19890         remote_mgs_nodsh && skip "remote MGS with nodsh"
19891
19892         local OSTIDX=0
19893
19894         # create on MDT0000 so the last_id and next_id are correct
19895         mkdir_on_mdt0 $DIR/$tdir
19896         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19897         OST=${OST%_UUID}
19898
19899         # on the mdt's osc
19900         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19901         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19902                         osp.$mdtosc_proc1.prealloc_last_id)
19903         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19904                         osp.$mdtosc_proc1.prealloc_next_id)
19905
19906         $LFS df -i
19907
19908         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19909         #define OBD_FAIL_OST_ENOINO              0x229
19910         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19911         create_pool $FSNAME.$TESTNAME || return 1
19912         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19913
19914         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19915
19916         MDSOBJS=$((last_id - next_id))
19917         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19918
19919         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19920         echo "OST still has $count kbytes free"
19921
19922         echo "create $MDSOBJS files @next_id..."
19923         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19924
19925         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19926                         osp.$mdtosc_proc1.prealloc_last_id)
19927         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19928                         osp.$mdtosc_proc1.prealloc_next_id)
19929
19930         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19931         $LFS df -i
19932
19933         echo "cleanup..."
19934
19935         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19936         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19937
19938         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19939                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19940         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19941                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19942         echo "unlink $MDSOBJS files @$next_id..."
19943         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19944 }
19945 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19946
19947 test_221() {
19948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19949
19950         dd if=`which date` of=$MOUNT/date oflag=sync
19951         chmod +x $MOUNT/date
19952
19953         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19954         $LCTL set_param fail_loc=0x80001401
19955
19956         $MOUNT/date > /dev/null
19957         rm -f $MOUNT/date
19958 }
19959 run_test 221 "make sure fault and truncate race to not cause OOM"
19960
19961 test_222a () {
19962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19963
19964         rm -rf $DIR/$tdir
19965         test_mkdir $DIR/$tdir
19966         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19967         createmany -o $DIR/$tdir/$tfile 10
19968         cancel_lru_locks mdc
19969         cancel_lru_locks osc
19970         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19971         $LCTL set_param fail_loc=0x31a
19972         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19973         $LCTL set_param fail_loc=0
19974         rm -r $DIR/$tdir
19975 }
19976 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19977
19978 test_222b () {
19979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19980
19981         rm -rf $DIR/$tdir
19982         test_mkdir $DIR/$tdir
19983         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19984         createmany -o $DIR/$tdir/$tfile 10
19985         cancel_lru_locks mdc
19986         cancel_lru_locks osc
19987         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19988         $LCTL set_param fail_loc=0x31a
19989         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19990         $LCTL set_param fail_loc=0
19991 }
19992 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19993
19994 test_223 () {
19995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19996
19997         rm -rf $DIR/$tdir
19998         test_mkdir $DIR/$tdir
19999         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20000         createmany -o $DIR/$tdir/$tfile 10
20001         cancel_lru_locks mdc
20002         cancel_lru_locks osc
20003         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20004         $LCTL set_param fail_loc=0x31b
20005         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20006         $LCTL set_param fail_loc=0
20007         rm -r $DIR/$tdir
20008 }
20009 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20010
20011 test_224a() { # LU-1039, MRP-303
20012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20013         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20014         $LCTL set_param fail_loc=0x508
20015         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20016         $LCTL set_param fail_loc=0
20017         df $DIR
20018 }
20019 run_test 224a "Don't panic on bulk IO failure"
20020
20021 test_224bd_sub() { # LU-1039, MRP-303
20022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20023         local timeout=$1
20024
20025         shift
20026         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20027
20028         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20029
20030         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20031         cancel_lru_locks osc
20032         set_checksums 0
20033         stack_trap "set_checksums $ORIG_CSUM" EXIT
20034         local at_max_saved=0
20035
20036         # adaptive timeouts may prevent seeing the issue
20037         if at_is_enabled; then
20038                 at_max_saved=$(at_max_get mds)
20039                 at_max_set 0 mds client
20040                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20041         fi
20042
20043         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20044         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20045         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20046
20047         do_facet ost1 $LCTL set_param fail_loc=0
20048         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20049         df $DIR
20050 }
20051
20052 test_224b() {
20053         test_224bd_sub 3 error "dd failed"
20054 }
20055 run_test 224b "Don't panic on bulk IO failure"
20056
20057 test_224c() { # LU-6441
20058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20059         remote_mds_nodsh && skip "remote MDS with nodsh"
20060
20061         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20062         save_writethrough $p
20063         set_cache writethrough on
20064
20065         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20066         local at_max=$($LCTL get_param -n at_max)
20067         local timeout=$($LCTL get_param -n timeout)
20068         local test_at="at_max"
20069         local param_at="$FSNAME.sys.at_max"
20070         local test_timeout="timeout"
20071         local param_timeout="$FSNAME.sys.timeout"
20072
20073         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20074
20075         set_persistent_param_and_check client "$test_at" "$param_at" 0
20076         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20077
20078         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20079         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20080         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20081         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20082         sync
20083         do_facet ost1 "$LCTL set_param fail_loc=0"
20084
20085         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20086         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20087                 $timeout
20088
20089         $LCTL set_param -n $pages_per_rpc
20090         restore_lustre_params < $p
20091         rm -f $p
20092 }
20093 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20094
20095 test_224d() { # LU-11169
20096         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20097 }
20098 run_test 224d "Don't corrupt data on bulk IO timeout"
20099
20100 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20101 test_225a () {
20102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20103         if [ -z ${MDSSURVEY} ]; then
20104                 skip_env "mds-survey not found"
20105         fi
20106         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20107                 skip "Need MDS version at least 2.2.51"
20108
20109         local mds=$(facet_host $SINGLEMDS)
20110         local target=$(do_nodes $mds 'lctl dl' |
20111                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20112
20113         local cmd1="file_count=1000 thrhi=4"
20114         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20115         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20116         local cmd="$cmd1 $cmd2 $cmd3"
20117
20118         rm -f ${TMP}/mds_survey*
20119         echo + $cmd
20120         eval $cmd || error "mds-survey with zero-stripe failed"
20121         cat ${TMP}/mds_survey*
20122         rm -f ${TMP}/mds_survey*
20123 }
20124 run_test 225a "Metadata survey sanity with zero-stripe"
20125
20126 test_225b () {
20127         if [ -z ${MDSSURVEY} ]; then
20128                 skip_env "mds-survey not found"
20129         fi
20130         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20131                 skip "Need MDS version at least 2.2.51"
20132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20133         remote_mds_nodsh && skip "remote MDS with nodsh"
20134         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20135                 skip_env "Need to mount OST to test"
20136         fi
20137
20138         local mds=$(facet_host $SINGLEMDS)
20139         local target=$(do_nodes $mds 'lctl dl' |
20140                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20141
20142         local cmd1="file_count=1000 thrhi=4"
20143         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20144         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20145         local cmd="$cmd1 $cmd2 $cmd3"
20146
20147         rm -f ${TMP}/mds_survey*
20148         echo + $cmd
20149         eval $cmd || error "mds-survey with stripe_count failed"
20150         cat ${TMP}/mds_survey*
20151         rm -f ${TMP}/mds_survey*
20152 }
20153 run_test 225b "Metadata survey sanity with stripe_count = 1"
20154
20155 mcreate_path2fid () {
20156         local mode=$1
20157         local major=$2
20158         local minor=$3
20159         local name=$4
20160         local desc=$5
20161         local path=$DIR/$tdir/$name
20162         local fid
20163         local rc
20164         local fid_path
20165
20166         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20167                 error "cannot create $desc"
20168
20169         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20170         rc=$?
20171         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20172
20173         fid_path=$($LFS fid2path $MOUNT $fid)
20174         rc=$?
20175         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20176
20177         [ "$path" == "$fid_path" ] ||
20178                 error "fid2path returned $fid_path, expected $path"
20179
20180         echo "pass with $path and $fid"
20181 }
20182
20183 test_226a () {
20184         rm -rf $DIR/$tdir
20185         mkdir -p $DIR/$tdir
20186
20187         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20188         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20189         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20190         mcreate_path2fid 0040666 0 0 dir "directory"
20191         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20192         mcreate_path2fid 0100666 0 0 file "regular file"
20193         mcreate_path2fid 0120666 0 0 link "symbolic link"
20194         mcreate_path2fid 0140666 0 0 sock "socket"
20195 }
20196 run_test 226a "call path2fid and fid2path on files of all type"
20197
20198 test_226b () {
20199         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20200
20201         local MDTIDX=1
20202
20203         rm -rf $DIR/$tdir
20204         mkdir -p $DIR/$tdir
20205         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20206                 error "create remote directory failed"
20207         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20208         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20209                                 "character special file (null)"
20210         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20211                                 "character special file (no device)"
20212         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20213         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20214                                 "block special file (loop)"
20215         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20216         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20217         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20218 }
20219 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20220
20221 test_226c () {
20222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20223         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20224                 skip "Need MDS version at least 2.13.55"
20225
20226         local submnt=/mnt/submnt
20227         local srcfile=/etc/passwd
20228         local dstfile=$submnt/passwd
20229         local path
20230         local fid
20231
20232         rm -rf $DIR/$tdir
20233         rm -rf $submnt
20234         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20235                 error "create remote directory failed"
20236         mkdir -p $submnt || error "create $submnt failed"
20237         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20238                 error "mount $submnt failed"
20239         stack_trap "umount $submnt" EXIT
20240
20241         cp $srcfile $dstfile
20242         fid=$($LFS path2fid $dstfile)
20243         path=$($LFS fid2path $submnt "$fid")
20244         [ "$path" = "$dstfile" ] ||
20245                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20246 }
20247 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20248
20249 # LU-1299 Executing or running ldd on a truncated executable does not
20250 # cause an out-of-memory condition.
20251 test_227() {
20252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20253         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20254
20255         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20256         chmod +x $MOUNT/date
20257
20258         $MOUNT/date > /dev/null
20259         ldd $MOUNT/date > /dev/null
20260         rm -f $MOUNT/date
20261 }
20262 run_test 227 "running truncated executable does not cause OOM"
20263
20264 # LU-1512 try to reuse idle OI blocks
20265 test_228a() {
20266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20267         remote_mds_nodsh && skip "remote MDS with nodsh"
20268         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20269
20270         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20271         local myDIR=$DIR/$tdir
20272
20273         mkdir -p $myDIR
20274         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20275         $LCTL set_param fail_loc=0x80001002
20276         createmany -o $myDIR/t- 10000
20277         $LCTL set_param fail_loc=0
20278         # The guard is current the largest FID holder
20279         touch $myDIR/guard
20280         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20281                     tr -d '[')
20282         local IDX=$(($SEQ % 64))
20283
20284         do_facet $SINGLEMDS sync
20285         # Make sure journal flushed.
20286         sleep 6
20287         local blk1=$(do_facet $SINGLEMDS \
20288                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20289                      grep Blockcount | awk '{print $4}')
20290
20291         # Remove old files, some OI blocks will become idle.
20292         unlinkmany $myDIR/t- 10000
20293         # Create new files, idle OI blocks should be reused.
20294         createmany -o $myDIR/t- 2000
20295         do_facet $SINGLEMDS sync
20296         # Make sure journal flushed.
20297         sleep 6
20298         local blk2=$(do_facet $SINGLEMDS \
20299                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20300                      grep Blockcount | awk '{print $4}')
20301
20302         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20303 }
20304 run_test 228a "try to reuse idle OI blocks"
20305
20306 test_228b() {
20307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20308         remote_mds_nodsh && skip "remote MDS with nodsh"
20309         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20310
20311         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20312         local myDIR=$DIR/$tdir
20313
20314         mkdir -p $myDIR
20315         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20316         $LCTL set_param fail_loc=0x80001002
20317         createmany -o $myDIR/t- 10000
20318         $LCTL set_param fail_loc=0
20319         # The guard is current the largest FID holder
20320         touch $myDIR/guard
20321         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20322                     tr -d '[')
20323         local IDX=$(($SEQ % 64))
20324
20325         do_facet $SINGLEMDS sync
20326         # Make sure journal flushed.
20327         sleep 6
20328         local blk1=$(do_facet $SINGLEMDS \
20329                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20330                      grep Blockcount | awk '{print $4}')
20331
20332         # Remove old files, some OI blocks will become idle.
20333         unlinkmany $myDIR/t- 10000
20334
20335         # stop the MDT
20336         stop $SINGLEMDS || error "Fail to stop MDT."
20337         # remount the MDT
20338         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20339                 error "Fail to start MDT."
20340
20341         client_up || error "Fail to df."
20342         # Create new files, idle OI blocks should be reused.
20343         createmany -o $myDIR/t- 2000
20344         do_facet $SINGLEMDS sync
20345         # Make sure journal flushed.
20346         sleep 6
20347         local blk2=$(do_facet $SINGLEMDS \
20348                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20349                      grep Blockcount | awk '{print $4}')
20350
20351         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20352 }
20353 run_test 228b "idle OI blocks can be reused after MDT restart"
20354
20355 #LU-1881
20356 test_228c() {
20357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20358         remote_mds_nodsh && skip "remote MDS with nodsh"
20359         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20360
20361         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20362         local myDIR=$DIR/$tdir
20363
20364         mkdir -p $myDIR
20365         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20366         $LCTL set_param fail_loc=0x80001002
20367         # 20000 files can guarantee there are index nodes in the OI file
20368         createmany -o $myDIR/t- 20000
20369         $LCTL set_param fail_loc=0
20370         # The guard is current the largest FID holder
20371         touch $myDIR/guard
20372         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20373                     tr -d '[')
20374         local IDX=$(($SEQ % 64))
20375
20376         do_facet $SINGLEMDS sync
20377         # Make sure journal flushed.
20378         sleep 6
20379         local blk1=$(do_facet $SINGLEMDS \
20380                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20381                      grep Blockcount | awk '{print $4}')
20382
20383         # Remove old files, some OI blocks will become idle.
20384         unlinkmany $myDIR/t- 20000
20385         rm -f $myDIR/guard
20386         # The OI file should become empty now
20387
20388         # Create new files, idle OI blocks should be reused.
20389         createmany -o $myDIR/t- 2000
20390         do_facet $SINGLEMDS sync
20391         # Make sure journal flushed.
20392         sleep 6
20393         local blk2=$(do_facet $SINGLEMDS \
20394                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20395                      grep Blockcount | awk '{print $4}')
20396
20397         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20398 }
20399 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20400
20401 test_229() { # LU-2482, LU-3448
20402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20403         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20404         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20405                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20406
20407         rm -f $DIR/$tfile
20408
20409         # Create a file with a released layout and stripe count 2.
20410         $MULTIOP $DIR/$tfile H2c ||
20411                 error "failed to create file with released layout"
20412
20413         $LFS getstripe -v $DIR/$tfile
20414
20415         local pattern=$($LFS getstripe -L $DIR/$tfile)
20416         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20417
20418         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20419                 error "getstripe"
20420         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20421         stat $DIR/$tfile || error "failed to stat released file"
20422
20423         chown $RUNAS_ID $DIR/$tfile ||
20424                 error "chown $RUNAS_ID $DIR/$tfile failed"
20425
20426         chgrp $RUNAS_ID $DIR/$tfile ||
20427                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20428
20429         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20430         rm $DIR/$tfile || error "failed to remove released file"
20431 }
20432 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20433
20434 test_230a() {
20435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20437         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20438                 skip "Need MDS version at least 2.11.52"
20439
20440         local MDTIDX=1
20441
20442         test_mkdir $DIR/$tdir
20443         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20444         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20445         [ $mdt_idx -ne 0 ] &&
20446                 error "create local directory on wrong MDT $mdt_idx"
20447
20448         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20449                         error "create remote directory failed"
20450         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20451         [ $mdt_idx -ne $MDTIDX ] &&
20452                 error "create remote directory on wrong MDT $mdt_idx"
20453
20454         createmany -o $DIR/$tdir/test_230/t- 10 ||
20455                 error "create files on remote directory failed"
20456         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20457         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20458         rm -r $DIR/$tdir || error "unlink remote directory failed"
20459 }
20460 run_test 230a "Create remote directory and files under the remote directory"
20461
20462 test_230b() {
20463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20465         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20466                 skip "Need MDS version at least 2.11.52"
20467
20468         local MDTIDX=1
20469         local mdt_index
20470         local i
20471         local file
20472         local pid
20473         local stripe_count
20474         local migrate_dir=$DIR/$tdir/migrate_dir
20475         local other_dir=$DIR/$tdir/other_dir
20476
20477         test_mkdir $DIR/$tdir
20478         test_mkdir -i0 -c1 $migrate_dir
20479         test_mkdir -i0 -c1 $other_dir
20480         for ((i=0; i<10; i++)); do
20481                 mkdir -p $migrate_dir/dir_${i}
20482                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20483                         error "create files under remote dir failed $i"
20484         done
20485
20486         cp /etc/passwd $migrate_dir/$tfile
20487         cp /etc/passwd $other_dir/$tfile
20488         chattr +SAD $migrate_dir
20489         chattr +SAD $migrate_dir/$tfile
20490
20491         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20492         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20493         local old_dir_mode=$(stat -c%f $migrate_dir)
20494         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20495
20496         mkdir -p $migrate_dir/dir_default_stripe2
20497         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20498         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20499
20500         mkdir -p $other_dir
20501         ln $migrate_dir/$tfile $other_dir/luna
20502         ln $migrate_dir/$tfile $migrate_dir/sofia
20503         ln $other_dir/$tfile $migrate_dir/david
20504         ln -s $migrate_dir/$tfile $other_dir/zachary
20505         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20506         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20507
20508         local len
20509         local lnktgt
20510
20511         # inline symlink
20512         for len in 58 59 60; do
20513                 lnktgt=$(str_repeat 'l' $len)
20514                 touch $migrate_dir/$lnktgt
20515                 ln -s $lnktgt $migrate_dir/${len}char_ln
20516         done
20517
20518         # PATH_MAX
20519         for len in 4094 4095; do
20520                 lnktgt=$(str_repeat 'l' $len)
20521                 ln -s $lnktgt $migrate_dir/${len}char_ln
20522         done
20523
20524         # NAME_MAX
20525         for len in 254 255; do
20526                 touch $migrate_dir/$(str_repeat 'l' $len)
20527         done
20528
20529         $LFS migrate -m $MDTIDX $migrate_dir ||
20530                 error "fails on migrating remote dir to MDT1"
20531
20532         echo "migratate to MDT1, then checking.."
20533         for ((i = 0; i < 10; i++)); do
20534                 for file in $(find $migrate_dir/dir_${i}); do
20535                         mdt_index=$($LFS getstripe -m $file)
20536                         # broken symlink getstripe will fail
20537                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20538                                 error "$file is not on MDT${MDTIDX}"
20539                 done
20540         done
20541
20542         # the multiple link file should still in MDT0
20543         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20544         [ $mdt_index == 0 ] ||
20545                 error "$file is not on MDT${MDTIDX}"
20546
20547         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20548         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20549                 error " expect $old_dir_flag get $new_dir_flag"
20550
20551         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20552         [ "$old_file_flag" = "$new_file_flag" ] ||
20553                 error " expect $old_file_flag get $new_file_flag"
20554
20555         local new_dir_mode=$(stat -c%f $migrate_dir)
20556         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20557                 error "expect mode $old_dir_mode get $new_dir_mode"
20558
20559         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20560         [ "$old_file_mode" = "$new_file_mode" ] ||
20561                 error "expect mode $old_file_mode get $new_file_mode"
20562
20563         diff /etc/passwd $migrate_dir/$tfile ||
20564                 error "$tfile different after migration"
20565
20566         diff /etc/passwd $other_dir/luna ||
20567                 error "luna different after migration"
20568
20569         diff /etc/passwd $migrate_dir/sofia ||
20570                 error "sofia different after migration"
20571
20572         diff /etc/passwd $migrate_dir/david ||
20573                 error "david different after migration"
20574
20575         diff /etc/passwd $other_dir/zachary ||
20576                 error "zachary different after migration"
20577
20578         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20579                 error "${tfile}_ln different after migration"
20580
20581         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20582                 error "${tfile}_ln_other different after migration"
20583
20584         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20585         [ $stripe_count = 2 ] ||
20586                 error "dir strpe_count $d != 2 after migration."
20587
20588         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20589         [ $stripe_count = 2 ] ||
20590                 error "file strpe_count $d != 2 after migration."
20591
20592         #migrate back to MDT0
20593         MDTIDX=0
20594
20595         $LFS migrate -m $MDTIDX $migrate_dir ||
20596                 error "fails on migrating remote dir to MDT0"
20597
20598         echo "migrate back to MDT0, checking.."
20599         for file in $(find $migrate_dir); do
20600                 mdt_index=$($LFS getstripe -m $file)
20601                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20602                         error "$file is not on MDT${MDTIDX}"
20603         done
20604
20605         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20606         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20607                 error " expect $old_dir_flag get $new_dir_flag"
20608
20609         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20610         [ "$old_file_flag" = "$new_file_flag" ] ||
20611                 error " expect $old_file_flag get $new_file_flag"
20612
20613         local new_dir_mode=$(stat -c%f $migrate_dir)
20614         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20615                 error "expect mode $old_dir_mode get $new_dir_mode"
20616
20617         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20618         [ "$old_file_mode" = "$new_file_mode" ] ||
20619                 error "expect mode $old_file_mode get $new_file_mode"
20620
20621         diff /etc/passwd ${migrate_dir}/$tfile ||
20622                 error "$tfile different after migration"
20623
20624         diff /etc/passwd ${other_dir}/luna ||
20625                 error "luna different after migration"
20626
20627         diff /etc/passwd ${migrate_dir}/sofia ||
20628                 error "sofia different after migration"
20629
20630         diff /etc/passwd ${other_dir}/zachary ||
20631                 error "zachary different after migration"
20632
20633         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20634                 error "${tfile}_ln different after migration"
20635
20636         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20637                 error "${tfile}_ln_other different after migration"
20638
20639         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20640         [ $stripe_count = 2 ] ||
20641                 error "dir strpe_count $d != 2 after migration."
20642
20643         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20644         [ $stripe_count = 2 ] ||
20645                 error "file strpe_count $d != 2 after migration."
20646
20647         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20648 }
20649 run_test 230b "migrate directory"
20650
20651 test_230c() {
20652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20654         remote_mds_nodsh && skip "remote MDS with nodsh"
20655         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20656                 skip "Need MDS version at least 2.11.52"
20657
20658         local MDTIDX=1
20659         local total=3
20660         local mdt_index
20661         local file
20662         local migrate_dir=$DIR/$tdir/migrate_dir
20663
20664         #If migrating directory fails in the middle, all entries of
20665         #the directory is still accessiable.
20666         test_mkdir $DIR/$tdir
20667         test_mkdir -i0 -c1 $migrate_dir
20668         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20669         stat $migrate_dir
20670         createmany -o $migrate_dir/f $total ||
20671                 error "create files under ${migrate_dir} failed"
20672
20673         # fail after migrating top dir, and this will fail only once, so the
20674         # first sub file migration will fail (currently f3), others succeed.
20675         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20676         do_facet mds1 lctl set_param fail_loc=0x1801
20677         local t=$(ls $migrate_dir | wc -l)
20678         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20679                 error "migrate should fail"
20680         local u=$(ls $migrate_dir | wc -l)
20681         [ "$u" == "$t" ] || error "$u != $t during migration"
20682
20683         # add new dir/file should succeed
20684         mkdir $migrate_dir/dir ||
20685                 error "mkdir failed under migrating directory"
20686         touch $migrate_dir/file ||
20687                 error "create file failed under migrating directory"
20688
20689         # add file with existing name should fail
20690         for file in $migrate_dir/f*; do
20691                 stat $file > /dev/null || error "stat $file failed"
20692                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20693                         error "open(O_CREAT|O_EXCL) $file should fail"
20694                 $MULTIOP $file m && error "create $file should fail"
20695                 touch $DIR/$tdir/remote_dir/$tfile ||
20696                         error "touch $tfile failed"
20697                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20698                         error "link $file should fail"
20699                 mdt_index=$($LFS getstripe -m $file)
20700                 if [ $mdt_index == 0 ]; then
20701                         # file failed to migrate is not allowed to rename to
20702                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20703                                 error "rename to $file should fail"
20704                 else
20705                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20706                                 error "rename to $file failed"
20707                 fi
20708                 echo hello >> $file || error "write $file failed"
20709         done
20710
20711         # resume migration with different options should fail
20712         $LFS migrate -m 0 $migrate_dir &&
20713                 error "migrate -m 0 $migrate_dir should fail"
20714
20715         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20716                 error "migrate -c 2 $migrate_dir should fail"
20717
20718         # resume migration should succeed
20719         $LFS migrate -m $MDTIDX $migrate_dir ||
20720                 error "migrate $migrate_dir failed"
20721
20722         echo "Finish migration, then checking.."
20723         for file in $(find $migrate_dir); do
20724                 mdt_index=$($LFS getstripe -m $file)
20725                 [ $mdt_index == $MDTIDX ] ||
20726                         error "$file is not on MDT${MDTIDX}"
20727         done
20728
20729         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20730 }
20731 run_test 230c "check directory accessiblity if migration failed"
20732
20733 test_230d() {
20734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20736         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20737                 skip "Need MDS version at least 2.11.52"
20738         # LU-11235
20739         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20740
20741         local migrate_dir=$DIR/$tdir/migrate_dir
20742         local old_index
20743         local new_index
20744         local old_count
20745         local new_count
20746         local new_hash
20747         local mdt_index
20748         local i
20749         local j
20750
20751         old_index=$((RANDOM % MDSCOUNT))
20752         old_count=$((MDSCOUNT - old_index))
20753         new_index=$((RANDOM % MDSCOUNT))
20754         new_count=$((MDSCOUNT - new_index))
20755         new_hash=1 # for all_char
20756
20757         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20758         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20759
20760         test_mkdir $DIR/$tdir
20761         test_mkdir -i $old_index -c $old_count $migrate_dir
20762
20763         for ((i=0; i<100; i++)); do
20764                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20765                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20766                         error "create files under remote dir failed $i"
20767         done
20768
20769         echo -n "Migrate from MDT$old_index "
20770         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20771         echo -n "to MDT$new_index"
20772         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20773         echo
20774
20775         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20776         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20777                 error "migrate remote dir error"
20778
20779         echo "Finish migration, then checking.."
20780         for file in $(find $migrate_dir -maxdepth 1); do
20781                 mdt_index=$($LFS getstripe -m $file)
20782                 if [ $mdt_index -lt $new_index ] ||
20783                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20784                         error "$file is on MDT$mdt_index"
20785                 fi
20786         done
20787
20788         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20789 }
20790 run_test 230d "check migrate big directory"
20791
20792 test_230e() {
20793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20795         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20796                 skip "Need MDS version at least 2.11.52"
20797
20798         local i
20799         local j
20800         local a_fid
20801         local b_fid
20802
20803         mkdir_on_mdt0 $DIR/$tdir
20804         mkdir $DIR/$tdir/migrate_dir
20805         mkdir $DIR/$tdir/other_dir
20806         touch $DIR/$tdir/migrate_dir/a
20807         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20808         ls $DIR/$tdir/other_dir
20809
20810         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20811                 error "migrate dir fails"
20812
20813         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20814         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20815
20816         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20817         [ $mdt_index == 0 ] || error "a is not on MDT0"
20818
20819         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20820                 error "migrate dir fails"
20821
20822         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20823         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20824
20825         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20826         [ $mdt_index == 1 ] || error "a is not on MDT1"
20827
20828         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20829         [ $mdt_index == 1 ] || error "b is not on MDT1"
20830
20831         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20832         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20833
20834         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20835
20836         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20837 }
20838 run_test 230e "migrate mulitple local link files"
20839
20840 test_230f() {
20841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20843         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20844                 skip "Need MDS version at least 2.11.52"
20845
20846         local a_fid
20847         local ln_fid
20848
20849         mkdir -p $DIR/$tdir
20850         mkdir $DIR/$tdir/migrate_dir
20851         $LFS mkdir -i1 $DIR/$tdir/other_dir
20852         touch $DIR/$tdir/migrate_dir/a
20853         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20854         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20855         ls $DIR/$tdir/other_dir
20856
20857         # a should be migrated to MDT1, since no other links on MDT0
20858         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20859                 error "#1 migrate dir fails"
20860         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20861         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20862         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20863         [ $mdt_index == 1 ] || error "a is not on MDT1"
20864
20865         # a should stay on MDT1, because it is a mulitple link file
20866         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20867                 error "#2 migrate dir fails"
20868         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20869         [ $mdt_index == 1 ] || error "a is not on MDT1"
20870
20871         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20872                 error "#3 migrate dir fails"
20873
20874         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20875         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20876         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20877
20878         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20879         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20880
20881         # a should be migrated to MDT0, since no other links on MDT1
20882         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20883                 error "#4 migrate dir fails"
20884         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20885         [ $mdt_index == 0 ] || error "a is not on MDT0"
20886
20887         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20888 }
20889 run_test 230f "migrate mulitple remote link files"
20890
20891 test_230g() {
20892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20895                 skip "Need MDS version at least 2.11.52"
20896
20897         mkdir -p $DIR/$tdir/migrate_dir
20898
20899         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20900                 error "migrating dir to non-exist MDT succeeds"
20901         true
20902 }
20903 run_test 230g "migrate dir to non-exist MDT"
20904
20905 test_230h() {
20906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20908         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20909                 skip "Need MDS version at least 2.11.52"
20910
20911         local mdt_index
20912
20913         mkdir -p $DIR/$tdir/migrate_dir
20914
20915         $LFS migrate -m1 $DIR &&
20916                 error "migrating mountpoint1 should fail"
20917
20918         $LFS migrate -m1 $DIR/$tdir/.. &&
20919                 error "migrating mountpoint2 should fail"
20920
20921         # same as mv
20922         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20923                 error "migrating $tdir/migrate_dir/.. should fail"
20924
20925         true
20926 }
20927 run_test 230h "migrate .. and root"
20928
20929 test_230i() {
20930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20932         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20933                 skip "Need MDS version at least 2.11.52"
20934
20935         mkdir -p $DIR/$tdir/migrate_dir
20936
20937         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20938                 error "migration fails with a tailing slash"
20939
20940         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20941                 error "migration fails with two tailing slashes"
20942 }
20943 run_test 230i "lfs migrate -m tolerates trailing slashes"
20944
20945 test_230j() {
20946         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20947         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20948                 skip "Need MDS version at least 2.11.52"
20949
20950         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20951         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20952                 error "create $tfile failed"
20953         cat /etc/passwd > $DIR/$tdir/$tfile
20954
20955         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20956
20957         cmp /etc/passwd $DIR/$tdir/$tfile ||
20958                 error "DoM file mismatch after migration"
20959 }
20960 run_test 230j "DoM file data not changed after dir migration"
20961
20962 test_230k() {
20963         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20964         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20965                 skip "Need MDS version at least 2.11.56"
20966
20967         local total=20
20968         local files_on_starting_mdt=0
20969
20970         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20971         $LFS getdirstripe $DIR/$tdir
20972         for i in $(seq $total); do
20973                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20974                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20975                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20976         done
20977
20978         echo "$files_on_starting_mdt files on MDT0"
20979
20980         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20981         $LFS getdirstripe $DIR/$tdir
20982
20983         files_on_starting_mdt=0
20984         for i in $(seq $total); do
20985                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20986                         error "file $tfile.$i mismatch after migration"
20987                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20988                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20989         done
20990
20991         echo "$files_on_starting_mdt files on MDT1 after migration"
20992         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20993
20994         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20995         $LFS getdirstripe $DIR/$tdir
20996
20997         files_on_starting_mdt=0
20998         for i in $(seq $total); do
20999                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21000                         error "file $tfile.$i mismatch after 2nd migration"
21001                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21002                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21003         done
21004
21005         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21006         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21007
21008         true
21009 }
21010 run_test 230k "file data not changed after dir migration"
21011
21012 test_230l() {
21013         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21014         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21015                 skip "Need MDS version at least 2.11.56"
21016
21017         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21018         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21019                 error "create files under remote dir failed $i"
21020         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21021 }
21022 run_test 230l "readdir between MDTs won't crash"
21023
21024 test_230m() {
21025         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21026         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21027                 skip "Need MDS version at least 2.11.56"
21028
21029         local MDTIDX=1
21030         local mig_dir=$DIR/$tdir/migrate_dir
21031         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21032         local shortstr="b"
21033         local val
21034
21035         echo "Creating files and dirs with xattrs"
21036         test_mkdir $DIR/$tdir
21037         test_mkdir -i0 -c1 $mig_dir
21038         mkdir $mig_dir/dir
21039         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21040                 error "cannot set xattr attr1 on dir"
21041         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21042                 error "cannot set xattr attr2 on dir"
21043         touch $mig_dir/dir/f0
21044         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21045                 error "cannot set xattr attr1 on file"
21046         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21047                 error "cannot set xattr attr2 on file"
21048         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21049         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21050         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21051         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21052         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21053         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21054         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21055         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21056         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21057
21058         echo "Migrating to MDT1"
21059         $LFS migrate -m $MDTIDX $mig_dir ||
21060                 error "fails on migrating dir to MDT1"
21061
21062         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21063         echo "Checking xattrs"
21064         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21065         [ "$val" = $longstr ] ||
21066                 error "expecting xattr1 $longstr on dir, found $val"
21067         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21068         [ "$val" = $shortstr ] ||
21069                 error "expecting xattr2 $shortstr on dir, found $val"
21070         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21071         [ "$val" = $longstr ] ||
21072                 error "expecting xattr1 $longstr on file, found $val"
21073         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21074         [ "$val" = $shortstr ] ||
21075                 error "expecting xattr2 $shortstr on file, found $val"
21076 }
21077 run_test 230m "xattrs not changed after dir migration"
21078
21079 test_230n() {
21080         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21081         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21082                 skip "Need MDS version at least 2.13.53"
21083
21084         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21085         cat /etc/hosts > $DIR/$tdir/$tfile
21086         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21087         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21088
21089         cmp /etc/hosts $DIR/$tdir/$tfile ||
21090                 error "File data mismatch after migration"
21091 }
21092 run_test 230n "Dir migration with mirrored file"
21093
21094 test_230o() {
21095         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21096         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21097                 skip "Need MDS version at least 2.13.52"
21098
21099         local mdts=$(comma_list $(mdts_nodes))
21100         local timeout=100
21101         local restripe_status
21102         local delta
21103         local i
21104
21105         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21106
21107         # in case "crush" hash type is not set
21108         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21109
21110         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21111                            mdt.*MDT0000.enable_dir_restripe)
21112         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21113         stack_trap "do_nodes $mdts $LCTL set_param \
21114                     mdt.*.enable_dir_restripe=$restripe_status"
21115
21116         mkdir $DIR/$tdir
21117         createmany -m $DIR/$tdir/f 100 ||
21118                 error "create files under remote dir failed $i"
21119         createmany -d $DIR/$tdir/d 100 ||
21120                 error "create dirs under remote dir failed $i"
21121
21122         for i in $(seq 2 $MDSCOUNT); do
21123                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21124                 $LFS setdirstripe -c $i $DIR/$tdir ||
21125                         error "split -c $i $tdir failed"
21126                 wait_update $HOSTNAME \
21127                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21128                         error "dir split not finished"
21129                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21130                         awk '/migrate/ {sum += $2} END { print sum }')
21131                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21132                 # delta is around total_files/stripe_count
21133                 (( $delta < 200 / (i - 1) + 4 )) ||
21134                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21135         done
21136 }
21137 run_test 230o "dir split"
21138
21139 test_230p() {
21140         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21141         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21142                 skip "Need MDS version at least 2.13.52"
21143
21144         local mdts=$(comma_list $(mdts_nodes))
21145         local timeout=100
21146         local restripe_status
21147         local delta
21148         local c
21149
21150         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21151
21152         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21153
21154         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21155                            mdt.*MDT0000.enable_dir_restripe)
21156         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21157         stack_trap "do_nodes $mdts $LCTL set_param \
21158                     mdt.*.enable_dir_restripe=$restripe_status"
21159
21160         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21161         createmany -m $DIR/$tdir/f 100 ||
21162                 error "create files under remote dir failed"
21163         createmany -d $DIR/$tdir/d 100 ||
21164                 error "create dirs under remote dir failed"
21165
21166         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21167                 local mdt_hash="crush"
21168
21169                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21170                 $LFS setdirstripe -c $c $DIR/$tdir ||
21171                         error "split -c $c $tdir failed"
21172                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21173                         mdt_hash="$mdt_hash,fixed"
21174                 elif [ $c -eq 1 ]; then
21175                         mdt_hash="none"
21176                 fi
21177                 wait_update $HOSTNAME \
21178                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21179                         error "dir merge not finished"
21180                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21181                         awk '/migrate/ {sum += $2} END { print sum }')
21182                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21183                 # delta is around total_files/stripe_count
21184                 (( delta < 200 / c + 4 )) ||
21185                         error "$delta files migrated >= $((200 / c + 4))"
21186         done
21187 }
21188 run_test 230p "dir merge"
21189
21190 test_230q() {
21191         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21192         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21193                 skip "Need MDS version at least 2.13.52"
21194
21195         local mdts=$(comma_list $(mdts_nodes))
21196         local saved_threshold=$(do_facet mds1 \
21197                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21198         local saved_delta=$(do_facet mds1 \
21199                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21200         local threshold=100
21201         local delta=2
21202         local total=0
21203         local stripe_count=0
21204         local stripe_index
21205         local nr_files
21206         local create
21207
21208         # test with fewer files on ZFS
21209         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21210
21211         stack_trap "do_nodes $mdts $LCTL set_param \
21212                     mdt.*.dir_split_count=$saved_threshold"
21213         stack_trap "do_nodes $mdts $LCTL set_param \
21214                     mdt.*.dir_split_delta=$saved_delta"
21215         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21216         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21217         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21218         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21219         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21220         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21221
21222         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21223         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21224
21225         create=$((threshold * 3 / 2))
21226         while [ $stripe_count -lt $MDSCOUNT ]; do
21227                 createmany -m $DIR/$tdir/f $total $create ||
21228                         error "create sub files failed"
21229                 stat $DIR/$tdir > /dev/null
21230                 total=$((total + create))
21231                 stripe_count=$((stripe_count + delta))
21232                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21233
21234                 wait_update $HOSTNAME \
21235                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21236                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21237
21238                 wait_update $HOSTNAME \
21239                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21240                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21241
21242                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21243                 echo "$nr_files/$total files on MDT$stripe_index after split"
21244                 # allow 10% margin of imbalance with crush hash
21245                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21246                         error "$nr_files files on MDT$stripe_index after split"
21247
21248                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21249                 [ $nr_files -eq $total ] ||
21250                         error "total sub files $nr_files != $total"
21251         done
21252
21253         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21254
21255         echo "fixed layout directory won't auto split"
21256         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21257         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21258                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21259         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21260                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21261 }
21262 run_test 230q "dir auto split"
21263
21264 test_230r() {
21265         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21266         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21267         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21268                 skip "Need MDS version at least 2.13.54"
21269
21270         # maximum amount of local locks:
21271         # parent striped dir - 2 locks
21272         # new stripe in parent to migrate to - 1 lock
21273         # source and target - 2 locks
21274         # Total 5 locks for regular file
21275         mkdir -p $DIR/$tdir
21276         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21277         touch $DIR/$tdir/dir1/eee
21278
21279         # create 4 hardlink for 4 more locks
21280         # Total: 9 locks > RS_MAX_LOCKS (8)
21281         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21282         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21283         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21284         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21285         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21286         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21287         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21288         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21289
21290         cancel_lru_locks mdc
21291
21292         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21293                 error "migrate dir fails"
21294
21295         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21296 }
21297 run_test 230r "migrate with too many local locks"
21298
21299 test_230s() {
21300         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21301                 skip "Need MDS version at least 2.14.52"
21302
21303         local mdts=$(comma_list $(mdts_nodes))
21304         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21305                                 mdt.*MDT0000.enable_dir_restripe)
21306
21307         stack_trap "do_nodes $mdts $LCTL set_param \
21308                     mdt.*.enable_dir_restripe=$restripe_status"
21309
21310         local st
21311         for st in 0 1; do
21312                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21313                 test_mkdir $DIR/$tdir
21314                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21315                         error "$LFS mkdir should return EEXIST if target exists"
21316                 rmdir $DIR/$tdir
21317         done
21318 }
21319 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21320
21321 test_230t()
21322 {
21323         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21324         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21325                 skip "Need MDS version at least 2.14.50"
21326
21327         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21328         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21329         $LFS project -p 1 -s $DIR/$tdir ||
21330                 error "set $tdir project id failed"
21331         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21332                 error "set subdir project id failed"
21333         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21334 }
21335 run_test 230t "migrate directory with project ID set"
21336
21337 test_230u()
21338 {
21339         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21340         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21341                 skip "Need MDS version at least 2.14.53"
21342
21343         local count
21344
21345         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21346         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21347         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21348         for i in $(seq 0 $((MDSCOUNT - 1))); do
21349                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21350                 echo "$count dirs migrated to MDT$i"
21351         done
21352         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21353         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21354 }
21355 run_test 230u "migrate directory by QOS"
21356
21357 test_230v()
21358 {
21359         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21360         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21361                 skip "Need MDS version at least 2.14.53"
21362
21363         local count
21364
21365         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21366         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21367         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21368         for i in $(seq 0 $((MDSCOUNT - 1))); do
21369                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21370                 echo "$count subdirs migrated to MDT$i"
21371                 (( i == 3 )) && (( count > 0 )) &&
21372                         error "subdir shouldn't be migrated to MDT3"
21373         done
21374         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21375         (( count == 3 )) || error "dirs migrated to $count MDTs"
21376 }
21377 run_test 230v "subdir migrated to the MDT where its parent is located"
21378
21379 test_230w() {
21380         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21381         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21382                 skip "Need MDS version at least 2.15.0"
21383
21384         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21385         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21386         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21387
21388         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21389                 error "migrate failed"
21390
21391         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21392                 error "$tdir stripe count mismatch"
21393
21394         for i in $(seq 0 9); do
21395                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21396                         error "d$i is striped"
21397         done
21398 }
21399 run_test 230w "non-recursive mode dir migration"
21400
21401 test_230x() {
21402         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21403         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21404                 skip "Need MDS version at least 2.15.0"
21405
21406         mkdir -p $DIR/$tdir || error "mkdir failed"
21407         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21408
21409         local mdt_name=$(mdtname_from_index 0)
21410         local low=$(do_facet mds2 $LCTL get_param -n \
21411                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21412         local high=$(do_facet mds2 $LCTL get_param -n \
21413                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21414         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21415         local maxage=$(do_facet mds2 $LCTL get_param -n \
21416                 osp.*$mdt_name-osp-MDT0001.maxage)
21417
21418         stack_trap "do_facet mds2 $LCTL set_param -n \
21419                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21420                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21421         stack_trap "do_facet mds2 $LCTL set_param -n \
21422                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21423
21424         do_facet mds2 $LCTL set_param -n \
21425                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21426         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21427         sleep 4
21428         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21429                 error "migrate $tdir should fail"
21430
21431         do_facet mds2 $LCTL set_param -n \
21432                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21433         do_facet mds2 $LCTL set_param -n \
21434                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21435         sleep 4
21436         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21437                 error "migrate failed"
21438         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21439                 error "$tdir stripe count mismatch"
21440 }
21441 run_test 230x "dir migration check space"
21442
21443 test_231a()
21444 {
21445         # For simplicity this test assumes that max_pages_per_rpc
21446         # is the same across all OSCs
21447         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21448         local bulk_size=$((max_pages * PAGE_SIZE))
21449         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21450                                        head -n 1)
21451
21452         mkdir -p $DIR/$tdir
21453         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21454                 error "failed to set stripe with -S ${brw_size}M option"
21455
21456         # clear the OSC stats
21457         $LCTL set_param osc.*.stats=0 &>/dev/null
21458         stop_writeback
21459
21460         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21461         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21462                 oflag=direct &>/dev/null || error "dd failed"
21463
21464         sync; sleep 1; sync # just to be safe
21465         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21466         if [ x$nrpcs != "x1" ]; then
21467                 $LCTL get_param osc.*.stats
21468                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21469         fi
21470
21471         start_writeback
21472         # Drop the OSC cache, otherwise we will read from it
21473         cancel_lru_locks osc
21474
21475         # clear the OSC stats
21476         $LCTL set_param osc.*.stats=0 &>/dev/null
21477
21478         # Client reads $bulk_size.
21479         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21480                 iflag=direct &>/dev/null || error "dd failed"
21481
21482         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21483         if [ x$nrpcs != "x1" ]; then
21484                 $LCTL get_param osc.*.stats
21485                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21486         fi
21487 }
21488 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21489
21490 test_231b() {
21491         mkdir -p $DIR/$tdir
21492         local i
21493         for i in {0..1023}; do
21494                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21495                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21496                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21497         done
21498         sync
21499 }
21500 run_test 231b "must not assert on fully utilized OST request buffer"
21501
21502 test_232a() {
21503         mkdir -p $DIR/$tdir
21504         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21505
21506         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21507         do_facet ost1 $LCTL set_param fail_loc=0x31c
21508
21509         # ignore dd failure
21510         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21511
21512         do_facet ost1 $LCTL set_param fail_loc=0
21513         umount_client $MOUNT || error "umount failed"
21514         mount_client $MOUNT || error "mount failed"
21515         stop ost1 || error "cannot stop ost1"
21516         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21517 }
21518 run_test 232a "failed lock should not block umount"
21519
21520 test_232b() {
21521         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21522                 skip "Need MDS version at least 2.10.58"
21523
21524         mkdir -p $DIR/$tdir
21525         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21526         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21527         sync
21528         cancel_lru_locks osc
21529
21530         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21531         do_facet ost1 $LCTL set_param fail_loc=0x31c
21532
21533         # ignore failure
21534         $LFS data_version $DIR/$tdir/$tfile || true
21535
21536         do_facet ost1 $LCTL set_param fail_loc=0
21537         umount_client $MOUNT || error "umount failed"
21538         mount_client $MOUNT || error "mount failed"
21539         stop ost1 || error "cannot stop ost1"
21540         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21541 }
21542 run_test 232b "failed data version lock should not block umount"
21543
21544 test_233a() {
21545         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21546                 skip "Need MDS version at least 2.3.64"
21547         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21548
21549         local fid=$($LFS path2fid $MOUNT)
21550
21551         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21552                 error "cannot access $MOUNT using its FID '$fid'"
21553 }
21554 run_test 233a "checking that OBF of the FS root succeeds"
21555
21556 test_233b() {
21557         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21558                 skip "Need MDS version at least 2.5.90"
21559         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21560
21561         local fid=$($LFS path2fid $MOUNT/.lustre)
21562
21563         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21564                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21565
21566         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21567         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21568                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21569 }
21570 run_test 233b "checking that OBF of the FS .lustre succeeds"
21571
21572 test_234() {
21573         local p="$TMP/sanityN-$TESTNAME.parameters"
21574         save_lustre_params client "llite.*.xattr_cache" > $p
21575         lctl set_param llite.*.xattr_cache 1 ||
21576                 skip_env "xattr cache is not supported"
21577
21578         mkdir -p $DIR/$tdir || error "mkdir failed"
21579         touch $DIR/$tdir/$tfile || error "touch failed"
21580         # OBD_FAIL_LLITE_XATTR_ENOMEM
21581         $LCTL set_param fail_loc=0x1405
21582         getfattr -n user.attr $DIR/$tdir/$tfile &&
21583                 error "getfattr should have failed with ENOMEM"
21584         $LCTL set_param fail_loc=0x0
21585         rm -rf $DIR/$tdir
21586
21587         restore_lustre_params < $p
21588         rm -f $p
21589 }
21590 run_test 234 "xattr cache should not crash on ENOMEM"
21591
21592 test_235() {
21593         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21594                 skip "Need MDS version at least 2.4.52"
21595
21596         flock_deadlock $DIR/$tfile
21597         local RC=$?
21598         case $RC in
21599                 0)
21600                 ;;
21601                 124) error "process hangs on a deadlock"
21602                 ;;
21603                 *) error "error executing flock_deadlock $DIR/$tfile"
21604                 ;;
21605         esac
21606 }
21607 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21608
21609 #LU-2935
21610 test_236() {
21611         check_swap_layouts_support
21612
21613         local ref1=/etc/passwd
21614         local ref2=/etc/group
21615         local file1=$DIR/$tdir/f1
21616         local file2=$DIR/$tdir/f2
21617
21618         test_mkdir -c1 $DIR/$tdir
21619         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21620         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21621         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21622         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21623         local fd=$(free_fd)
21624         local cmd="exec $fd<>$file2"
21625         eval $cmd
21626         rm $file2
21627         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21628                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21629         cmd="exec $fd>&-"
21630         eval $cmd
21631         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21632
21633         #cleanup
21634         rm -rf $DIR/$tdir
21635 }
21636 run_test 236 "Layout swap on open unlinked file"
21637
21638 # LU-4659 linkea consistency
21639 test_238() {
21640         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21641                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21642                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21643                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21644
21645         touch $DIR/$tfile
21646         ln $DIR/$tfile $DIR/$tfile.lnk
21647         touch $DIR/$tfile.new
21648         mv $DIR/$tfile.new $DIR/$tfile
21649         local fid1=$($LFS path2fid $DIR/$tfile)
21650         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21651         local path1=$($LFS fid2path $FSNAME "$fid1")
21652         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21653         local path2=$($LFS fid2path $FSNAME "$fid2")
21654         [ $tfile.lnk == $path2 ] ||
21655                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21656         rm -f $DIR/$tfile*
21657 }
21658 run_test 238 "Verify linkea consistency"
21659
21660 test_239A() { # was test_239
21661         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21662                 skip "Need MDS version at least 2.5.60"
21663
21664         local list=$(comma_list $(mdts_nodes))
21665
21666         mkdir -p $DIR/$tdir
21667         createmany -o $DIR/$tdir/f- 5000
21668         unlinkmany $DIR/$tdir/f- 5000
21669         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21670                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21671         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21672                         osp.*MDT*.sync_in_flight" | calc_sum)
21673         [ "$changes" -eq 0 ] || error "$changes not synced"
21674 }
21675 run_test 239A "osp_sync test"
21676
21677 test_239a() { #LU-5297
21678         remote_mds_nodsh && skip "remote MDS with nodsh"
21679
21680         touch $DIR/$tfile
21681         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21682         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21683         chgrp $RUNAS_GID $DIR/$tfile
21684         wait_delete_completed
21685 }
21686 run_test 239a "process invalid osp sync record correctly"
21687
21688 test_239b() { #LU-5297
21689         remote_mds_nodsh && skip "remote MDS with nodsh"
21690
21691         touch $DIR/$tfile1
21692         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21693         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21694         chgrp $RUNAS_GID $DIR/$tfile1
21695         wait_delete_completed
21696         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21697         touch $DIR/$tfile2
21698         chgrp $RUNAS_GID $DIR/$tfile2
21699         wait_delete_completed
21700 }
21701 run_test 239b "process osp sync record with ENOMEM error correctly"
21702
21703 test_240() {
21704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21705         remote_mds_nodsh && skip "remote MDS with nodsh"
21706
21707         mkdir -p $DIR/$tdir
21708
21709         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21710                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21711         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21712                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21713
21714         umount_client $MOUNT || error "umount failed"
21715         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21716         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21717         mount_client $MOUNT || error "failed to mount client"
21718
21719         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21720         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21721 }
21722 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21723
21724 test_241_bio() {
21725         local count=$1
21726         local bsize=$2
21727
21728         for LOOP in $(seq $count); do
21729                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21730                 cancel_lru_locks $OSC || true
21731         done
21732 }
21733
21734 test_241_dio() {
21735         local count=$1
21736         local bsize=$2
21737
21738         for LOOP in $(seq $1); do
21739                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21740                         2>/dev/null
21741         done
21742 }
21743
21744 test_241a() { # was test_241
21745         local bsize=$PAGE_SIZE
21746
21747         (( bsize < 40960 )) && bsize=40960
21748         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21749         ls -la $DIR/$tfile
21750         cancel_lru_locks $OSC
21751         test_241_bio 1000 $bsize &
21752         PID=$!
21753         test_241_dio 1000 $bsize
21754         wait $PID
21755 }
21756 run_test 241a "bio vs dio"
21757
21758 test_241b() {
21759         local bsize=$PAGE_SIZE
21760
21761         (( bsize < 40960 )) && bsize=40960
21762         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21763         ls -la $DIR/$tfile
21764         test_241_dio 1000 $bsize &
21765         PID=$!
21766         test_241_dio 1000 $bsize
21767         wait $PID
21768 }
21769 run_test 241b "dio vs dio"
21770
21771 test_242() {
21772         remote_mds_nodsh && skip "remote MDS with nodsh"
21773
21774         mkdir_on_mdt0 $DIR/$tdir
21775         touch $DIR/$tdir/$tfile
21776
21777         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21778         do_facet mds1 lctl set_param fail_loc=0x105
21779         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21780
21781         do_facet mds1 lctl set_param fail_loc=0
21782         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21783 }
21784 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21785
21786 test_243()
21787 {
21788         test_mkdir $DIR/$tdir
21789         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21790 }
21791 run_test 243 "various group lock tests"
21792
21793 test_244a()
21794 {
21795         test_mkdir $DIR/$tdir
21796         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21797         sendfile_grouplock $DIR/$tdir/$tfile || \
21798                 error "sendfile+grouplock failed"
21799         rm -rf $DIR/$tdir
21800 }
21801 run_test 244a "sendfile with group lock tests"
21802
21803 test_244b()
21804 {
21805         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21806
21807         local threads=50
21808         local size=$((1024*1024))
21809
21810         test_mkdir $DIR/$tdir
21811         for i in $(seq 1 $threads); do
21812                 local file=$DIR/$tdir/file_$((i / 10))
21813                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21814                 local pids[$i]=$!
21815         done
21816         for i in $(seq 1 $threads); do
21817                 wait ${pids[$i]}
21818         done
21819 }
21820 run_test 244b "multi-threaded write with group lock"
21821
21822 test_245a() {
21823         local flagname="multi_mod_rpcs"
21824         local connect_data_name="max_mod_rpcs"
21825         local out
21826
21827         # check if multiple modify RPCs flag is set
21828         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21829                 grep "connect_flags:")
21830         echo "$out"
21831
21832         echo "$out" | grep -qw $flagname
21833         if [ $? -ne 0 ]; then
21834                 echo "connect flag $flagname is not set"
21835                 return
21836         fi
21837
21838         # check if multiple modify RPCs data is set
21839         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21840         echo "$out"
21841
21842         echo "$out" | grep -qw $connect_data_name ||
21843                 error "import should have connect data $connect_data_name"
21844 }
21845 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21846
21847 test_245b() {
21848         local flagname="multi_mod_rpcs"
21849         local connect_data_name="max_mod_rpcs"
21850         local out
21851
21852         remote_mds_nodsh && skip "remote MDS with nodsh"
21853         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21854
21855         # check if multiple modify RPCs flag is set
21856         out=$(do_facet mds1 \
21857               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21858               grep "connect_flags:")
21859         echo "$out"
21860
21861         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21862
21863         # check if multiple modify RPCs data is set
21864         out=$(do_facet mds1 \
21865               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21866
21867         [[ "$out" =~ $connect_data_name ]] ||
21868                 {
21869                         echo "$out"
21870                         error "missing connect data $connect_data_name"
21871                 }
21872 }
21873 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21874
21875 cleanup_247() {
21876         local submount=$1
21877
21878         trap 0
21879         umount_client $submount
21880         rmdir $submount
21881 }
21882
21883 test_247a() {
21884         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21885                 grep -q subtree ||
21886                 skip_env "Fileset feature is not supported"
21887
21888         local submount=${MOUNT}_$tdir
21889
21890         mkdir $MOUNT/$tdir
21891         mkdir -p $submount || error "mkdir $submount failed"
21892         FILESET="$FILESET/$tdir" mount_client $submount ||
21893                 error "mount $submount failed"
21894         trap "cleanup_247 $submount" EXIT
21895         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21896         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21897                 error "read $MOUNT/$tdir/$tfile failed"
21898         cleanup_247 $submount
21899 }
21900 run_test 247a "mount subdir as fileset"
21901
21902 test_247b() {
21903         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21904                 skip_env "Fileset feature is not supported"
21905
21906         local submount=${MOUNT}_$tdir
21907
21908         rm -rf $MOUNT/$tdir
21909         mkdir -p $submount || error "mkdir $submount failed"
21910         SKIP_FILESET=1
21911         FILESET="$FILESET/$tdir" mount_client $submount &&
21912                 error "mount $submount should fail"
21913         rmdir $submount
21914 }
21915 run_test 247b "mount subdir that dose not exist"
21916
21917 test_247c() {
21918         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21919                 skip_env "Fileset feature is not supported"
21920
21921         local submount=${MOUNT}_$tdir
21922
21923         mkdir -p $MOUNT/$tdir/dir1
21924         mkdir -p $submount || error "mkdir $submount failed"
21925         trap "cleanup_247 $submount" EXIT
21926         FILESET="$FILESET/$tdir" mount_client $submount ||
21927                 error "mount $submount failed"
21928         local fid=$($LFS path2fid $MOUNT/)
21929         $LFS fid2path $submount $fid && error "fid2path should fail"
21930         cleanup_247 $submount
21931 }
21932 run_test 247c "running fid2path outside subdirectory root"
21933
21934 test_247d() {
21935         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21936                 skip "Fileset feature is not supported"
21937
21938         local submount=${MOUNT}_$tdir
21939
21940         mkdir -p $MOUNT/$tdir/dir1
21941         mkdir -p $submount || error "mkdir $submount failed"
21942         FILESET="$FILESET/$tdir" mount_client $submount ||
21943                 error "mount $submount failed"
21944         trap "cleanup_247 $submount" EXIT
21945
21946         local td=$submount/dir1
21947         local fid=$($LFS path2fid $td)
21948         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21949
21950         # check that we get the same pathname back
21951         local rootpath
21952         local found
21953         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21954                 echo "$rootpath $fid"
21955                 found=$($LFS fid2path $rootpath "$fid")
21956                 [ -n "$found" ] || error "fid2path should succeed"
21957                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21958         done
21959         # check wrong root path format
21960         rootpath=$submount"_wrong"
21961         found=$($LFS fid2path $rootpath "$fid")
21962         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21963
21964         cleanup_247 $submount
21965 }
21966 run_test 247d "running fid2path inside subdirectory root"
21967
21968 # LU-8037
21969 test_247e() {
21970         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21971                 grep -q subtree ||
21972                 skip "Fileset feature is not supported"
21973
21974         local submount=${MOUNT}_$tdir
21975
21976         mkdir $MOUNT/$tdir
21977         mkdir -p $submount || error "mkdir $submount failed"
21978         FILESET="$FILESET/.." mount_client $submount &&
21979                 error "mount $submount should fail"
21980         rmdir $submount
21981 }
21982 run_test 247e "mount .. as fileset"
21983
21984 test_247f() {
21985         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21986         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21987                 skip "Need at least version 2.14.50.162"
21988         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21989                 skip "Fileset feature is not supported"
21990
21991         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21992         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21993                 error "mkdir remote failed"
21994         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21995                 error "mkdir remote/subdir failed"
21996         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21997                 error "mkdir striped failed"
21998         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21999
22000         local submount=${MOUNT}_$tdir
22001
22002         mkdir -p $submount || error "mkdir $submount failed"
22003         stack_trap "rmdir $submount"
22004
22005         local dir
22006         local fileset=$FILESET
22007         local mdts=$(comma_list $(mdts_nodes))
22008
22009         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22010         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22011                 $tdir/striped/subdir $tdir/striped/.; do
22012                 FILESET="$fileset/$dir" mount_client $submount ||
22013                         error "mount $dir failed"
22014                 umount_client $submount
22015         done
22016 }
22017 run_test 247f "mount striped or remote directory as fileset"
22018
22019 test_subdir_mount_lock()
22020 {
22021         local testdir=$1
22022         local submount=${MOUNT}_$(basename $testdir)
22023
22024         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22025
22026         mkdir -p $submount || error "mkdir $submount failed"
22027         stack_trap "rmdir $submount"
22028
22029         FILESET="$fileset/$testdir" mount_client $submount ||
22030                 error "mount $FILESET failed"
22031         stack_trap "umount $submount"
22032
22033         local mdts=$(comma_list $(mdts_nodes))
22034
22035         local nrpcs
22036
22037         stat $submount > /dev/null || error "stat $submount failed"
22038         cancel_lru_locks $MDC
22039         stat $submount > /dev/null || error "stat $submount failed"
22040         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22041         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22042         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22043         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22044                 awk '/getattr/ {sum += $2} END {print sum}')
22045
22046         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22047 }
22048
22049 test_247g() {
22050         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22051
22052         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22053                 error "mkdir $tdir failed"
22054         test_subdir_mount_lock $tdir
22055 }
22056 run_test 247g "striped directory submount revalidate ROOT from cache"
22057
22058 test_247h() {
22059         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22060         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22061                 skip "Need MDS version at least 2.15.51"
22062
22063         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22064         test_subdir_mount_lock $tdir
22065         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22066         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22067                 error "mkdir $tdir.1 failed"
22068         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22069 }
22070 run_test 247h "remote directory submount revalidate ROOT from cache"
22071
22072 test_248a() {
22073         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22074         [ -z "$fast_read_sav" ] && skip "no fast read support"
22075
22076         # create a large file for fast read verification
22077         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22078
22079         # make sure the file is created correctly
22080         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22081                 { rm -f $DIR/$tfile; skip "file creation error"; }
22082
22083         echo "Test 1: verify that fast read is 4 times faster on cache read"
22084
22085         # small read with fast read enabled
22086         $LCTL set_param -n llite.*.fast_read=1
22087         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22088                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22089                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22090         # small read with fast read disabled
22091         $LCTL set_param -n llite.*.fast_read=0
22092         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22093                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22094                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22095
22096         # verify that fast read is 4 times faster for cache read
22097         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22098                 error_not_in_vm "fast read was not 4 times faster: " \
22099                            "$t_fast vs $t_slow"
22100
22101         echo "Test 2: verify the performance between big and small read"
22102         $LCTL set_param -n llite.*.fast_read=1
22103
22104         # 1k non-cache read
22105         cancel_lru_locks osc
22106         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22107                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22108                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22109
22110         # 1M non-cache read
22111         cancel_lru_locks osc
22112         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22113                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22114                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22115
22116         # verify that big IO is not 4 times faster than small IO
22117         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22118                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22119
22120         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22121         rm -f $DIR/$tfile
22122 }
22123 run_test 248a "fast read verification"
22124
22125 test_248b() {
22126         # Default short_io_bytes=16384, try both smaller and larger sizes.
22127         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22128         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22129         echo "bs=53248 count=113 normal buffered write"
22130         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22131                 error "dd of initial data file failed"
22132         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22133
22134         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22135         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22136                 error "dd with sync normal writes failed"
22137         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22138
22139         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22140         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22141                 error "dd with sync small writes failed"
22142         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22143
22144         cancel_lru_locks osc
22145
22146         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22147         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22148         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22149         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22150                 iflag=direct || error "dd with O_DIRECT small read failed"
22151         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22152         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22153                 error "compare $TMP/$tfile.1 failed"
22154
22155         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22156         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22157
22158         # just to see what the maximum tunable value is, and test parsing
22159         echo "test invalid parameter 2MB"
22160         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22161                 error "too-large short_io_bytes allowed"
22162         echo "test maximum parameter 512KB"
22163         # if we can set a larger short_io_bytes, run test regardless of version
22164         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22165                 # older clients may not allow setting it this large, that's OK
22166                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22167                         skip "Need at least client version 2.13.50"
22168                 error "medium short_io_bytes failed"
22169         fi
22170         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22171         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22172
22173         echo "test large parameter 64KB"
22174         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22175         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22176
22177         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22178         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22179                 error "dd with sync large writes failed"
22180         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22181
22182         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22183         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22184         num=$((113 * 4096 / PAGE_SIZE))
22185         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22186         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22187                 error "dd with O_DIRECT large writes failed"
22188         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22189                 error "compare $DIR/$tfile.3 failed"
22190
22191         cancel_lru_locks osc
22192
22193         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22194         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22195                 error "dd with O_DIRECT large read failed"
22196         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22197                 error "compare $TMP/$tfile.2 failed"
22198
22199         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22200         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22201                 error "dd with O_DIRECT large read failed"
22202         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22203                 error "compare $TMP/$tfile.3 failed"
22204 }
22205 run_test 248b "test short_io read and write for both small and large sizes"
22206
22207 test_249() { # LU-7890
22208         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22209                 skip "Need at least version 2.8.54"
22210
22211         rm -f $DIR/$tfile
22212         $LFS setstripe -c 1 $DIR/$tfile
22213         # Offset 2T == 4k * 512M
22214         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22215                 error "dd to 2T offset failed"
22216 }
22217 run_test 249 "Write above 2T file size"
22218
22219 test_250() {
22220         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22221          && skip "no 16TB file size limit on ZFS"
22222
22223         $LFS setstripe -c 1 $DIR/$tfile
22224         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22225         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22226         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22227         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22228                 conv=notrunc,fsync && error "append succeeded"
22229         return 0
22230 }
22231 run_test 250 "Write above 16T limit"
22232
22233 test_251() {
22234         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22235
22236         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22237         #Skip once - writing the first stripe will succeed
22238         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22239         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22240                 error "short write happened"
22241
22242         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22243         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22244                 error "short read happened"
22245
22246         rm -f $DIR/$tfile
22247 }
22248 run_test 251 "Handling short read and write correctly"
22249
22250 test_252() {
22251         remote_mds_nodsh && skip "remote MDS with nodsh"
22252         remote_ost_nodsh && skip "remote OST with nodsh"
22253         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22254                 skip_env "ldiskfs only test"
22255         fi
22256
22257         local tgt
22258         local dev
22259         local out
22260         local uuid
22261         local num
22262         local gen
22263
22264         # check lr_reader on OST0000
22265         tgt=ost1
22266         dev=$(facet_device $tgt)
22267         out=$(do_facet $tgt $LR_READER $dev)
22268         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22269         echo "$out"
22270         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22271         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22272                 error "Invalid uuid returned by $LR_READER on target $tgt"
22273         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22274
22275         # check lr_reader -c on MDT0000
22276         tgt=mds1
22277         dev=$(facet_device $tgt)
22278         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22279                 skip "$LR_READER does not support additional options"
22280         fi
22281         out=$(do_facet $tgt $LR_READER -c $dev)
22282         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22283         echo "$out"
22284         num=$(echo "$out" | grep -c "mdtlov")
22285         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22286                 error "Invalid number of mdtlov clients returned by $LR_READER"
22287         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22288
22289         # check lr_reader -cr on MDT0000
22290         out=$(do_facet $tgt $LR_READER -cr $dev)
22291         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22292         echo "$out"
22293         echo "$out" | grep -q "^reply_data:$" ||
22294                 error "$LR_READER should have returned 'reply_data' section"
22295         num=$(echo "$out" | grep -c "client_generation")
22296         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22297 }
22298 run_test 252 "check lr_reader tool"
22299
22300 test_253() {
22301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22302         remote_mds_nodsh && skip "remote MDS with nodsh"
22303         remote_mgs_nodsh && skip "remote MGS with nodsh"
22304
22305         local ostidx=0
22306         local rc=0
22307         local ost_name=$(ostname_from_index $ostidx)
22308
22309         # on the mdt's osc
22310         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22311         do_facet $SINGLEMDS $LCTL get_param -n \
22312                 osp.$mdtosc_proc1.reserved_mb_high ||
22313                 skip  "remote MDS does not support reserved_mb_high"
22314
22315         rm -rf $DIR/$tdir
22316         wait_mds_ost_sync
22317         wait_delete_completed
22318         mkdir $DIR/$tdir
22319
22320         pool_add $TESTNAME || error "Pool creation failed"
22321         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22322
22323         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22324                 error "Setstripe failed"
22325
22326         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22327
22328         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22329                     grep "watermarks")
22330         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22331
22332         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22333                         osp.$mdtosc_proc1.prealloc_status)
22334         echo "prealloc_status $oa_status"
22335
22336         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22337                 error "File creation should fail"
22338
22339         #object allocation was stopped, but we still able to append files
22340         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22341                 oflag=append || error "Append failed"
22342
22343         rm -f $DIR/$tdir/$tfile.0
22344
22345         # For this test, we want to delete the files we created to go out of
22346         # space but leave the watermark, so we remain nearly out of space
22347         ost_watermarks_enospc_delete_files $tfile $ostidx
22348
22349         wait_delete_completed
22350
22351         sleep_maxage
22352
22353         for i in $(seq 10 12); do
22354                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22355                         2>/dev/null || error "File creation failed after rm"
22356         done
22357
22358         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22359                         osp.$mdtosc_proc1.prealloc_status)
22360         echo "prealloc_status $oa_status"
22361
22362         if (( oa_status != 0 )); then
22363                 error "Object allocation still disable after rm"
22364         fi
22365 }
22366 run_test 253 "Check object allocation limit"
22367
22368 test_254() {
22369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22370         remote_mds_nodsh && skip "remote MDS with nodsh"
22371
22372         local mdt=$(facet_svc $SINGLEMDS)
22373
22374         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22375                 skip "MDS does not support changelog_size"
22376
22377         local cl_user
22378
22379         changelog_register || error "changelog_register failed"
22380
22381         changelog_clear 0 || error "changelog_clear failed"
22382
22383         local size1=$(do_facet $SINGLEMDS \
22384                       $LCTL get_param -n mdd.$mdt.changelog_size)
22385         echo "Changelog size $size1"
22386
22387         rm -rf $DIR/$tdir
22388         $LFS mkdir -i 0 $DIR/$tdir
22389         # change something
22390         mkdir -p $DIR/$tdir/pics/2008/zachy
22391         touch $DIR/$tdir/pics/2008/zachy/timestamp
22392         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22393         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22394         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22395         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22396         rm $DIR/$tdir/pics/desktop.jpg
22397
22398         local size2=$(do_facet $SINGLEMDS \
22399                       $LCTL get_param -n mdd.$mdt.changelog_size)
22400         echo "Changelog size after work $size2"
22401
22402         (( $size2 > $size1 )) ||
22403                 error "new Changelog size=$size2 less than old size=$size1"
22404 }
22405 run_test 254 "Check changelog size"
22406
22407 ladvise_no_type()
22408 {
22409         local type=$1
22410         local file=$2
22411
22412         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22413                 awk -F: '{print $2}' | grep $type > /dev/null
22414         if [ $? -ne 0 ]; then
22415                 return 0
22416         fi
22417         return 1
22418 }
22419
22420 ladvise_no_ioctl()
22421 {
22422         local file=$1
22423
22424         lfs ladvise -a willread $file > /dev/null 2>&1
22425         if [ $? -eq 0 ]; then
22426                 return 1
22427         fi
22428
22429         lfs ladvise -a willread $file 2>&1 |
22430                 grep "Inappropriate ioctl for device" > /dev/null
22431         if [ $? -eq 0 ]; then
22432                 return 0
22433         fi
22434         return 1
22435 }
22436
22437 percent() {
22438         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22439 }
22440
22441 # run a random read IO workload
22442 # usage: random_read_iops <filename> <filesize> <iosize>
22443 random_read_iops() {
22444         local file=$1
22445         local fsize=$2
22446         local iosize=${3:-4096}
22447
22448         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22449                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22450 }
22451
22452 drop_file_oss_cache() {
22453         local file="$1"
22454         local nodes="$2"
22455
22456         $LFS ladvise -a dontneed $file 2>/dev/null ||
22457                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22458 }
22459
22460 ladvise_willread_performance()
22461 {
22462         local repeat=10
22463         local average_origin=0
22464         local average_cache=0
22465         local average_ladvise=0
22466
22467         for ((i = 1; i <= $repeat; i++)); do
22468                 echo "Iter $i/$repeat: reading without willread hint"
22469                 cancel_lru_locks osc
22470                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22471                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22472                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22473                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22474
22475                 cancel_lru_locks osc
22476                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22477                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22478                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22479
22480                 cancel_lru_locks osc
22481                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22482                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22483                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22484                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22485                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22486         done
22487         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22488         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22489         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22490
22491         speedup_cache=$(percent $average_cache $average_origin)
22492         speedup_ladvise=$(percent $average_ladvise $average_origin)
22493
22494         echo "Average uncached read: $average_origin"
22495         echo "Average speedup with OSS cached read: " \
22496                 "$average_cache = +$speedup_cache%"
22497         echo "Average speedup with ladvise willread: " \
22498                 "$average_ladvise = +$speedup_ladvise%"
22499
22500         local lowest_speedup=20
22501         if (( ${average_cache%.*} < $lowest_speedup )); then
22502                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22503                      " got $average_cache%. Skipping ladvise willread check."
22504                 return 0
22505         fi
22506
22507         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22508         # it is still good to run until then to exercise 'ladvise willread'
22509         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22510                 [ "$ost1_FSTYPE" = "zfs" ] &&
22511                 echo "osd-zfs does not support dontneed or drop_caches" &&
22512                 return 0
22513
22514         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22515         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22516                 error_not_in_vm "Speedup with willread is less than " \
22517                         "$lowest_speedup%, got $average_ladvise%"
22518 }
22519
22520 test_255a() {
22521         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22522                 skip "lustre < 2.8.54 does not support ladvise "
22523         remote_ost_nodsh && skip "remote OST with nodsh"
22524
22525         stack_trap "rm -f $DIR/$tfile"
22526         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22527
22528         ladvise_no_type willread $DIR/$tfile &&
22529                 skip "willread ladvise is not supported"
22530
22531         ladvise_no_ioctl $DIR/$tfile &&
22532                 skip "ladvise ioctl is not supported"
22533
22534         local size_mb=100
22535         local size=$((size_mb * 1048576))
22536         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22537                 error "dd to $DIR/$tfile failed"
22538
22539         lfs ladvise -a willread $DIR/$tfile ||
22540                 error "Ladvise failed with no range argument"
22541
22542         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22543                 error "Ladvise failed with no -l or -e argument"
22544
22545         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22546                 error "Ladvise failed with only -e argument"
22547
22548         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22549                 error "Ladvise failed with only -l argument"
22550
22551         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22552                 error "End offset should not be smaller than start offset"
22553
22554         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22555                 error "End offset should not be equal to start offset"
22556
22557         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22558                 error "Ladvise failed with overflowing -s argument"
22559
22560         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22561                 error "Ladvise failed with overflowing -e argument"
22562
22563         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22564                 error "Ladvise failed with overflowing -l argument"
22565
22566         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22567                 error "Ladvise succeeded with conflicting -l and -e arguments"
22568
22569         echo "Synchronous ladvise should wait"
22570         local delay=4
22571 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22572         do_nodes $(comma_list $(osts_nodes)) \
22573                 $LCTL set_param fail_val=$delay fail_loc=0x237
22574
22575         local start_ts=$SECONDS
22576         lfs ladvise -a willread $DIR/$tfile ||
22577                 error "Ladvise failed with no range argument"
22578         local end_ts=$SECONDS
22579         local inteval_ts=$((end_ts - start_ts))
22580
22581         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22582                 error "Synchronous advice didn't wait reply"
22583         fi
22584
22585         echo "Asynchronous ladvise shouldn't wait"
22586         local start_ts=$SECONDS
22587         lfs ladvise -a willread -b $DIR/$tfile ||
22588                 error "Ladvise failed with no range argument"
22589         local end_ts=$SECONDS
22590         local inteval_ts=$((end_ts - start_ts))
22591
22592         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22593                 error "Asynchronous advice blocked"
22594         fi
22595
22596         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22597         ladvise_willread_performance
22598 }
22599 run_test 255a "check 'lfs ladvise -a willread'"
22600
22601 facet_meminfo() {
22602         local facet=$1
22603         local info=$2
22604
22605         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22606 }
22607
22608 test_255b() {
22609         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22610                 skip "lustre < 2.8.54 does not support ladvise "
22611         remote_ost_nodsh && skip "remote OST with nodsh"
22612
22613         stack_trap "rm -f $DIR/$tfile"
22614         lfs setstripe -c 1 -i 0 $DIR/$tfile
22615
22616         ladvise_no_type dontneed $DIR/$tfile &&
22617                 skip "dontneed ladvise is not supported"
22618
22619         ladvise_no_ioctl $DIR/$tfile &&
22620                 skip "ladvise ioctl is not supported"
22621
22622         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22623                 [ "$ost1_FSTYPE" = "zfs" ] &&
22624                 skip "zfs-osd does not support 'ladvise dontneed'"
22625
22626         local size_mb=100
22627         local size=$((size_mb * 1048576))
22628         # In order to prevent disturbance of other processes, only check 3/4
22629         # of the memory usage
22630         local kibibytes=$((size_mb * 1024 * 3 / 4))
22631
22632         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22633                 error "dd to $DIR/$tfile failed"
22634
22635         #force write to complete before dropping OST cache & checking memory
22636         sync
22637
22638         local total=$(facet_meminfo ost1 MemTotal)
22639         echo "Total memory: $total KiB"
22640
22641         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22642         local before_read=$(facet_meminfo ost1 Cached)
22643         echo "Cache used before read: $before_read KiB"
22644
22645         lfs ladvise -a willread $DIR/$tfile ||
22646                 error "Ladvise willread failed"
22647         local after_read=$(facet_meminfo ost1 Cached)
22648         echo "Cache used after read: $after_read KiB"
22649
22650         lfs ladvise -a dontneed $DIR/$tfile ||
22651                 error "Ladvise dontneed again failed"
22652         local no_read=$(facet_meminfo ost1 Cached)
22653         echo "Cache used after dontneed ladvise: $no_read KiB"
22654
22655         if [ $total -lt $((before_read + kibibytes)) ]; then
22656                 echo "Memory is too small, abort checking"
22657                 return 0
22658         fi
22659
22660         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22661                 error "Ladvise willread should use more memory" \
22662                         "than $kibibytes KiB"
22663         fi
22664
22665         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22666                 error "Ladvise dontneed should release more memory" \
22667                         "than $kibibytes KiB"
22668         fi
22669 }
22670 run_test 255b "check 'lfs ladvise -a dontneed'"
22671
22672 test_255c() {
22673         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22674                 skip "lustre < 2.10.50 does not support lockahead"
22675
22676         local ost1_imp=$(get_osc_import_name client ost1)
22677         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22678                          cut -d'.' -f2)
22679         local count
22680         local new_count
22681         local difference
22682         local i
22683         local rc
22684
22685         test_mkdir -p $DIR/$tdir
22686         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22687
22688         #test 10 returns only success/failure
22689         i=10
22690         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22691         rc=$?
22692         if [ $rc -eq 255 ]; then
22693                 error "Ladvise test${i} failed, ${rc}"
22694         fi
22695
22696         #test 11 counts lock enqueue requests, all others count new locks
22697         i=11
22698         count=$(do_facet ost1 \
22699                 $LCTL get_param -n ost.OSS.ost.stats)
22700         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22701
22702         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22703         rc=$?
22704         if [ $rc -eq 255 ]; then
22705                 error "Ladvise test${i} failed, ${rc}"
22706         fi
22707
22708         new_count=$(do_facet ost1 \
22709                 $LCTL get_param -n ost.OSS.ost.stats)
22710         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22711                    awk '{ print $2 }')
22712
22713         difference="$((new_count - count))"
22714         if [ $difference -ne $rc ]; then
22715                 error "Ladvise test${i}, bad enqueue count, returned " \
22716                       "${rc}, actual ${difference}"
22717         fi
22718
22719         for i in $(seq 12 21); do
22720                 # If we do not do this, we run the risk of having too many
22721                 # locks and starting lock cancellation while we are checking
22722                 # lock counts.
22723                 cancel_lru_locks osc
22724
22725                 count=$($LCTL get_param -n \
22726                        ldlm.namespaces.$imp_name.lock_unused_count)
22727
22728                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22729                 rc=$?
22730                 if [ $rc -eq 255 ]; then
22731                         error "Ladvise test ${i} failed, ${rc}"
22732                 fi
22733
22734                 new_count=$($LCTL get_param -n \
22735                        ldlm.namespaces.$imp_name.lock_unused_count)
22736                 difference="$((new_count - count))"
22737
22738                 # Test 15 output is divided by 100 to map down to valid return
22739                 if [ $i -eq 15 ]; then
22740                         rc="$((rc * 100))"
22741                 fi
22742
22743                 if [ $difference -ne $rc ]; then
22744                         error "Ladvise test ${i}, bad lock count, returned " \
22745                               "${rc}, actual ${difference}"
22746                 fi
22747         done
22748
22749         #test 22 returns only success/failure
22750         i=22
22751         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22752         rc=$?
22753         if [ $rc -eq 255 ]; then
22754                 error "Ladvise test${i} failed, ${rc}"
22755         fi
22756 }
22757 run_test 255c "suite of ladvise lockahead tests"
22758
22759 test_256() {
22760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22761         remote_mds_nodsh && skip "remote MDS with nodsh"
22762         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22763         changelog_users $SINGLEMDS | grep "^cl" &&
22764                 skip "active changelog user"
22765
22766         local cl_user
22767         local cat_sl
22768         local mdt_dev
22769
22770         mdt_dev=$(facet_device $SINGLEMDS)
22771         echo $mdt_dev
22772
22773         changelog_register || error "changelog_register failed"
22774
22775         rm -rf $DIR/$tdir
22776         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22777
22778         changelog_clear 0 || error "changelog_clear failed"
22779
22780         # change something
22781         touch $DIR/$tdir/{1..10}
22782
22783         # stop the MDT
22784         stop $SINGLEMDS || error "Fail to stop MDT"
22785
22786         # remount the MDT
22787         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22788                 error "Fail to start MDT"
22789
22790         #after mount new plainllog is used
22791         touch $DIR/$tdir/{11..19}
22792         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22793         stack_trap "rm -f $tmpfile"
22794         cat_sl=$(do_facet $SINGLEMDS "sync; \
22795                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22796                  llog_reader $tmpfile | grep -c type=1064553b")
22797         do_facet $SINGLEMDS llog_reader $tmpfile
22798
22799         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22800
22801         changelog_clear 0 || error "changelog_clear failed"
22802
22803         cat_sl=$(do_facet $SINGLEMDS "sync; \
22804                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22805                  llog_reader $tmpfile | grep -c type=1064553b")
22806
22807         if (( cat_sl == 2 )); then
22808                 error "Empty plain llog was not deleted from changelog catalog"
22809         elif (( cat_sl != 1 )); then
22810                 error "Active plain llog shouldn't be deleted from catalog"
22811         fi
22812 }
22813 run_test 256 "Check llog delete for empty and not full state"
22814
22815 test_257() {
22816         remote_mds_nodsh && skip "remote MDS with nodsh"
22817         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22818                 skip "Need MDS version at least 2.8.55"
22819
22820         test_mkdir $DIR/$tdir
22821
22822         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22823                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22824         stat $DIR/$tdir
22825
22826 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22827         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22828         local facet=mds$((mdtidx + 1))
22829         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22830         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22831
22832         stop $facet || error "stop MDS failed"
22833         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22834                 error "start MDS fail"
22835         wait_recovery_complete $facet
22836 }
22837 run_test 257 "xattr locks are not lost"
22838
22839 # Verify we take the i_mutex when security requires it
22840 test_258a() {
22841 #define OBD_FAIL_IMUTEX_SEC 0x141c
22842         $LCTL set_param fail_loc=0x141c
22843         touch $DIR/$tfile
22844         chmod u+s $DIR/$tfile
22845         chmod a+rwx $DIR/$tfile
22846         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22847         RC=$?
22848         if [ $RC -ne 0 ]; then
22849                 error "error, failed to take i_mutex, rc=$?"
22850         fi
22851         rm -f $DIR/$tfile
22852 }
22853 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22854
22855 # Verify we do NOT take the i_mutex in the normal case
22856 test_258b() {
22857 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22858         $LCTL set_param fail_loc=0x141d
22859         touch $DIR/$tfile
22860         chmod a+rwx $DIR
22861         chmod a+rw $DIR/$tfile
22862         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22863         RC=$?
22864         if [ $RC -ne 0 ]; then
22865                 error "error, took i_mutex unnecessarily, rc=$?"
22866         fi
22867         rm -f $DIR/$tfile
22868
22869 }
22870 run_test 258b "verify i_mutex security behavior"
22871
22872 test_259() {
22873         local file=$DIR/$tfile
22874         local before
22875         local after
22876
22877         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22878
22879         stack_trap "rm -f $file" EXIT
22880
22881         wait_delete_completed
22882         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22883         echo "before: $before"
22884
22885         $LFS setstripe -i 0 -c 1 $file
22886         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22887         sync_all_data
22888         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22889         echo "after write: $after"
22890
22891 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22892         do_facet ost1 $LCTL set_param fail_loc=0x2301
22893         $TRUNCATE $file 0
22894         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22895         echo "after truncate: $after"
22896
22897         stop ost1
22898         do_facet ost1 $LCTL set_param fail_loc=0
22899         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22900         sleep 2
22901         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22902         echo "after restart: $after"
22903         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22904                 error "missing truncate?"
22905
22906         return 0
22907 }
22908 run_test 259 "crash at delayed truncate"
22909
22910 test_260() {
22911 #define OBD_FAIL_MDC_CLOSE               0x806
22912         $LCTL set_param fail_loc=0x80000806
22913         touch $DIR/$tfile
22914
22915 }
22916 run_test 260 "Check mdc_close fail"
22917
22918 ### Data-on-MDT sanity tests ###
22919 test_270a() {
22920         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22921                 skip "Need MDS version at least 2.10.55 for DoM"
22922
22923         # create DoM file
22924         local dom=$DIR/$tdir/dom_file
22925         local tmp=$DIR/$tdir/tmp_file
22926
22927         mkdir_on_mdt0 $DIR/$tdir
22928
22929         # basic checks for DoM component creation
22930         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22931                 error "Can set MDT layout to non-first entry"
22932
22933         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22934                 error "Can define multiple entries as MDT layout"
22935
22936         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22937
22938         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22939         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22940         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22941
22942         local mdtidx=$($LFS getstripe -m $dom)
22943         local mdtname=MDT$(printf %04x $mdtidx)
22944         local facet=mds$((mdtidx + 1))
22945         local space_check=1
22946
22947         # Skip free space checks with ZFS
22948         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22949
22950         # write
22951         sync
22952         local size_tmp=$((65536 * 3))
22953         local mdtfree1=$(do_facet $facet \
22954                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22955
22956         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22957         # check also direct IO along write
22958         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22959         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22960         sync
22961         cmp $tmp $dom || error "file data is different"
22962         [ $(stat -c%s $dom) == $size_tmp ] ||
22963                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22964         if [ $space_check == 1 ]; then
22965                 local mdtfree2=$(do_facet $facet \
22966                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22967
22968                 # increase in usage from by $size_tmp
22969                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22970                         error "MDT free space wrong after write: " \
22971                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22972         fi
22973
22974         # truncate
22975         local size_dom=10000
22976
22977         $TRUNCATE $dom $size_dom
22978         [ $(stat -c%s $dom) == $size_dom ] ||
22979                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22980         if [ $space_check == 1 ]; then
22981                 mdtfree1=$(do_facet $facet \
22982                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22983                 # decrease in usage from $size_tmp to new $size_dom
22984                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22985                   $(((size_tmp - size_dom) / 1024)) ] ||
22986                         error "MDT free space is wrong after truncate: " \
22987                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22988         fi
22989
22990         # append
22991         cat $tmp >> $dom
22992         sync
22993         size_dom=$((size_dom + size_tmp))
22994         [ $(stat -c%s $dom) == $size_dom ] ||
22995                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22996         if [ $space_check == 1 ]; then
22997                 mdtfree2=$(do_facet $facet \
22998                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22999                 # increase in usage by $size_tmp from previous
23000                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23001                         error "MDT free space is wrong after append: " \
23002                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23003         fi
23004
23005         # delete
23006         rm $dom
23007         if [ $space_check == 1 ]; then
23008                 mdtfree1=$(do_facet $facet \
23009                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23010                 # decrease in usage by $size_dom from previous
23011                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23012                         error "MDT free space is wrong after removal: " \
23013                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23014         fi
23015
23016         # combined striping
23017         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23018                 error "Can't create DoM + OST striping"
23019
23020         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23021         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23022         # check also direct IO along write
23023         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23024         sync
23025         cmp $tmp $dom || error "file data is different"
23026         [ $(stat -c%s $dom) == $size_tmp ] ||
23027                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23028         rm $dom $tmp
23029
23030         return 0
23031 }
23032 run_test 270a "DoM: basic functionality tests"
23033
23034 test_270b() {
23035         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23036                 skip "Need MDS version at least 2.10.55"
23037
23038         local dom=$DIR/$tdir/dom_file
23039         local max_size=1048576
23040
23041         mkdir -p $DIR/$tdir
23042         $LFS setstripe -E $max_size -L mdt $dom
23043
23044         # truncate over the limit
23045         $TRUNCATE $dom $(($max_size + 1)) &&
23046                 error "successful truncate over the maximum size"
23047         # write over the limit
23048         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23049                 error "successful write over the maximum size"
23050         # append over the limit
23051         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23052         echo "12345" >> $dom && error "successful append over the maximum size"
23053         rm $dom
23054
23055         return 0
23056 }
23057 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23058
23059 test_270c() {
23060         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23061                 skip "Need MDS version at least 2.10.55"
23062
23063         mkdir -p $DIR/$tdir
23064         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23065
23066         # check files inherit DoM EA
23067         touch $DIR/$tdir/first
23068         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23069                 error "bad pattern"
23070         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23071                 error "bad stripe count"
23072         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23073                 error "bad stripe size"
23074
23075         # check directory inherits DoM EA and uses it as default
23076         mkdir $DIR/$tdir/subdir
23077         touch $DIR/$tdir/subdir/second
23078         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23079                 error "bad pattern in sub-directory"
23080         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23081                 error "bad stripe count in sub-directory"
23082         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23083                 error "bad stripe size in sub-directory"
23084         return 0
23085 }
23086 run_test 270c "DoM: DoM EA inheritance tests"
23087
23088 test_270d() {
23089         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23090                 skip "Need MDS version at least 2.10.55"
23091
23092         mkdir -p $DIR/$tdir
23093         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23094
23095         # inherit default DoM striping
23096         mkdir $DIR/$tdir/subdir
23097         touch $DIR/$tdir/subdir/f1
23098
23099         # change default directory striping
23100         $LFS setstripe -c 1 $DIR/$tdir/subdir
23101         touch $DIR/$tdir/subdir/f2
23102         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23103                 error "wrong default striping in file 2"
23104         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23105                 error "bad pattern in file 2"
23106         return 0
23107 }
23108 run_test 270d "DoM: change striping from DoM to RAID0"
23109
23110 test_270e() {
23111         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23112                 skip "Need MDS version at least 2.10.55"
23113
23114         mkdir -p $DIR/$tdir/dom
23115         mkdir -p $DIR/$tdir/norm
23116         DOMFILES=20
23117         NORMFILES=10
23118         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23119         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23120
23121         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23122         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23123
23124         # find DoM files by layout
23125         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23126         [ $NUM -eq  $DOMFILES ] ||
23127                 error "lfs find -L: found $NUM, expected $DOMFILES"
23128         echo "Test 1: lfs find 20 DOM files by layout: OK"
23129
23130         # there should be 1 dir with default DOM striping
23131         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23132         [ $NUM -eq  1 ] ||
23133                 error "lfs find -L: found $NUM, expected 1 dir"
23134         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23135
23136         # find DoM files by stripe size
23137         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23138         [ $NUM -eq  $DOMFILES ] ||
23139                 error "lfs find -S: found $NUM, expected $DOMFILES"
23140         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23141
23142         # find files by stripe offset except DoM files
23143         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23144         [ $NUM -eq  $NORMFILES ] ||
23145                 error "lfs find -i: found $NUM, expected $NORMFILES"
23146         echo "Test 5: lfs find no DOM files by stripe index: OK"
23147         return 0
23148 }
23149 run_test 270e "DoM: lfs find with DoM files test"
23150
23151 test_270f() {
23152         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23153                 skip "Need MDS version at least 2.10.55"
23154
23155         local mdtname=${FSNAME}-MDT0000-mdtlov
23156         local dom=$DIR/$tdir/dom_file
23157         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23158                                                 lod.$mdtname.dom_stripesize)
23159         local dom_limit=131072
23160
23161         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23162         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23163                                                 lod.$mdtname.dom_stripesize)
23164         [ ${dom_limit} -eq ${dom_current} ] ||
23165                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23166
23167         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23168         $LFS setstripe -d $DIR/$tdir
23169         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23170                 error "Can't set directory default striping"
23171
23172         # exceed maximum stripe size
23173         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23174                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23175         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23176                 error "Able to create DoM component size more than LOD limit"
23177
23178         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23179         dom_current=$(do_facet mds1 $LCTL get_param -n \
23180                                                 lod.$mdtname.dom_stripesize)
23181         [ 0 -eq ${dom_current} ] ||
23182                 error "Can't set zero DoM stripe limit"
23183         rm $dom
23184
23185         # attempt to create DoM file on server with disabled DoM should
23186         # remove DoM entry from layout and be succeed
23187         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23188                 error "Can't create DoM file (DoM is disabled)"
23189         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23190                 error "File has DoM component while DoM is disabled"
23191         rm $dom
23192
23193         # attempt to create DoM file with only DoM stripe should return error
23194         $LFS setstripe -E $dom_limit -L mdt $dom &&
23195                 error "Able to create DoM-only file while DoM is disabled"
23196
23197         # too low values to be aligned with smallest stripe size 64K
23198         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23199         dom_current=$(do_facet mds1 $LCTL get_param -n \
23200                                                 lod.$mdtname.dom_stripesize)
23201         [ 30000 -eq ${dom_current} ] &&
23202                 error "Can set too small DoM stripe limit"
23203
23204         # 64K is a minimal stripe size in Lustre, expect limit of that size
23205         [ 65536 -eq ${dom_current} ] ||
23206                 error "Limit is not set to 64K but ${dom_current}"
23207
23208         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23209         dom_current=$(do_facet mds1 $LCTL get_param -n \
23210                                                 lod.$mdtname.dom_stripesize)
23211         echo $dom_current
23212         [ 2147483648 -eq ${dom_current} ] &&
23213                 error "Can set too large DoM stripe limit"
23214
23215         do_facet mds1 $LCTL set_param -n \
23216                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23217         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23218                 error "Can't create DoM component size after limit change"
23219         do_facet mds1 $LCTL set_param -n \
23220                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23221         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23222                 error "Can't create DoM file after limit decrease"
23223         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23224                 error "Can create big DoM component after limit decrease"
23225         touch ${dom}_def ||
23226                 error "Can't create file with old default layout"
23227
23228         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23229         return 0
23230 }
23231 run_test 270f "DoM: maximum DoM stripe size checks"
23232
23233 test_270g() {
23234         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23235                 skip "Need MDS version at least 2.13.52"
23236         local dom=$DIR/$tdir/$tfile
23237
23238         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23239         local lodname=${FSNAME}-MDT0000-mdtlov
23240
23241         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23242         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23243         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23244         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23245
23246         local dom_limit=1024
23247         local dom_threshold="50%"
23248
23249         $LFS setstripe -d $DIR/$tdir
23250         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23251                 error "Can't set directory default striping"
23252
23253         do_facet mds1 $LCTL set_param -n \
23254                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23255         # set 0 threshold and create DOM file to change tunable stripesize
23256         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23257         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23258                 error "Failed to create $dom file"
23259         # now tunable dom_cur_stripesize should reach maximum
23260         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23261                                         lod.${lodname}.dom_stripesize_cur_kb)
23262         [[ $dom_current == $dom_limit ]] ||
23263                 error "Current DOM stripesize is not maximum"
23264         rm $dom
23265
23266         # set threshold for further tests
23267         do_facet mds1 $LCTL set_param -n \
23268                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23269         echo "DOM threshold is $dom_threshold free space"
23270         local dom_def
23271         local dom_set
23272         # Spoof bfree to exceed threshold
23273         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23274         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23275         for spfree in 40 20 0 15 30 55; do
23276                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23277                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23278                         error "Failed to create $dom file"
23279                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23280                                         lod.${lodname}.dom_stripesize_cur_kb)
23281                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23282                 [[ $dom_def != $dom_current ]] ||
23283                         error "Default stripe size was not changed"
23284                 if (( spfree > 0 )) ; then
23285                         dom_set=$($LFS getstripe -S $dom)
23286                         (( dom_set == dom_def * 1024 )) ||
23287                                 error "DOM component size is still old"
23288                 else
23289                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23290                                 error "DoM component is set with no free space"
23291                 fi
23292                 rm $dom
23293                 dom_current=$dom_def
23294         done
23295 }
23296 run_test 270g "DoM: default DoM stripe size depends on free space"
23297
23298 test_270h() {
23299         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23300                 skip "Need MDS version at least 2.13.53"
23301
23302         local mdtname=${FSNAME}-MDT0000-mdtlov
23303         local dom=$DIR/$tdir/$tfile
23304         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23305
23306         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23307         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23308
23309         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23310         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23311                 error "can't create OST file"
23312         # mirrored file with DOM entry in the second mirror
23313         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23314                 error "can't create mirror with DoM component"
23315
23316         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23317
23318         # DOM component in the middle and has other enries in the same mirror,
23319         # should succeed but lost DoM component
23320         $LFS setstripe --copy=${dom}_1 $dom ||
23321                 error "Can't create file from OST|DOM mirror layout"
23322         # check new file has no DoM layout after all
23323         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23324                 error "File has DoM component while DoM is disabled"
23325 }
23326 run_test 270h "DoM: DoM stripe removal when disabled on server"
23327
23328 test_270i() {
23329         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23330                 skip "Need MDS version at least 2.14.54"
23331
23332         mkdir $DIR/$tdir
23333         # DoM with plain layout
23334         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23335                 error "default plain layout with DoM must fail"
23336         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23337                 error "setstripe plain file layout with DoM must fail"
23338         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23339                 error "default DoM layout with bad striping must fail"
23340         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23341                 error "setstripe to DoM layout with bad striping must fail"
23342         return 0
23343 }
23344 run_test 270i "DoM: setting invalid DoM striping should fail"
23345
23346 test_271a() {
23347         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23348                 skip "Need MDS version at least 2.10.55"
23349
23350         local dom=$DIR/$tdir/dom
23351
23352         mkdir -p $DIR/$tdir
23353
23354         $LFS setstripe -E 1024K -L mdt $dom
23355
23356         lctl set_param -n mdc.*.stats=clear
23357         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23358         cat $dom > /dev/null
23359         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23360         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23361         ls $dom
23362         rm -f $dom
23363 }
23364 run_test 271a "DoM: data is cached for read after write"
23365
23366 test_271b() {
23367         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23368                 skip "Need MDS version at least 2.10.55"
23369
23370         local dom=$DIR/$tdir/dom
23371
23372         mkdir -p $DIR/$tdir
23373
23374         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23375
23376         lctl set_param -n mdc.*.stats=clear
23377         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23378         cancel_lru_locks mdc
23379         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23380         # second stat to check size is cached on client
23381         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23382         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23383         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23384         rm -f $dom
23385 }
23386 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23387
23388 test_271ba() {
23389         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23390                 skip "Need MDS version at least 2.10.55"
23391
23392         local dom=$DIR/$tdir/dom
23393
23394         mkdir -p $DIR/$tdir
23395
23396         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23397
23398         lctl set_param -n mdc.*.stats=clear
23399         lctl set_param -n osc.*.stats=clear
23400         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23401         cancel_lru_locks mdc
23402         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23403         # second stat to check size is cached on client
23404         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23405         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23406         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23407         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23408         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23409         rm -f $dom
23410 }
23411 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23412
23413
23414 get_mdc_stats() {
23415         local mdtidx=$1
23416         local param=$2
23417         local mdt=MDT$(printf %04x $mdtidx)
23418
23419         if [ -z $param ]; then
23420                 lctl get_param -n mdc.*$mdt*.stats
23421         else
23422                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23423         fi
23424 }
23425
23426 test_271c() {
23427         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23428                 skip "Need MDS version at least 2.10.55"
23429
23430         local dom=$DIR/$tdir/dom
23431
23432         mkdir -p $DIR/$tdir
23433
23434         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23435
23436         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23437         local facet=mds$((mdtidx + 1))
23438
23439         cancel_lru_locks mdc
23440         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23441         createmany -o $dom 1000
23442         lctl set_param -n mdc.*.stats=clear
23443         smalliomany -w $dom 1000 200
23444         get_mdc_stats $mdtidx
23445         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23446         # Each file has 1 open, 1 IO enqueues, total 2000
23447         # but now we have also +1 getxattr for security.capability, total 3000
23448         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23449         unlinkmany $dom 1000
23450
23451         cancel_lru_locks mdc
23452         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23453         createmany -o $dom 1000
23454         lctl set_param -n mdc.*.stats=clear
23455         smalliomany -w $dom 1000 200
23456         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23457         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23458         # for OPEN and IO lock.
23459         [ $((enq - enq_2)) -ge 1000 ] ||
23460                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23461         unlinkmany $dom 1000
23462         return 0
23463 }
23464 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23465
23466 cleanup_271def_tests() {
23467         trap 0
23468         rm -f $1
23469 }
23470
23471 test_271d() {
23472         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23473                 skip "Need MDS version at least 2.10.57"
23474
23475         local dom=$DIR/$tdir/dom
23476         local tmp=$TMP/$tfile
23477         trap "cleanup_271def_tests $tmp" EXIT
23478
23479         mkdir -p $DIR/$tdir
23480
23481         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23482
23483         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23484
23485         cancel_lru_locks mdc
23486         dd if=/dev/urandom of=$tmp bs=1000 count=1
23487         dd if=$tmp of=$dom bs=1000 count=1
23488         cancel_lru_locks mdc
23489
23490         cat /etc/hosts >> $tmp
23491         lctl set_param -n mdc.*.stats=clear
23492
23493         # append data to the same file it should update local page
23494         echo "Append to the same page"
23495         cat /etc/hosts >> $dom
23496         local num=$(get_mdc_stats $mdtidx ost_read)
23497         local ra=$(get_mdc_stats $mdtidx req_active)
23498         local rw=$(get_mdc_stats $mdtidx req_waittime)
23499
23500         [ -z $num ] || error "$num READ RPC occured"
23501         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23502         echo "... DONE"
23503
23504         # compare content
23505         cmp $tmp $dom || error "file miscompare"
23506
23507         cancel_lru_locks mdc
23508         lctl set_param -n mdc.*.stats=clear
23509
23510         echo "Open and read file"
23511         cat $dom > /dev/null
23512         local num=$(get_mdc_stats $mdtidx ost_read)
23513         local ra=$(get_mdc_stats $mdtidx req_active)
23514         local rw=$(get_mdc_stats $mdtidx req_waittime)
23515
23516         [ -z $num ] || error "$num READ RPC occured"
23517         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23518         echo "... DONE"
23519
23520         # compare content
23521         cmp $tmp $dom || error "file miscompare"
23522
23523         return 0
23524 }
23525 run_test 271d "DoM: read on open (1K file in reply buffer)"
23526
23527 test_271f() {
23528         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23529                 skip "Need MDS version at least 2.10.57"
23530
23531         local dom=$DIR/$tdir/dom
23532         local tmp=$TMP/$tfile
23533         trap "cleanup_271def_tests $tmp" EXIT
23534
23535         mkdir -p $DIR/$tdir
23536
23537         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23538
23539         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23540
23541         cancel_lru_locks mdc
23542         dd if=/dev/urandom of=$tmp bs=265000 count=1
23543         dd if=$tmp of=$dom bs=265000 count=1
23544         cancel_lru_locks mdc
23545         cat /etc/hosts >> $tmp
23546         lctl set_param -n mdc.*.stats=clear
23547
23548         echo "Append to the same page"
23549         cat /etc/hosts >> $dom
23550         local num=$(get_mdc_stats $mdtidx ost_read)
23551         local ra=$(get_mdc_stats $mdtidx req_active)
23552         local rw=$(get_mdc_stats $mdtidx req_waittime)
23553
23554         [ -z $num ] || error "$num READ RPC occured"
23555         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23556         echo "... DONE"
23557
23558         # compare content
23559         cmp $tmp $dom || error "file miscompare"
23560
23561         cancel_lru_locks mdc
23562         lctl set_param -n mdc.*.stats=clear
23563
23564         echo "Open and read file"
23565         cat $dom > /dev/null
23566         local num=$(get_mdc_stats $mdtidx ost_read)
23567         local ra=$(get_mdc_stats $mdtidx req_active)
23568         local rw=$(get_mdc_stats $mdtidx req_waittime)
23569
23570         [ -z $num ] && num=0
23571         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23572         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23573         echo "... DONE"
23574
23575         # compare content
23576         cmp $tmp $dom || error "file miscompare"
23577
23578         return 0
23579 }
23580 run_test 271f "DoM: read on open (200K file and read tail)"
23581
23582 test_271g() {
23583         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23584                 skip "Skipping due to old client or server version"
23585
23586         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23587         # to get layout
23588         $CHECKSTAT -t file $DIR1/$tfile
23589
23590         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23591         MULTIOP_PID=$!
23592         sleep 1
23593         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23594         $LCTL set_param fail_loc=0x80000314
23595         rm $DIR1/$tfile || error "Unlink fails"
23596         RC=$?
23597         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23598         [ $RC -eq 0 ] || error "Failed write to stale object"
23599 }
23600 run_test 271g "Discard DoM data vs client flush race"
23601
23602 test_272a() {
23603         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23604                 skip "Need MDS version at least 2.11.50"
23605
23606         local dom=$DIR/$tdir/dom
23607         mkdir -p $DIR/$tdir
23608
23609         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23610         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23611                 error "failed to write data into $dom"
23612         local old_md5=$(md5sum $dom)
23613
23614         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23615                 error "failed to migrate to the same DoM component"
23616
23617         local new_md5=$(md5sum $dom)
23618
23619         [ "$old_md5" == "$new_md5" ] ||
23620                 error "md5sum differ: $old_md5, $new_md5"
23621
23622         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23623                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23624 }
23625 run_test 272a "DoM migration: new layout with the same DOM component"
23626
23627 test_272b() {
23628         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23629                 skip "Need MDS version at least 2.11.50"
23630
23631         local dom=$DIR/$tdir/dom
23632         mkdir -p $DIR/$tdir
23633         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23634
23635         local mdtidx=$($LFS getstripe -m $dom)
23636         local mdtname=MDT$(printf %04x $mdtidx)
23637         local facet=mds$((mdtidx + 1))
23638
23639         local mdtfree1=$(do_facet $facet \
23640                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23641         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23642                 error "failed to write data into $dom"
23643         local old_md5=$(md5sum $dom)
23644         cancel_lru_locks mdc
23645         local mdtfree1=$(do_facet $facet \
23646                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23647
23648         $LFS migrate -c2 $dom ||
23649                 error "failed to migrate to the new composite layout"
23650         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23651                 error "MDT stripe was not removed"
23652
23653         cancel_lru_locks mdc
23654         local new_md5=$(md5sum $dom)
23655         [ "$old_md5" == "$new_md5" ] ||
23656                 error "$old_md5 != $new_md5"
23657
23658         # Skip free space checks with ZFS
23659         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23660                 local mdtfree2=$(do_facet $facet \
23661                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23662                 [ $mdtfree2 -gt $mdtfree1 ] ||
23663                         error "MDT space is not freed after migration"
23664         fi
23665         return 0
23666 }
23667 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23668
23669 test_272c() {
23670         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23671                 skip "Need MDS version at least 2.11.50"
23672
23673         local dom=$DIR/$tdir/$tfile
23674         mkdir -p $DIR/$tdir
23675         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23676
23677         local mdtidx=$($LFS getstripe -m $dom)
23678         local mdtname=MDT$(printf %04x $mdtidx)
23679         local facet=mds$((mdtidx + 1))
23680
23681         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23682                 error "failed to write data into $dom"
23683         local old_md5=$(md5sum $dom)
23684         cancel_lru_locks mdc
23685         local mdtfree1=$(do_facet $facet \
23686                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23687
23688         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23689                 error "failed to migrate to the new composite layout"
23690         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23691                 error "MDT stripe was not removed"
23692
23693         cancel_lru_locks mdc
23694         local new_md5=$(md5sum $dom)
23695         [ "$old_md5" == "$new_md5" ] ||
23696                 error "$old_md5 != $new_md5"
23697
23698         # Skip free space checks with ZFS
23699         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23700                 local mdtfree2=$(do_facet $facet \
23701                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23702                 [ $mdtfree2 -gt $mdtfree1 ] ||
23703                         error "MDS space is not freed after migration"
23704         fi
23705         return 0
23706 }
23707 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23708
23709 test_272d() {
23710         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23711                 skip "Need MDS version at least 2.12.55"
23712
23713         local dom=$DIR/$tdir/$tfile
23714         mkdir -p $DIR/$tdir
23715         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23716
23717         local mdtidx=$($LFS getstripe -m $dom)
23718         local mdtname=MDT$(printf %04x $mdtidx)
23719         local facet=mds$((mdtidx + 1))
23720
23721         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23722                 error "failed to write data into $dom"
23723         local old_md5=$(md5sum $dom)
23724         cancel_lru_locks mdc
23725         local mdtfree1=$(do_facet $facet \
23726                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23727
23728         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23729                 error "failed mirroring to the new composite layout"
23730         $LFS mirror resync $dom ||
23731                 error "failed mirror resync"
23732         $LFS mirror split --mirror-id 1 -d $dom ||
23733                 error "failed mirror split"
23734
23735         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23736                 error "MDT stripe was not removed"
23737
23738         cancel_lru_locks mdc
23739         local new_md5=$(md5sum $dom)
23740         [ "$old_md5" == "$new_md5" ] ||
23741                 error "$old_md5 != $new_md5"
23742
23743         # Skip free space checks with ZFS
23744         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23745                 local mdtfree2=$(do_facet $facet \
23746                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23747                 [ $mdtfree2 -gt $mdtfree1 ] ||
23748                         error "MDS space is not freed after DOM mirror deletion"
23749         fi
23750         return 0
23751 }
23752 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23753
23754 test_272e() {
23755         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23756                 skip "Need MDS version at least 2.12.55"
23757
23758         local dom=$DIR/$tdir/$tfile
23759         mkdir -p $DIR/$tdir
23760         $LFS setstripe -c 2 $dom
23761
23762         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23763                 error "failed to write data into $dom"
23764         local old_md5=$(md5sum $dom)
23765         cancel_lru_locks
23766
23767         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23768                 error "failed mirroring to the DOM layout"
23769         $LFS mirror resync $dom ||
23770                 error "failed mirror resync"
23771         $LFS mirror split --mirror-id 1 -d $dom ||
23772                 error "failed mirror split"
23773
23774         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23775                 error "MDT stripe wasn't set"
23776
23777         cancel_lru_locks
23778         local new_md5=$(md5sum $dom)
23779         [ "$old_md5" == "$new_md5" ] ||
23780                 error "$old_md5 != $new_md5"
23781
23782         return 0
23783 }
23784 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23785
23786 test_272f() {
23787         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23788                 skip "Need MDS version at least 2.12.55"
23789
23790         local dom=$DIR/$tdir/$tfile
23791         mkdir -p $DIR/$tdir
23792         $LFS setstripe -c 2 $dom
23793
23794         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23795                 error "failed to write data into $dom"
23796         local old_md5=$(md5sum $dom)
23797         cancel_lru_locks
23798
23799         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23800                 error "failed migrating to the DOM file"
23801
23802         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23803                 error "MDT stripe wasn't set"
23804
23805         cancel_lru_locks
23806         local new_md5=$(md5sum $dom)
23807         [ "$old_md5" != "$new_md5" ] &&
23808                 error "$old_md5 != $new_md5"
23809
23810         return 0
23811 }
23812 run_test 272f "DoM migration: OST-striped file to DOM file"
23813
23814 test_273a() {
23815         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23816                 skip "Need MDS version at least 2.11.50"
23817
23818         # Layout swap cannot be done if either file has DOM component,
23819         # this will never be supported, migration should be used instead
23820
23821         local dom=$DIR/$tdir/$tfile
23822         mkdir -p $DIR/$tdir
23823
23824         $LFS setstripe -c2 ${dom}_plain
23825         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23826         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23827                 error "can swap layout with DoM component"
23828         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23829                 error "can swap layout with DoM component"
23830
23831         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23832         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23833                 error "can swap layout with DoM component"
23834         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23835                 error "can swap layout with DoM component"
23836         return 0
23837 }
23838 run_test 273a "DoM: layout swapping should fail with DOM"
23839
23840 test_273b() {
23841         mkdir -p $DIR/$tdir
23842         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23843
23844 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23845         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23846
23847         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23848 }
23849 run_test 273b "DoM: race writeback and object destroy"
23850
23851 test_275() {
23852         remote_ost_nodsh && skip "remote OST with nodsh"
23853         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23854                 skip "Need OST version >= 2.10.57"
23855
23856         local file=$DIR/$tfile
23857         local oss
23858
23859         oss=$(comma_list $(osts_nodes))
23860
23861         dd if=/dev/urandom of=$file bs=1M count=2 ||
23862                 error "failed to create a file"
23863         cancel_lru_locks osc
23864
23865         #lock 1
23866         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23867                 error "failed to read a file"
23868
23869 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23870         $LCTL set_param fail_loc=0x8000031f
23871
23872         cancel_lru_locks osc &
23873         sleep 1
23874
23875 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23876         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23877         #IO takes another lock, but matches the PENDING one
23878         #and places it to the IO RPC
23879         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23880                 error "failed to read a file with PENDING lock"
23881 }
23882 run_test 275 "Read on a canceled duplicate lock"
23883
23884 test_276() {
23885         remote_ost_nodsh && skip "remote OST with nodsh"
23886         local pid
23887
23888         do_facet ost1 "(while true; do \
23889                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23890                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23891         pid=$!
23892
23893         for LOOP in $(seq 20); do
23894                 stop ost1
23895                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23896         done
23897         kill -9 $pid
23898         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23899                 rm $TMP/sanity_276_pid"
23900 }
23901 run_test 276 "Race between mount and obd_statfs"
23902
23903 test_277() {
23904         $LCTL set_param ldlm.namespaces.*.lru_size=0
23905         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23906         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23907                         grep ^used_mb | awk '{print $2}')
23908         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23909         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23910                 oflag=direct conv=notrunc
23911         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23912                         grep ^used_mb | awk '{print $2}')
23913         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23914 }
23915 run_test 277 "Direct IO shall drop page cache"
23916
23917 test_278() {
23918         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23919         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23920         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23921                 skip "needs the same host for mdt1 mdt2" && return
23922
23923         local pid1
23924         local pid2
23925
23926 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23927         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23928         stop mds2 &
23929         pid2=$!
23930
23931         stop mds1
23932
23933         echo "Starting MDTs"
23934         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23935         wait $pid2
23936 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23937 #will return NULL
23938         do_facet mds2 $LCTL set_param fail_loc=0
23939
23940         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23941         wait_recovery_complete mds2
23942 }
23943 run_test 278 "Race starting MDS between MDTs stop/start"
23944
23945 test_280() {
23946         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23947                 skip "Need MGS version at least 2.13.52"
23948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23949         combined_mgs_mds || skip "needs combined MGS/MDT"
23950
23951         umount_client $MOUNT
23952 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23953         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23954
23955         mount_client $MOUNT &
23956         sleep 1
23957         stop mgs || error "stop mgs failed"
23958         #for a race mgs would crash
23959         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23960         # make sure we unmount client before remounting
23961         wait
23962         umount_client $MOUNT
23963         mount_client $MOUNT || error "mount client failed"
23964 }
23965 run_test 280 "Race between MGS umount and client llog processing"
23966
23967 cleanup_test_300() {
23968         trap 0
23969         umask $SAVE_UMASK
23970 }
23971 test_striped_dir() {
23972         local mdt_index=$1
23973         local stripe_count
23974         local stripe_index
23975
23976         mkdir -p $DIR/$tdir
23977
23978         SAVE_UMASK=$(umask)
23979         trap cleanup_test_300 RETURN EXIT
23980
23981         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23982                                                 $DIR/$tdir/striped_dir ||
23983                 error "set striped dir error"
23984
23985         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23986         [ "$mode" = "755" ] || error "expect 755 got $mode"
23987
23988         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23989                 error "getdirstripe failed"
23990         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23991         if [ "$stripe_count" != "2" ]; then
23992                 error "1:stripe_count is $stripe_count, expect 2"
23993         fi
23994         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23995         if [ "$stripe_count" != "2" ]; then
23996                 error "2:stripe_count is $stripe_count, expect 2"
23997         fi
23998
23999         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24000         if [ "$stripe_index" != "$mdt_index" ]; then
24001                 error "stripe_index is $stripe_index, expect $mdt_index"
24002         fi
24003
24004         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24005                 error "nlink error after create striped dir"
24006
24007         mkdir $DIR/$tdir/striped_dir/a
24008         mkdir $DIR/$tdir/striped_dir/b
24009
24010         stat $DIR/$tdir/striped_dir/a ||
24011                 error "create dir under striped dir failed"
24012         stat $DIR/$tdir/striped_dir/b ||
24013                 error "create dir under striped dir failed"
24014
24015         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24016                 error "nlink error after mkdir"
24017
24018         rmdir $DIR/$tdir/striped_dir/a
24019         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24020                 error "nlink error after rmdir"
24021
24022         rmdir $DIR/$tdir/striped_dir/b
24023         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24024                 error "nlink error after rmdir"
24025
24026         chattr +i $DIR/$tdir/striped_dir
24027         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24028                 error "immutable flags not working under striped dir!"
24029         chattr -i $DIR/$tdir/striped_dir
24030
24031         rmdir $DIR/$tdir/striped_dir ||
24032                 error "rmdir striped dir error"
24033
24034         cleanup_test_300
24035
24036         true
24037 }
24038
24039 test_300a() {
24040         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24041                 skip "skipped for lustre < 2.7.0"
24042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24044
24045         test_striped_dir 0 || error "failed on striped dir on MDT0"
24046         test_striped_dir 1 || error "failed on striped dir on MDT0"
24047 }
24048 run_test 300a "basic striped dir sanity test"
24049
24050 test_300b() {
24051         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24052                 skip "skipped for lustre < 2.7.0"
24053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24055
24056         local i
24057         local mtime1
24058         local mtime2
24059         local mtime3
24060
24061         test_mkdir $DIR/$tdir || error "mkdir fail"
24062         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24063                 error "set striped dir error"
24064         for i in {0..9}; do
24065                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24066                 sleep 1
24067                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24068                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24069                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24070                 sleep 1
24071                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24072                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24073                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24074         done
24075         true
24076 }
24077 run_test 300b "check ctime/mtime for striped dir"
24078
24079 test_300c() {
24080         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24081                 skip "skipped for lustre < 2.7.0"
24082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24083         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24084
24085         local file_count
24086
24087         mkdir_on_mdt0 $DIR/$tdir
24088         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24089                 error "set striped dir error"
24090
24091         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24092                 error "chown striped dir failed"
24093
24094         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24095                 error "create 5k files failed"
24096
24097         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24098
24099         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24100
24101         rm -rf $DIR/$tdir
24102 }
24103 run_test 300c "chown && check ls under striped directory"
24104
24105 test_300d() {
24106         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24107                 skip "skipped for lustre < 2.7.0"
24108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24110
24111         local stripe_count
24112         local file
24113
24114         mkdir -p $DIR/$tdir
24115         $LFS setstripe -c 2 $DIR/$tdir
24116
24117         #local striped directory
24118         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24119                 error "set striped dir error"
24120         #look at the directories for debug purposes
24121         ls -l $DIR/$tdir
24122         $LFS getdirstripe $DIR/$tdir
24123         ls -l $DIR/$tdir/striped_dir
24124         $LFS getdirstripe $DIR/$tdir/striped_dir
24125         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24126                 error "create 10 files failed"
24127
24128         #remote striped directory
24129         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24130                 error "set striped dir error"
24131         #look at the directories for debug purposes
24132         ls -l $DIR/$tdir
24133         $LFS getdirstripe $DIR/$tdir
24134         ls -l $DIR/$tdir/remote_striped_dir
24135         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24136         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24137                 error "create 10 files failed"
24138
24139         for file in $(find $DIR/$tdir); do
24140                 stripe_count=$($LFS getstripe -c $file)
24141                 [ $stripe_count -eq 2 ] ||
24142                         error "wrong stripe $stripe_count for $file"
24143         done
24144
24145         rm -rf $DIR/$tdir
24146 }
24147 run_test 300d "check default stripe under striped directory"
24148
24149 test_300e() {
24150         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24151                 skip "Need MDS version at least 2.7.55"
24152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24154
24155         local stripe_count
24156         local file
24157
24158         mkdir -p $DIR/$tdir
24159
24160         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24161                 error "set striped dir error"
24162
24163         touch $DIR/$tdir/striped_dir/a
24164         touch $DIR/$tdir/striped_dir/b
24165         touch $DIR/$tdir/striped_dir/c
24166
24167         mkdir $DIR/$tdir/striped_dir/dir_a
24168         mkdir $DIR/$tdir/striped_dir/dir_b
24169         mkdir $DIR/$tdir/striped_dir/dir_c
24170
24171         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24172                 error "set striped adir under striped dir error"
24173
24174         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24175                 error "set striped bdir under striped dir error"
24176
24177         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24178                 error "set striped cdir under striped dir error"
24179
24180         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24181                 error "rename dir under striped dir fails"
24182
24183         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24184                 error "rename dir under different stripes fails"
24185
24186         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24187                 error "rename file under striped dir should succeed"
24188
24189         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24190                 error "rename dir under striped dir should succeed"
24191
24192         rm -rf $DIR/$tdir
24193 }
24194 run_test 300e "check rename under striped directory"
24195
24196 test_300f() {
24197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24199         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24200                 skip "Need MDS version at least 2.7.55"
24201
24202         local stripe_count
24203         local file
24204
24205         rm -rf $DIR/$tdir
24206         mkdir -p $DIR/$tdir
24207
24208         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24209                 error "set striped dir error"
24210
24211         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24212                 error "set striped dir error"
24213
24214         touch $DIR/$tdir/striped_dir/a
24215         mkdir $DIR/$tdir/striped_dir/dir_a
24216         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24217                 error "create striped dir under striped dir fails"
24218
24219         touch $DIR/$tdir/striped_dir1/b
24220         mkdir $DIR/$tdir/striped_dir1/dir_b
24221         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24222                 error "create striped dir under striped dir fails"
24223
24224         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24225                 error "rename dir under different striped dir should fail"
24226
24227         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24228                 error "rename striped dir under diff striped dir should fail"
24229
24230         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24231                 error "rename file under diff striped dirs fails"
24232
24233         rm -rf $DIR/$tdir
24234 }
24235 run_test 300f "check rename cross striped directory"
24236
24237 test_300_check_default_striped_dir()
24238 {
24239         local dirname=$1
24240         local default_count=$2
24241         local default_index=$3
24242         local stripe_count
24243         local stripe_index
24244         local dir_stripe_index
24245         local dir
24246
24247         echo "checking $dirname $default_count $default_index"
24248         $LFS setdirstripe -D -c $default_count -i $default_index \
24249                                 -H all_char $DIR/$tdir/$dirname ||
24250                 error "set default stripe on striped dir error"
24251         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24252         [ $stripe_count -eq $default_count ] ||
24253                 error "expect $default_count get $stripe_count for $dirname"
24254
24255         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24256         [ $stripe_index -eq $default_index ] ||
24257                 error "expect $default_index get $stripe_index for $dirname"
24258
24259         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24260                                                 error "create dirs failed"
24261
24262         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24263         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24264         for dir in $(find $DIR/$tdir/$dirname/*); do
24265                 stripe_count=$($LFS getdirstripe -c $dir)
24266                 (( $stripe_count == $default_count )) ||
24267                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24268                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24269                 error "stripe count $default_count != $stripe_count for $dir"
24270
24271                 stripe_index=$($LFS getdirstripe -i $dir)
24272                 [ $default_index -eq -1 ] ||
24273                         [ $stripe_index -eq $default_index ] ||
24274                         error "$stripe_index != $default_index for $dir"
24275
24276                 #check default stripe
24277                 stripe_count=$($LFS getdirstripe -D -c $dir)
24278                 [ $stripe_count -eq $default_count ] ||
24279                 error "default count $default_count != $stripe_count for $dir"
24280
24281                 stripe_index=$($LFS getdirstripe -D -i $dir)
24282                 [ $stripe_index -eq $default_index ] ||
24283                 error "default index $default_index != $stripe_index for $dir"
24284         done
24285         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24286 }
24287
24288 test_300g() {
24289         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24290         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24291                 skip "Need MDS version at least 2.7.55"
24292
24293         local dir
24294         local stripe_count
24295         local stripe_index
24296
24297         mkdir_on_mdt0 $DIR/$tdir
24298         mkdir $DIR/$tdir/normal_dir
24299
24300         #Checking when client cache stripe index
24301         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24302         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24303                 error "create striped_dir failed"
24304
24305         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24306                 error "create dir0 fails"
24307         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24308         [ $stripe_index -eq 0 ] ||
24309                 error "dir0 expect index 0 got $stripe_index"
24310
24311         mkdir $DIR/$tdir/striped_dir/dir1 ||
24312                 error "create dir1 fails"
24313         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24314         [ $stripe_index -eq 1 ] ||
24315                 error "dir1 expect index 1 got $stripe_index"
24316
24317         #check default stripe count/stripe index
24318         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24319         test_300_check_default_striped_dir normal_dir 1 0
24320         test_300_check_default_striped_dir normal_dir -1 1
24321         test_300_check_default_striped_dir normal_dir 2 -1
24322
24323         #delete default stripe information
24324         echo "delete default stripeEA"
24325         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24326                 error "set default stripe on striped dir error"
24327
24328         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24329         for dir in $(find $DIR/$tdir/normal_dir/*); do
24330                 stripe_count=$($LFS getdirstripe -c $dir)
24331                 [ $stripe_count -eq 0 ] ||
24332                         error "expect 1 get $stripe_count for $dir"
24333         done
24334 }
24335 run_test 300g "check default striped directory for normal directory"
24336
24337 test_300h() {
24338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24339         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24340                 skip "Need MDS version at least 2.7.55"
24341
24342         local dir
24343         local stripe_count
24344
24345         mkdir $DIR/$tdir
24346         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24347                 error "set striped dir error"
24348
24349         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24350         test_300_check_default_striped_dir striped_dir 1 0
24351         test_300_check_default_striped_dir striped_dir -1 1
24352         test_300_check_default_striped_dir striped_dir 2 -1
24353
24354         #delete default stripe information
24355         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24356                 error "set default stripe on striped dir error"
24357
24358         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24359         for dir in $(find $DIR/$tdir/striped_dir/*); do
24360                 stripe_count=$($LFS getdirstripe -c $dir)
24361                 [ $stripe_count -eq 0 ] ||
24362                         error "expect 1 get $stripe_count for $dir"
24363         done
24364 }
24365 run_test 300h "check default striped directory for striped directory"
24366
24367 test_300i() {
24368         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24369         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24370         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24371                 skip "Need MDS version at least 2.7.55"
24372
24373         local stripe_count
24374         local file
24375
24376         mkdir $DIR/$tdir
24377
24378         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24379                 error "set striped dir error"
24380
24381         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24382                 error "create files under striped dir failed"
24383
24384         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24385                 error "set striped hashdir error"
24386
24387         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24388                 error "create dir0 under hash dir failed"
24389         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24390                 error "create dir1 under hash dir failed"
24391         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24392                 error "create dir2 under hash dir failed"
24393
24394         # unfortunately, we need to umount to clear dir layout cache for now
24395         # once we fully implement dir layout, we can drop this
24396         umount_client $MOUNT || error "umount failed"
24397         mount_client $MOUNT || error "mount failed"
24398
24399         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24400         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24401         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24402
24403         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24404                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24405                         error "create crush2 dir $tdir/hashdir/d3 failed"
24406                 $LFS find -H crush2 $DIR/$tdir/hashdir
24407                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24408                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24409
24410                 # mkdir with an invalid hash type (hash=fail_val) from client
24411                 # should be replaced on MDS with a valid (default) hash type
24412                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24413                 $LCTL set_param fail_loc=0x1901 fail_val=99
24414                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24415
24416                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24417                 local expect=$(do_facet mds1 \
24418                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24419                 [[ $hash == $expect ]] ||
24420                         error "d99 hash '$hash' != expected hash '$expect'"
24421         fi
24422
24423         #set the stripe to be unknown hash type on read
24424         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24425         $LCTL set_param fail_loc=0x1901 fail_val=99
24426         for ((i = 0; i < 10; i++)); do
24427                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24428                         error "stat f-$i failed"
24429                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24430         done
24431
24432         touch $DIR/$tdir/striped_dir/f0 &&
24433                 error "create under striped dir with unknown hash should fail"
24434
24435         $LCTL set_param fail_loc=0
24436
24437         umount_client $MOUNT || error "umount failed"
24438         mount_client $MOUNT || error "mount failed"
24439
24440         return 0
24441 }
24442 run_test 300i "client handle unknown hash type striped directory"
24443
24444 test_300j() {
24445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24447         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24448                 skip "Need MDS version at least 2.7.55"
24449
24450         local stripe_count
24451         local file
24452
24453         mkdir $DIR/$tdir
24454
24455         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24456         $LCTL set_param fail_loc=0x1702
24457         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24458                 error "set striped dir error"
24459
24460         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24461                 error "create files under striped dir failed"
24462
24463         $LCTL set_param fail_loc=0
24464
24465         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24466
24467         return 0
24468 }
24469 run_test 300j "test large update record"
24470
24471 test_300k() {
24472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24474         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24475                 skip "Need MDS version at least 2.7.55"
24476
24477         # this test needs a huge transaction
24478         local kb
24479         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24480              osd*.$FSNAME-MDT0000.kbytestotal")
24481         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24482
24483         local stripe_count
24484         local file
24485
24486         mkdir $DIR/$tdir
24487
24488         #define OBD_FAIL_LARGE_STRIPE   0x1703
24489         $LCTL set_param fail_loc=0x1703
24490         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24491                 error "set striped dir error"
24492         $LCTL set_param fail_loc=0
24493
24494         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24495                 error "getstripeddir fails"
24496         rm -rf $DIR/$tdir/striped_dir ||
24497                 error "unlink striped dir fails"
24498
24499         return 0
24500 }
24501 run_test 300k "test large striped directory"
24502
24503 test_300l() {
24504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24506         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24507                 skip "Need MDS version at least 2.7.55"
24508
24509         local stripe_index
24510
24511         test_mkdir -p $DIR/$tdir/striped_dir
24512         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24513                         error "chown $RUNAS_ID failed"
24514         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24515                 error "set default striped dir failed"
24516
24517         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24518         $LCTL set_param fail_loc=0x80000158
24519         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24520
24521         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24522         [ $stripe_index -eq 1 ] ||
24523                 error "expect 1 get $stripe_index for $dir"
24524 }
24525 run_test 300l "non-root user to create dir under striped dir with stale layout"
24526
24527 test_300m() {
24528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24529         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24530         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24531                 skip "Need MDS version at least 2.7.55"
24532
24533         mkdir -p $DIR/$tdir/striped_dir
24534         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24535                 error "set default stripes dir error"
24536
24537         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24538
24539         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24540         [ $stripe_count -eq 0 ] ||
24541                         error "expect 0 get $stripe_count for a"
24542
24543         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24544                 error "set default stripes dir error"
24545
24546         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24547
24548         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24549         [ $stripe_count -eq 0 ] ||
24550                         error "expect 0 get $stripe_count for b"
24551
24552         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24553                 error "set default stripes dir error"
24554
24555         mkdir $DIR/$tdir/striped_dir/c &&
24556                 error "default stripe_index is invalid, mkdir c should fails"
24557
24558         rm -rf $DIR/$tdir || error "rmdir fails"
24559 }
24560 run_test 300m "setstriped directory on single MDT FS"
24561
24562 cleanup_300n() {
24563         local list=$(comma_list $(mdts_nodes))
24564
24565         trap 0
24566         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24567 }
24568
24569 test_300n() {
24570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24572         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24573                 skip "Need MDS version at least 2.7.55"
24574         remote_mds_nodsh && skip "remote MDS with nodsh"
24575
24576         local stripe_index
24577         local list=$(comma_list $(mdts_nodes))
24578
24579         trap cleanup_300n RETURN EXIT
24580         mkdir -p $DIR/$tdir
24581         chmod 777 $DIR/$tdir
24582         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24583                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24584                 error "create striped dir succeeds with gid=0"
24585
24586         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24587         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24588                 error "create striped dir fails with gid=-1"
24589
24590         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24591         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24592                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24593                 error "set default striped dir succeeds with gid=0"
24594
24595
24596         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24597         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24598                 error "set default striped dir fails with gid=-1"
24599
24600
24601         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24602         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24603                                         error "create test_dir fails"
24604         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24605                                         error "create test_dir1 fails"
24606         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24607                                         error "create test_dir2 fails"
24608         cleanup_300n
24609 }
24610 run_test 300n "non-root user to create dir under striped dir with default EA"
24611
24612 test_300o() {
24613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24614         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24615         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24616                 skip "Need MDS version at least 2.7.55"
24617
24618         local numfree1
24619         local numfree2
24620
24621         mkdir -p $DIR/$tdir
24622
24623         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24624         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24625         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24626                 skip "not enough free inodes $numfree1 $numfree2"
24627         fi
24628
24629         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24630         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24631         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24632                 skip "not enough free space $numfree1 $numfree2"
24633         fi
24634
24635         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24636                 error "setdirstripe fails"
24637
24638         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24639                 error "create dirs fails"
24640
24641         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24642         ls $DIR/$tdir/striped_dir > /dev/null ||
24643                 error "ls striped dir fails"
24644         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24645                 error "unlink big striped dir fails"
24646 }
24647 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24648
24649 test_300p() {
24650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24652         remote_mds_nodsh && skip "remote MDS with nodsh"
24653
24654         mkdir_on_mdt0 $DIR/$tdir
24655
24656         #define OBD_FAIL_OUT_ENOSPC     0x1704
24657         do_facet mds2 lctl set_param fail_loc=0x80001704
24658         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24659                  && error "create striped directory should fail"
24660
24661         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24662
24663         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24664         true
24665 }
24666 run_test 300p "create striped directory without space"
24667
24668 test_300q() {
24669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24671
24672         local fd=$(free_fd)
24673         local cmd="exec $fd<$tdir"
24674         cd $DIR
24675         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24676         eval $cmd
24677         cmd="exec $fd<&-"
24678         trap "eval $cmd" EXIT
24679         cd $tdir || error "cd $tdir fails"
24680         rmdir  ../$tdir || error "rmdir $tdir fails"
24681         mkdir local_dir && error "create dir succeeds"
24682         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24683         eval $cmd
24684         return 0
24685 }
24686 run_test 300q "create remote directory under orphan directory"
24687
24688 test_300r() {
24689         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24690                 skip "Need MDS version at least 2.7.55" && return
24691         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24692
24693         mkdir $DIR/$tdir
24694
24695         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24696                 error "set striped dir error"
24697
24698         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24699                 error "getstripeddir fails"
24700
24701         local stripe_count
24702         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24703                       awk '/lmv_stripe_count:/ { print $2 }')
24704
24705         [ $MDSCOUNT -ne $stripe_count ] &&
24706                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24707
24708         rm -rf $DIR/$tdir/striped_dir ||
24709                 error "unlink striped dir fails"
24710 }
24711 run_test 300r "test -1 striped directory"
24712
24713 test_300s_helper() {
24714         local count=$1
24715
24716         local stripe_dir=$DIR/$tdir/striped_dir.$count
24717
24718         $LFS mkdir -c $count $stripe_dir ||
24719                 error "lfs mkdir -c error"
24720
24721         $LFS getdirstripe $stripe_dir ||
24722                 error "lfs getdirstripe fails"
24723
24724         local stripe_count
24725         stripe_count=$($LFS getdirstripe $stripe_dir |
24726                       awk '/lmv_stripe_count:/ { print $2 }')
24727
24728         [ $count -ne $stripe_count ] &&
24729                 error_noexit "bad stripe count $stripe_count expected $count"
24730
24731         local dupe_stripes
24732         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24733                 awk '/0x/ {count[$1] += 1}; END {
24734                         for (idx in count) {
24735                                 if (count[idx]>1) {
24736                                         print "index " idx " count " count[idx]
24737                                 }
24738                         }
24739                 }')
24740
24741         if [[ -n "$dupe_stripes" ]] ; then
24742                 lfs getdirstripe $stripe_dir
24743                 error_noexit "Dupe MDT above: $dupe_stripes "
24744         fi
24745
24746         rm -rf $stripe_dir ||
24747                 error_noexit "unlink $stripe_dir fails"
24748 }
24749
24750 test_300s() {
24751         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24752                 skip "Need MDS version at least 2.7.55" && return
24753         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24754
24755         mkdir $DIR/$tdir
24756         for count in $(seq 2 $MDSCOUNT); do
24757                 test_300s_helper $count
24758         done
24759 }
24760 run_test 300s "test lfs mkdir -c without -i"
24761
24762 test_300t() {
24763         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24764                 skip "need MDS 2.14.55 or later"
24765         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24766
24767         local testdir="$DIR/$tdir/striped_dir"
24768         local dir1=$testdir/dir1
24769         local dir2=$testdir/dir2
24770
24771         mkdir -p $testdir
24772
24773         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24774                 error "failed to set default stripe count for $testdir"
24775
24776         mkdir $dir1
24777         local stripe_count=$($LFS getdirstripe -c $dir1)
24778
24779         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24780
24781         local max_count=$((MDSCOUNT - 1))
24782         local mdts=$(comma_list $(mdts_nodes))
24783
24784         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24785         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24786
24787         mkdir $dir2
24788         stripe_count=$($LFS getdirstripe -c $dir2)
24789
24790         (( $stripe_count == $max_count )) || error "wrong stripe count"
24791 }
24792 run_test 300t "test max_mdt_stripecount"
24793
24794 prepare_remote_file() {
24795         mkdir $DIR/$tdir/src_dir ||
24796                 error "create remote source failed"
24797
24798         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24799                  error "cp to remote source failed"
24800         touch $DIR/$tdir/src_dir/a
24801
24802         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24803                 error "create remote target dir failed"
24804
24805         touch $DIR/$tdir/tgt_dir/b
24806
24807         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24808                 error "rename dir cross MDT failed!"
24809
24810         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24811                 error "src_child still exists after rename"
24812
24813         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24814                 error "missing file(a) after rename"
24815
24816         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24817                 error "diff after rename"
24818 }
24819
24820 test_310a() {
24821         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24823
24824         local remote_file=$DIR/$tdir/tgt_dir/b
24825
24826         mkdir -p $DIR/$tdir
24827
24828         prepare_remote_file || error "prepare remote file failed"
24829
24830         #open-unlink file
24831         $OPENUNLINK $remote_file $remote_file ||
24832                 error "openunlink $remote_file failed"
24833         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24834 }
24835 run_test 310a "open unlink remote file"
24836
24837 test_310b() {
24838         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24840
24841         local remote_file=$DIR/$tdir/tgt_dir/b
24842
24843         mkdir -p $DIR/$tdir
24844
24845         prepare_remote_file || error "prepare remote file failed"
24846
24847         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24848         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24849         $CHECKSTAT -t file $remote_file || error "check file failed"
24850 }
24851 run_test 310b "unlink remote file with multiple links while open"
24852
24853 test_310c() {
24854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24855         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24856
24857         local remote_file=$DIR/$tdir/tgt_dir/b
24858
24859         mkdir -p $DIR/$tdir
24860
24861         prepare_remote_file || error "prepare remote file failed"
24862
24863         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24864         multiop_bg_pause $remote_file O_uc ||
24865                         error "mulitop failed for remote file"
24866         MULTIPID=$!
24867         $MULTIOP $DIR/$tfile Ouc
24868         kill -USR1 $MULTIPID
24869         wait $MULTIPID
24870 }
24871 run_test 310c "open-unlink remote file with multiple links"
24872
24873 #LU-4825
24874 test_311() {
24875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24876         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24877         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24878                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24879         remote_mds_nodsh && skip "remote MDS with nodsh"
24880
24881         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24882         local mdts=$(comma_list $(mdts_nodes))
24883
24884         mkdir -p $DIR/$tdir
24885         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24886         createmany -o $DIR/$tdir/$tfile. 1000
24887
24888         # statfs data is not real time, let's just calculate it
24889         old_iused=$((old_iused + 1000))
24890
24891         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24892                         osp.*OST0000*MDT0000.create_count")
24893         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24894                                 osp.*OST0000*MDT0000.max_create_count")
24895         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24896
24897         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24898         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24899         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24900
24901         unlinkmany $DIR/$tdir/$tfile. 1000
24902
24903         do_nodes $mdts "$LCTL set_param -n \
24904                         osp.*OST0000*.max_create_count=$max_count"
24905         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24906                 do_nodes $mdts "$LCTL set_param -n \
24907                                 osp.*OST0000*.create_count=$count"
24908         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24909                         grep "=0" && error "create_count is zero"
24910
24911         local new_iused
24912         for i in $(seq 120); do
24913                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24914                 # system may be too busy to destroy all objs in time, use
24915                 # a somewhat small value to not fail autotest
24916                 [ $((old_iused - new_iused)) -gt 400 ] && break
24917                 sleep 1
24918         done
24919
24920         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24921         [ $((old_iused - new_iused)) -gt 400 ] ||
24922                 error "objs not destroyed after unlink"
24923 }
24924 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24925
24926 zfs_get_objid()
24927 {
24928         local ost=$1
24929         local tf=$2
24930         local fid=($($LFS getstripe $tf | grep 0x))
24931         local seq=${fid[3]#0x}
24932         local objid=${fid[1]}
24933
24934         local vdevdir=$(dirname $(facet_vdevice $ost))
24935         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24936         local zfs_zapid=$(do_facet $ost $cmd |
24937                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24938                           awk '/Object/{getline; print $1}')
24939         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24940                           awk "/$objid = /"'{printf $3}')
24941
24942         echo $zfs_objid
24943 }
24944
24945 zfs_object_blksz() {
24946         local ost=$1
24947         local objid=$2
24948
24949         local vdevdir=$(dirname $(facet_vdevice $ost))
24950         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24951         local blksz=$(do_facet $ost $cmd $objid |
24952                       awk '/dblk/{getline; printf $4}')
24953
24954         case "${blksz: -1}" in
24955                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24956                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24957                 *) ;;
24958         esac
24959
24960         echo $blksz
24961 }
24962
24963 test_312() { # LU-4856
24964         remote_ost_nodsh && skip "remote OST with nodsh"
24965         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
24966
24967         local max_blksz=$(do_facet ost1 \
24968                           $ZFS get -p recordsize $(facet_device ost1) |
24969                           awk '!/VALUE/{print $3}')
24970         local tf=$DIR/$tfile
24971
24972         $LFS setstripe -c1 $tf
24973         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
24974
24975         # Get ZFS object id
24976         local zfs_objid=$(zfs_get_objid $facet $tf)
24977         # block size change by sequential overwrite
24978         local bs
24979
24980         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24981                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24982
24983                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
24984                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
24985         done
24986         rm -f $tf
24987
24988         $LFS setstripe -c1 $tf
24989         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24990
24991         # block size change by sequential append write
24992         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24993         zfs_objid=$(zfs_get_objid $facet $tf)
24994         local count
24995
24996         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24997                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24998                         oflag=sync conv=notrunc
24999
25000                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25001                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25002                         error "blksz error, actual $blksz, " \
25003                                 "expected: 2 * $count * $PAGE_SIZE"
25004         done
25005         rm -f $tf
25006
25007         # random write
25008         $LFS setstripe -c1 $tf
25009         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25010         zfs_objid=$(zfs_get_objid $facet $tf)
25011
25012         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25013         blksz=$(zfs_object_blksz $facet $zfs_objid)
25014         (( blksz == PAGE_SIZE )) ||
25015                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25016
25017         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25018         blksz=$(zfs_object_blksz $facet $zfs_objid)
25019         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25020
25021         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25022         blksz=$(zfs_object_blksz $facet $zfs_objid)
25023         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25024 }
25025 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25026
25027 test_313() {
25028         remote_ost_nodsh && skip "remote OST with nodsh"
25029
25030         local file=$DIR/$tfile
25031
25032         rm -f $file
25033         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25034
25035         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25036         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25037         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25038                 error "write should failed"
25039         do_facet ost1 "$LCTL set_param fail_loc=0"
25040         rm -f $file
25041 }
25042 run_test 313 "io should fail after last_rcvd update fail"
25043
25044 test_314() {
25045         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25046
25047         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25048         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25049         rm -f $DIR/$tfile
25050         wait_delete_completed
25051         do_facet ost1 "$LCTL set_param fail_loc=0"
25052 }
25053 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25054
25055 test_315() { # LU-618
25056         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25057
25058         local file=$DIR/$tfile
25059         rm -f $file
25060
25061         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25062                 error "multiop file write failed"
25063         $MULTIOP $file oO_RDONLY:r4063232_c &
25064         PID=$!
25065
25066         sleep 2
25067
25068         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25069         kill -USR1 $PID
25070
25071         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25072         rm -f $file
25073 }
25074 run_test 315 "read should be accounted"
25075
25076 test_316() {
25077         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25078         large_xattr_enabled || skip "ea_inode feature disabled"
25079
25080         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25081         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25082         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25083         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25084
25085         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25086 }
25087 run_test 316 "lfs migrate of file with large_xattr enabled"
25088
25089 test_317() {
25090         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25091                 skip "Need MDS version at least 2.11.53"
25092         if [ "$ost1_FSTYPE" == "zfs" ]; then
25093                 skip "LU-10370: no implementation for ZFS"
25094         fi
25095
25096         local trunc_sz
25097         local grant_blk_size
25098
25099         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25100                         awk '/grant_block_size:/ { print $2; exit; }')
25101         #
25102         # Create File of size 5M. Truncate it to below size's and verify
25103         # blocks count.
25104         #
25105         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25106                 error "Create file $DIR/$tfile failed"
25107         stack_trap "rm -f $DIR/$tfile" EXIT
25108
25109         for trunc_sz in 2097152 4097 4000 509 0; do
25110                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25111                         error "truncate $tfile to $trunc_sz failed"
25112                 local sz=$(stat --format=%s $DIR/$tfile)
25113                 local blk=$(stat --format=%b $DIR/$tfile)
25114                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25115                                      grant_blk_size) * 8))
25116
25117                 if [[ $blk -ne $trunc_blk ]]; then
25118                         $(which stat) $DIR/$tfile
25119                         error "Expected Block $trunc_blk got $blk for $tfile"
25120                 fi
25121
25122                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25123                         error "Expected Size $trunc_sz got $sz for $tfile"
25124         done
25125
25126         #
25127         # sparse file test
25128         # Create file with a hole and write actual 65536 bytes which aligned
25129         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25130         #
25131         local bs=65536
25132         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25133                 error "Create file : $DIR/$tfile"
25134
25135         #
25136         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25137         # blocks. The block count must drop to 8.
25138         #
25139         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25140                 ((bs - grant_blk_size) + 1)))
25141         $TRUNCATE $DIR/$tfile $trunc_sz ||
25142                 error "truncate $tfile to $trunc_sz failed"
25143
25144         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25145         sz=$(stat --format=%s $DIR/$tfile)
25146         blk=$(stat --format=%b $DIR/$tfile)
25147
25148         if [[ $blk -ne $trunc_bsz ]]; then
25149                 $(which stat) $DIR/$tfile
25150                 error "Expected Block $trunc_bsz got $blk for $tfile"
25151         fi
25152
25153         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25154                 error "Expected Size $trunc_sz got $sz for $tfile"
25155 }
25156 run_test 317 "Verify blocks get correctly update after truncate"
25157
25158 test_318() {
25159         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25160         local old_max_active=$($LCTL get_param -n \
25161                             ${llite_name}.max_read_ahead_async_active \
25162                             2>/dev/null)
25163
25164         $LCTL set_param llite.*.max_read_ahead_async_active=256
25165         local max_active=$($LCTL get_param -n \
25166                            ${llite_name}.max_read_ahead_async_active \
25167                            2>/dev/null)
25168         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25169
25170         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25171                 error "set max_read_ahead_async_active should succeed"
25172
25173         $LCTL set_param llite.*.max_read_ahead_async_active=512
25174         max_active=$($LCTL get_param -n \
25175                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25176         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25177
25178         # restore @max_active
25179         [ $old_max_active -ne 0 ] && $LCTL set_param \
25180                 llite.*.max_read_ahead_async_active=$old_max_active
25181
25182         local old_threshold=$($LCTL get_param -n \
25183                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25184         local max_per_file_mb=$($LCTL get_param -n \
25185                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25186
25187         local invalid=$(($max_per_file_mb + 1))
25188         $LCTL set_param \
25189                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25190                         && error "set $invalid should fail"
25191
25192         local valid=$(($invalid - 1))
25193         $LCTL set_param \
25194                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25195                         error "set $valid should succeed"
25196         local threshold=$($LCTL get_param -n \
25197                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25198         [ $threshold -eq $valid ] || error \
25199                 "expect threshold $valid got $threshold"
25200         $LCTL set_param \
25201                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25202 }
25203 run_test 318 "Verify async readahead tunables"
25204
25205 test_319() {
25206         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25207
25208         local before=$(date +%s)
25209         local evict
25210         local mdir=$DIR/$tdir
25211         local file=$mdir/xxx
25212
25213         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25214         touch $file
25215
25216 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25217         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25218         $LFS migrate -m1 $mdir &
25219
25220         sleep 1
25221         dd if=$file of=/dev/null
25222         wait
25223         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25224           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25225
25226         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25227 }
25228 run_test 319 "lost lease lock on migrate error"
25229
25230 test_398a() { # LU-4198
25231         local ost1_imp=$(get_osc_import_name client ost1)
25232         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25233                          cut -d'.' -f2)
25234
25235         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25236         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25237
25238         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25239         # request a new lock on client
25240         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25241
25242         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25243         #local lock_count=$($LCTL get_param -n \
25244         #                  ldlm.namespaces.$imp_name.lru_size)
25245         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25246
25247         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25248
25249         # no lock cached, should use lockless DIO and not enqueue new lock
25250         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25251                 conv=notrunc ||
25252                 error "dio write failed"
25253         lock_count=$($LCTL get_param -n \
25254                      ldlm.namespaces.$imp_name.lru_size)
25255         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25256
25257         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25258
25259         # no lock cached, should use locked DIO append
25260         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25261                 conv=notrunc || error "DIO append failed"
25262         lock_count=$($LCTL get_param -n \
25263                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25264         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25265 }
25266 run_test 398a "direct IO should cancel lock otherwise lockless"
25267
25268 test_398b() { # LU-4198
25269         local before=$(date +%s)
25270         local njobs=4
25271         local size=48
25272
25273         which fio || skip_env "no fio installed"
25274         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25275         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25276
25277         # Single page, multiple pages, stripe size, 4*stripe size
25278         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25279                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25280                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25281                         --numjobs=$njobs --fallocate=none \
25282                         --iodepth=16 --allow_file_create=0 \
25283                         --size=$((size/njobs))M \
25284                         --filename=$DIR/$tfile &
25285                 bg_pid=$!
25286
25287                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25288                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25289                         --numjobs=$njobs --fallocate=none \
25290                         --iodepth=16 --allow_file_create=0 \
25291                         --size=$((size/njobs))M \
25292                         --filename=$DIR/$tfile || true
25293                 wait $bg_pid
25294         done
25295
25296         evict=$(do_facet client $LCTL get_param \
25297                 osc.$FSNAME-OST*-osc-*/state |
25298             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25299
25300         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25301                 (do_facet client $LCTL get_param \
25302                         osc.$FSNAME-OST*-osc-*/state;
25303                     error "eviction happened: $evict before:$before")
25304
25305         rm -f $DIR/$tfile
25306 }
25307 run_test 398b "DIO and buffer IO race"
25308
25309 test_398c() { # LU-4198
25310         local ost1_imp=$(get_osc_import_name client ost1)
25311         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25312                          cut -d'.' -f2)
25313
25314         which fio || skip_env "no fio installed"
25315
25316         saved_debug=$($LCTL get_param -n debug)
25317         $LCTL set_param debug=0
25318
25319         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25320         ((size /= 1024)) # by megabytes
25321         ((size /= 2)) # write half of the OST at most
25322         [ $size -gt 40 ] && size=40 #reduce test time anyway
25323
25324         $LFS setstripe -c 1 $DIR/$tfile
25325
25326         # it seems like ldiskfs reserves more space than necessary if the
25327         # writing blocks are not mapped, so it extends the file firstly
25328         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25329         cancel_lru_locks osc
25330
25331         # clear and verify rpc_stats later
25332         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25333
25334         local njobs=4
25335         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25336         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25337                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25338                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25339                 --filename=$DIR/$tfile
25340         [ $? -eq 0 ] || error "fio write error"
25341
25342         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25343                 error "Locks were requested while doing AIO"
25344
25345         # get the percentage of 1-page I/O
25346         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25347                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25348                 awk '{print $7}')
25349         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25350
25351         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25352         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25353                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25354                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25355                 --filename=$DIR/$tfile
25356         [ $? -eq 0 ] || error "fio mixed read write error"
25357
25358         echo "AIO with large block size ${size}M"
25359         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25360                 --numjobs=1 --fallocate=none --ioengine=libaio \
25361                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25362                 --filename=$DIR/$tfile
25363         [ $? -eq 0 ] || error "fio large block size failed"
25364
25365         rm -f $DIR/$tfile
25366         $LCTL set_param debug="$saved_debug"
25367 }
25368 run_test 398c "run fio to test AIO"
25369
25370 test_398d() { #  LU-13846
25371         which aiocp || skip_env "no aiocp installed"
25372         local aio_file=$DIR/$tfile.aio
25373
25374         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25375
25376         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25377         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25378         stack_trap "rm -f $DIR/$tfile $aio_file"
25379
25380         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25381
25382         # make sure we don't crash and fail properly
25383         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25384                 error "aio not aligned with PAGE SIZE should fail"
25385
25386         rm -f $DIR/$tfile $aio_file
25387 }
25388 run_test 398d "run aiocp to verify block size > stripe size"
25389
25390 test_398e() {
25391         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25392         touch $DIR/$tfile.new
25393         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25394 }
25395 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25396
25397 test_398f() { #  LU-14687
25398         which aiocp || skip_env "no aiocp installed"
25399         local aio_file=$DIR/$tfile.aio
25400
25401         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25402
25403         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25404         stack_trap "rm -f $DIR/$tfile $aio_file"
25405
25406         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25407         $LCTL set_param fail_loc=0x1418
25408         # make sure we don't crash and fail properly
25409         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25410                 error "aio with page allocation failure succeeded"
25411         $LCTL set_param fail_loc=0
25412         diff $DIR/$tfile $aio_file
25413         [[ $? != 0 ]] || error "no diff after failed aiocp"
25414 }
25415 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25416
25417 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25418 # stripe and i/o size must be > stripe size
25419 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25420 # single RPC in flight.  This test shows async DIO submission is working by
25421 # showing multiple RPCs in flight.
25422 test_398g() { #  LU-13798
25423         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25424
25425         # We need to do some i/o first to acquire enough grant to put our RPCs
25426         # in flight; otherwise a new connection may not have enough grant
25427         # available
25428         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25429                 error "parallel dio failed"
25430         stack_trap "rm -f $DIR/$tfile"
25431
25432         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25433         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25434         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25435         stack_trap "$LCTL set_param -n $pages_per_rpc"
25436
25437         # Recreate file so it's empty
25438         rm -f $DIR/$tfile
25439         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25440         #Pause rpc completion to guarantee we see multiple rpcs in flight
25441         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25442         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25443         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25444
25445         # Clear rpc stats
25446         $LCTL set_param osc.*.rpc_stats=c
25447
25448         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25449                 error "parallel dio failed"
25450         stack_trap "rm -f $DIR/$tfile"
25451
25452         $LCTL get_param osc.*-OST0000-*.rpc_stats
25453         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25454                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25455                 grep "8:" | awk '{print $8}')
25456         # We look at the "8 rpcs in flight" field, and verify A) it is present
25457         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25458         # as expected for an 8M DIO to a file with 1M stripes.
25459         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25460
25461         # Verify turning off parallel dio works as expected
25462         # Clear rpc stats
25463         $LCTL set_param osc.*.rpc_stats=c
25464         $LCTL set_param llite.*.parallel_dio=0
25465         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25466
25467         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25468                 error "dio with parallel dio disabled failed"
25469
25470         # Ideally, we would see only one RPC in flight here, but there is an
25471         # unavoidable race between i/o completion and RPC in flight counting,
25472         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25473         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25474         # So instead we just verify it's always < 8.
25475         $LCTL get_param osc.*-OST0000-*.rpc_stats
25476         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25477                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25478                 grep '^$' -B1 | grep . | awk '{print $1}')
25479         [ $ret != "8:" ] ||
25480                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25481 }
25482 run_test 398g "verify parallel dio async RPC submission"
25483
25484 test_398h() { #  LU-13798
25485         local dio_file=$DIR/$tfile.dio
25486
25487         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25488
25489         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25490         stack_trap "rm -f $DIR/$tfile $dio_file"
25491
25492         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25493                 error "parallel dio failed"
25494         diff $DIR/$tfile $dio_file
25495         [[ $? == 0 ]] || error "file diff after aiocp"
25496 }
25497 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25498
25499 test_398i() { #  LU-13798
25500         local dio_file=$DIR/$tfile.dio
25501
25502         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25503
25504         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25505         stack_trap "rm -f $DIR/$tfile $dio_file"
25506
25507         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25508         $LCTL set_param fail_loc=0x1418
25509         # make sure we don't crash and fail properly
25510         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25511                 error "parallel dio page allocation failure succeeded"
25512         diff $DIR/$tfile $dio_file
25513         [[ $? != 0 ]] || error "no diff after failed aiocp"
25514 }
25515 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25516
25517 test_398j() { #  LU-13798
25518         # Stripe size > RPC size but less than i/o size tests split across
25519         # stripes and RPCs for individual i/o op
25520         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25521
25522         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25523         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25524         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25525         stack_trap "$LCTL set_param -n $pages_per_rpc"
25526
25527         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25528                 error "parallel dio write failed"
25529         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25530
25531         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25532                 error "parallel dio read failed"
25533         diff $DIR/$tfile $DIR/$tfile.2
25534         [[ $? == 0 ]] || error "file diff after parallel dio read"
25535 }
25536 run_test 398j "test parallel dio where stripe size > rpc_size"
25537
25538 test_398k() { #  LU-13798
25539         wait_delete_completed
25540         wait_mds_ost_sync
25541
25542         # 4 stripe file; we will cause out of space on OST0
25543         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25544
25545         # Fill OST0 (if it's not too large)
25546         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25547                    head -n1)
25548         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25549                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25550         fi
25551         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25552         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25553                 error "dd should fill OST0"
25554         stack_trap "rm -f $DIR/$tfile.1"
25555
25556         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25557         err=$?
25558
25559         ls -la $DIR/$tfile
25560         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25561                 error "file is not 0 bytes in size"
25562
25563         # dd above should not succeed, but don't error until here so we can
25564         # get debug info above
25565         [[ $err != 0 ]] ||
25566                 error "parallel dio write with enospc succeeded"
25567         stack_trap "rm -f $DIR/$tfile"
25568 }
25569 run_test 398k "test enospc on first stripe"
25570
25571 test_398l() { #  LU-13798
25572         wait_delete_completed
25573         wait_mds_ost_sync
25574
25575         # 4 stripe file; we will cause out of space on OST0
25576         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25577         # happens on the second i/o chunk we issue
25578         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25579
25580         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25581         stack_trap "rm -f $DIR/$tfile"
25582
25583         # Fill OST0 (if it's not too large)
25584         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25585                    head -n1)
25586         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25587                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25588         fi
25589         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25590         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25591                 error "dd should fill OST0"
25592         stack_trap "rm -f $DIR/$tfile.1"
25593
25594         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25595         err=$?
25596         stack_trap "rm -f $DIR/$tfile.2"
25597
25598         # Check that short write completed as expected
25599         ls -la $DIR/$tfile.2
25600         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25601                 error "file is not 1M in size"
25602
25603         # dd above should not succeed, but don't error until here so we can
25604         # get debug info above
25605         [[ $err != 0 ]] ||
25606                 error "parallel dio write with enospc succeeded"
25607
25608         # Truncate source file to same length as output file and diff them
25609         $TRUNCATE $DIR/$tfile 1048576
25610         diff $DIR/$tfile $DIR/$tfile.2
25611         [[ $? == 0 ]] || error "data incorrect after short write"
25612 }
25613 run_test 398l "test enospc on intermediate stripe/RPC"
25614
25615 test_398m() { #  LU-13798
25616         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25617
25618         # Set up failure on OST0, the first stripe:
25619         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25620         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25621         # OST0 is on ost1, OST1 is on ost2.
25622         # So this fail_val specifies OST0
25623         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25624         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25625
25626         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25627                 error "parallel dio write with failure on first stripe succeeded"
25628         stack_trap "rm -f $DIR/$tfile"
25629         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25630
25631         # Place data in file for read
25632         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25633                 error "parallel dio write failed"
25634
25635         # Fail read on OST0, first stripe
25636         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25637         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25638         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25639                 error "parallel dio read with error on first stripe succeeded"
25640         rm -f $DIR/$tfile.2
25641         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25642
25643         # Switch to testing on OST1, second stripe
25644         # Clear file contents, maintain striping
25645         echo > $DIR/$tfile
25646         # Set up failure on OST1, second stripe:
25647         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25648         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25649
25650         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25651                 error "parallel dio write with failure on second stripe succeeded"
25652         stack_trap "rm -f $DIR/$tfile"
25653         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25654
25655         # Place data in file for read
25656         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25657                 error "parallel dio write failed"
25658
25659         # Fail read on OST1, second stripe
25660         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25661         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25662         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25663                 error "parallel dio read with error on second stripe succeeded"
25664         rm -f $DIR/$tfile.2
25665         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25666 }
25667 run_test 398m "test RPC failures with parallel dio"
25668
25669 # Parallel submission of DIO should not cause problems for append, but it's
25670 # important to verify.
25671 test_398n() { #  LU-13798
25672         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25673
25674         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25675                 error "dd to create source file failed"
25676         stack_trap "rm -f $DIR/$tfile"
25677
25678         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25679                 error "parallel dio write with failure on second stripe succeeded"
25680         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25681         diff $DIR/$tfile $DIR/$tfile.1
25682         [[ $? == 0 ]] || error "data incorrect after append"
25683
25684 }
25685 run_test 398n "test append with parallel DIO"
25686
25687 test_398o() {
25688         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25689 }
25690 run_test 398o "right kms with DIO"
25691
25692 test_fake_rw() {
25693         local read_write=$1
25694         if [ "$read_write" = "write" ]; then
25695                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25696         elif [ "$read_write" = "read" ]; then
25697                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25698         else
25699                 error "argument error"
25700         fi
25701
25702         # turn off debug for performance testing
25703         local saved_debug=$($LCTL get_param -n debug)
25704         $LCTL set_param debug=0
25705
25706         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25707
25708         # get ost1 size - $FSNAME-OST0000
25709         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25710         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25711         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25712
25713         if [ "$read_write" = "read" ]; then
25714                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25715         fi
25716
25717         local start_time=$(date +%s.%N)
25718         $dd_cmd bs=1M count=$blocks oflag=sync ||
25719                 error "real dd $read_write error"
25720         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25721
25722         if [ "$read_write" = "write" ]; then
25723                 rm -f $DIR/$tfile
25724         fi
25725
25726         # define OBD_FAIL_OST_FAKE_RW           0x238
25727         do_facet ost1 $LCTL set_param fail_loc=0x238
25728
25729         local start_time=$(date +%s.%N)
25730         $dd_cmd bs=1M count=$blocks oflag=sync ||
25731                 error "fake dd $read_write error"
25732         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25733
25734         if [ "$read_write" = "write" ]; then
25735                 # verify file size
25736                 cancel_lru_locks osc
25737                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25738                         error "$tfile size not $blocks MB"
25739         fi
25740         do_facet ost1 $LCTL set_param fail_loc=0
25741
25742         echo "fake $read_write $duration_fake vs. normal $read_write" \
25743                 "$duration in seconds"
25744         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25745                 error_not_in_vm "fake write is slower"
25746
25747         $LCTL set_param -n debug="$saved_debug"
25748         rm -f $DIR/$tfile
25749 }
25750 test_399a() { # LU-7655 for OST fake write
25751         remote_ost_nodsh && skip "remote OST with nodsh"
25752
25753         test_fake_rw write
25754 }
25755 run_test 399a "fake write should not be slower than normal write"
25756
25757 test_399b() { # LU-8726 for OST fake read
25758         remote_ost_nodsh && skip "remote OST with nodsh"
25759         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25760                 skip_env "ldiskfs only test"
25761         fi
25762
25763         test_fake_rw read
25764 }
25765 run_test 399b "fake read should not be slower than normal read"
25766
25767 test_400a() { # LU-1606, was conf-sanity test_74
25768         if ! which $CC > /dev/null 2>&1; then
25769                 skip_env "$CC is not installed"
25770         fi
25771
25772         local extra_flags=''
25773         local out=$TMP/$tfile
25774         local prefix=/usr/include/lustre
25775         local prog
25776
25777         # Oleg removes .c files in his test rig so test if any c files exist
25778         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25779                 skip_env "Needed .c test files are missing"
25780
25781         if ! [[ -d $prefix ]]; then
25782                 # Assume we're running in tree and fixup the include path.
25783                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25784                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25785                 extra_flags+=" -L$LUSTRE/utils/.libs"
25786         fi
25787
25788         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25789                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25790                         error "client api broken"
25791         done
25792         rm -f $out
25793 }
25794 run_test 400a "Lustre client api program can compile and link"
25795
25796 test_400b() { # LU-1606, LU-5011
25797         local header
25798         local out=$TMP/$tfile
25799         local prefix=/usr/include/linux/lustre
25800
25801         # We use a hard coded prefix so that this test will not fail
25802         # when run in tree. There are headers in lustre/include/lustre/
25803         # that are not packaged (like lustre_idl.h) and have more
25804         # complicated include dependencies (like config.h and lnet/types.h).
25805         # Since this test about correct packaging we just skip them when
25806         # they don't exist (see below) rather than try to fixup cppflags.
25807
25808         if ! which $CC > /dev/null 2>&1; then
25809                 skip_env "$CC is not installed"
25810         fi
25811
25812         for header in $prefix/*.h; do
25813                 if ! [[ -f "$header" ]]; then
25814                         continue
25815                 fi
25816
25817                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25818                         continue # lustre_ioctl.h is internal header
25819                 fi
25820
25821                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25822                         error "cannot compile '$header'"
25823         done
25824         rm -f $out
25825 }
25826 run_test 400b "packaged headers can be compiled"
25827
25828 test_401a() { #LU-7437
25829         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25830         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25831
25832         #count the number of parameters by "list_param -R"
25833         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25834         #count the number of parameters by listing proc files
25835         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25836         echo "proc_dirs='$proc_dirs'"
25837         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25838         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25839                       sort -u | wc -l)
25840
25841         [ $params -eq $procs ] ||
25842                 error "found $params parameters vs. $procs proc files"
25843
25844         # test the list_param -D option only returns directories
25845         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25846         #count the number of parameters by listing proc directories
25847         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25848                 sort -u | wc -l)
25849
25850         [ $params -eq $procs ] ||
25851                 error "found $params parameters vs. $procs proc files"
25852 }
25853 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25854
25855 test_401b() {
25856         # jobid_var may not allow arbitrary values, so use jobid_name
25857         # if available
25858         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25859                 local testname=jobid_name tmp='testing%p'
25860         else
25861                 local testname=jobid_var tmp=testing
25862         fi
25863
25864         local save=$($LCTL get_param -n $testname)
25865
25866         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25867                 error "no error returned when setting bad parameters"
25868
25869         local jobid_new=$($LCTL get_param -n foe $testname baz)
25870         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25871
25872         $LCTL set_param -n fog=bam $testname=$save bat=fog
25873         local jobid_old=$($LCTL get_param -n foe $testname bag)
25874         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25875 }
25876 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25877
25878 test_401c() {
25879         # jobid_var may not allow arbitrary values, so use jobid_name
25880         # if available
25881         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25882                 local testname=jobid_name
25883         else
25884                 local testname=jobid_var
25885         fi
25886
25887         local jobid_var_old=$($LCTL get_param -n $testname)
25888         local jobid_var_new
25889
25890         $LCTL set_param $testname= &&
25891                 error "no error returned for 'set_param a='"
25892
25893         jobid_var_new=$($LCTL get_param -n $testname)
25894         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25895                 error "$testname was changed by setting without value"
25896
25897         $LCTL set_param $testname &&
25898                 error "no error returned for 'set_param a'"
25899
25900         jobid_var_new=$($LCTL get_param -n $testname)
25901         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25902                 error "$testname was changed by setting without value"
25903 }
25904 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25905
25906 test_401d() {
25907         # jobid_var may not allow arbitrary values, so use jobid_name
25908         # if available
25909         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25910                 local testname=jobid_name new_value='foo=bar%p'
25911         else
25912                 local testname=jobid_var new_valuie=foo=bar
25913         fi
25914
25915         local jobid_var_old=$($LCTL get_param -n $testname)
25916         local jobid_var_new
25917
25918         $LCTL set_param $testname=$new_value ||
25919                 error "'set_param a=b' did not accept a value containing '='"
25920
25921         jobid_var_new=$($LCTL get_param -n $testname)
25922         [[ "$jobid_var_new" == "$new_value" ]] ||
25923                 error "'set_param a=b' failed on a value containing '='"
25924
25925         # Reset the $testname to test the other format
25926         $LCTL set_param $testname=$jobid_var_old
25927         jobid_var_new=$($LCTL get_param -n $testname)
25928         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25929                 error "failed to reset $testname"
25930
25931         $LCTL set_param $testname $new_value ||
25932                 error "'set_param a b' did not accept a value containing '='"
25933
25934         jobid_var_new=$($LCTL get_param -n $testname)
25935         [[ "$jobid_var_new" == "$new_value" ]] ||
25936                 error "'set_param a b' failed on a value containing '='"
25937
25938         $LCTL set_param $testname $jobid_var_old
25939         jobid_var_new=$($LCTL get_param -n $testname)
25940         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25941                 error "failed to reset $testname"
25942 }
25943 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25944
25945 test_401e() { # LU-14779
25946         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25947                 error "lctl list_param MGC* failed"
25948         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25949         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25950                 error "lctl get_param lru_size failed"
25951 }
25952 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25953
25954 test_402() {
25955         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25956         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25957                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25958         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25959                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25960                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25961         remote_mds_nodsh && skip "remote MDS with nodsh"
25962
25963         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25964 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25965         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25966         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25967                 echo "Touch failed - OK"
25968 }
25969 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25970
25971 test_403() {
25972         local file1=$DIR/$tfile.1
25973         local file2=$DIR/$tfile.2
25974         local tfile=$TMP/$tfile
25975
25976         rm -f $file1 $file2 $tfile
25977
25978         touch $file1
25979         ln $file1 $file2
25980
25981         # 30 sec OBD_TIMEOUT in ll_getattr()
25982         # right before populating st_nlink
25983         $LCTL set_param fail_loc=0x80001409
25984         stat -c %h $file1 > $tfile &
25985
25986         # create an alias, drop all locks and reclaim the dentry
25987         < $file2
25988         cancel_lru_locks mdc
25989         cancel_lru_locks osc
25990         sysctl -w vm.drop_caches=2
25991
25992         wait
25993
25994         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25995
25996         rm -f $tfile $file1 $file2
25997 }
25998 run_test 403 "i_nlink should not drop to zero due to aliasing"
25999
26000 test_404() { # LU-6601
26001         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26002                 skip "Need server version newer than 2.8.52"
26003         remote_mds_nodsh && skip "remote MDS with nodsh"
26004
26005         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26006                 awk '/osp .*-osc-MDT/ { print $4}')
26007
26008         local osp
26009         for osp in $mosps; do
26010                 echo "Deactivate: " $osp
26011                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26012                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26013                         awk -vp=$osp '$4 == p { print $2 }')
26014                 [ $stat = IN ] || {
26015                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26016                         error "deactivate error"
26017                 }
26018                 echo "Activate: " $osp
26019                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26020                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26021                         awk -vp=$osp '$4 == p { print $2 }')
26022                 [ $stat = UP ] || {
26023                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26024                         error "activate error"
26025                 }
26026         done
26027 }
26028 run_test 404 "validate manual {de}activated works properly for OSPs"
26029
26030 test_405() {
26031         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26032         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26033                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26034                         skip "Layout swap lock is not supported"
26035
26036         check_swap_layouts_support
26037         check_swap_layout_no_dom $DIR
26038
26039         test_mkdir $DIR/$tdir
26040         swap_lock_test -d $DIR/$tdir ||
26041                 error "One layout swap locked test failed"
26042 }
26043 run_test 405 "Various layout swap lock tests"
26044
26045 test_406() {
26046         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26047         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26048         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26050         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26051                 skip "Need MDS version at least 2.8.50"
26052
26053         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26054         local test_pool=$TESTNAME
26055
26056         pool_add $test_pool || error "pool_add failed"
26057         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26058                 error "pool_add_targets failed"
26059
26060         save_layout_restore_at_exit $MOUNT
26061
26062         # parent set default stripe count only, child will stripe from both
26063         # parent and fs default
26064         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26065                 error "setstripe $MOUNT failed"
26066         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26067         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26068         for i in $(seq 10); do
26069                 local f=$DIR/$tdir/$tfile.$i
26070                 touch $f || error "touch failed"
26071                 local count=$($LFS getstripe -c $f)
26072                 [ $count -eq $OSTCOUNT ] ||
26073                         error "$f stripe count $count != $OSTCOUNT"
26074                 local offset=$($LFS getstripe -i $f)
26075                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26076                 local size=$($LFS getstripe -S $f)
26077                 [ $size -eq $((def_stripe_size * 2)) ] ||
26078                         error "$f stripe size $size != $((def_stripe_size * 2))"
26079                 local pool=$($LFS getstripe -p $f)
26080                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26081         done
26082
26083         # change fs default striping, delete parent default striping, now child
26084         # will stripe from new fs default striping only
26085         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26086                 error "change $MOUNT default stripe failed"
26087         $LFS setstripe -c 0 $DIR/$tdir ||
26088                 error "delete $tdir default stripe failed"
26089         for i in $(seq 11 20); do
26090                 local f=$DIR/$tdir/$tfile.$i
26091                 touch $f || error "touch $f failed"
26092                 local count=$($LFS getstripe -c $f)
26093                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26094                 local offset=$($LFS getstripe -i $f)
26095                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26096                 local size=$($LFS getstripe -S $f)
26097                 [ $size -eq $def_stripe_size ] ||
26098                         error "$f stripe size $size != $def_stripe_size"
26099                 local pool=$($LFS getstripe -p $f)
26100                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26101         done
26102
26103         unlinkmany $DIR/$tdir/$tfile. 1 20
26104
26105         local f=$DIR/$tdir/$tfile
26106         pool_remove_all_targets $test_pool $f
26107         pool_remove $test_pool $f
26108 }
26109 run_test 406 "DNE support fs default striping"
26110
26111 test_407() {
26112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26113         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26114                 skip "Need MDS version at least 2.8.55"
26115         remote_mds_nodsh && skip "remote MDS with nodsh"
26116
26117         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26118                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26119         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26120                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26121         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26122
26123         #define OBD_FAIL_DT_TXN_STOP    0x2019
26124         for idx in $(seq $MDSCOUNT); do
26125                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26126         done
26127         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26128         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26129                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26130         true
26131 }
26132 run_test 407 "transaction fail should cause operation fail"
26133
26134 test_408() {
26135         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26136
26137         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26138         lctl set_param fail_loc=0x8000040a
26139         # let ll_prepare_partial_page() fail
26140         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26141
26142         rm -f $DIR/$tfile
26143
26144         # create at least 100 unused inodes so that
26145         # shrink_icache_memory(0) should not return 0
26146         touch $DIR/$tfile-{0..100}
26147         rm -f $DIR/$tfile-{0..100}
26148         sync
26149
26150         echo 2 > /proc/sys/vm/drop_caches
26151 }
26152 run_test 408 "drop_caches should not hang due to page leaks"
26153
26154 test_409()
26155 {
26156         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26157
26158         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26159         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26160         touch $DIR/$tdir/guard || error "(2) Fail to create"
26161
26162         local PREFIX=$(str_repeat 'A' 128)
26163         echo "Create 1K hard links start at $(date)"
26164         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26165                 error "(3) Fail to hard link"
26166
26167         echo "Links count should be right although linkEA overflow"
26168         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26169         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26170         [ $linkcount -eq 1001 ] ||
26171                 error "(5) Unexpected hard links count: $linkcount"
26172
26173         echo "List all links start at $(date)"
26174         ls -l $DIR/$tdir/foo > /dev/null ||
26175                 error "(6) Fail to list $DIR/$tdir/foo"
26176
26177         echo "Unlink hard links start at $(date)"
26178         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26179                 error "(7) Fail to unlink"
26180         echo "Unlink hard links finished at $(date)"
26181 }
26182 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26183
26184 test_410()
26185 {
26186         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26187                 skip "Need client version at least 2.9.59"
26188         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26189                 skip "Need MODULES build"
26190
26191         # Create a file, and stat it from the kernel
26192         local testfile=$DIR/$tfile
26193         touch $testfile
26194
26195         local run_id=$RANDOM
26196         local my_ino=$(stat --format "%i" $testfile)
26197
26198         # Try to insert the module. This will always fail as the
26199         # module is designed to not be inserted.
26200         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26201             &> /dev/null
26202
26203         # Anything but success is a test failure
26204         dmesg | grep -q \
26205             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26206             error "no inode match"
26207 }
26208 run_test 410 "Test inode number returned from kernel thread"
26209
26210 cleanup_test411_cgroup() {
26211         trap 0
26212         rmdir "$1"
26213 }
26214
26215 test_411() {
26216         local cg_basedir=/sys/fs/cgroup/memory
26217         # LU-9966
26218         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26219                 skip "no setup for cgroup"
26220
26221         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26222                 error "test file creation failed"
26223         cancel_lru_locks osc
26224
26225         # Create a very small memory cgroup to force a slab allocation error
26226         local cgdir=$cg_basedir/osc_slab_alloc
26227         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26228         trap "cleanup_test411_cgroup $cgdir" EXIT
26229         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26230         echo 1M > $cgdir/memory.limit_in_bytes
26231
26232         # Should not LBUG, just be killed by oom-killer
26233         # dd will return 0 even allocation failure in some environment.
26234         # So don't check return value
26235         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26236         cleanup_test411_cgroup $cgdir
26237
26238         return 0
26239 }
26240 run_test 411 "Slab allocation error with cgroup does not LBUG"
26241
26242 test_412() {
26243         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26244         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26245                 skip "Need server version at least 2.10.55"
26246
26247         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26248                 error "mkdir failed"
26249         $LFS getdirstripe $DIR/$tdir
26250         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26251         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26252                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26253         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26254         [ $stripe_count -eq 2 ] ||
26255                 error "expect 2 get $stripe_count"
26256
26257         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26258
26259         local index
26260         local index2
26261
26262         # subdirs should be on the same MDT as parent
26263         for i in $(seq 0 $((MDSCOUNT - 1))); do
26264                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26265                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26266                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26267                 (( index == i )) || error "mdt$i/sub on MDT$index"
26268         done
26269
26270         # stripe offset -1, ditto
26271         for i in {1..10}; do
26272                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26273                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26274                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26275                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26276                 (( index == index2 )) ||
26277                         error "qos$i on MDT$index, sub on MDT$index2"
26278         done
26279
26280         local testdir=$DIR/$tdir/inherit
26281
26282         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26283         # inherit 2 levels
26284         for i in 1 2; do
26285                 testdir=$testdir/s$i
26286                 mkdir $testdir || error "mkdir $testdir failed"
26287                 index=$($LFS getstripe -m $testdir)
26288                 (( index == 1 )) ||
26289                         error "$testdir on MDT$index"
26290         done
26291
26292         # not inherit any more
26293         testdir=$testdir/s3
26294         mkdir $testdir || error "mkdir $testdir failed"
26295         getfattr -d -m dmv $testdir | grep dmv &&
26296                 error "default LMV set on $testdir" || true
26297 }
26298 run_test 412 "mkdir on specific MDTs"
26299
26300 TEST413_COUNT=${TEST413_COUNT:-200}
26301 generate_uneven_mdts() {
26302         local threshold=$1
26303         local lmv_qos_maxage
26304         local lod_qos_maxage
26305         local ffree
26306         local bavail
26307         local max
26308         local min
26309         local max_index
26310         local min_index
26311         local tmp
26312         local i
26313
26314         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26315         $LCTL set_param lmv.*.qos_maxage=1
26316         stack_trap "$LCTL set_param \
26317                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26318         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26319                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26320         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26321                 lod.*.mdt_qos_maxage=1
26322         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26323                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26324
26325         echo
26326         echo "Check for uneven MDTs: "
26327
26328         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26329         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26330         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26331
26332         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26333         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26334         max_index=0
26335         min_index=0
26336         for ((i = 1; i < ${#ffree[@]}; i++)); do
26337                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26338                 if [ $tmp -gt $max ]; then
26339                         max=$tmp
26340                         max_index=$i
26341                 fi
26342                 if [ $tmp -lt $min ]; then
26343                         min=$tmp
26344                         min_index=$i
26345                 fi
26346         done
26347
26348         (( ${ffree[min_index]} > 0 )) ||
26349                 skip "no free files in MDT$min_index"
26350         (( ${ffree[min_index]} < 10000000 )) ||
26351                 skip "too many free files in MDT$min_index"
26352
26353         # Check if we need to generate uneven MDTs
26354         local diff=$(((max - min) * 100 / min))
26355         local testdir=$DIR/$tdir-fillmdt
26356         local start
26357
26358         i=0
26359         while (( diff < threshold )); do
26360                 mkdir -p $testdir
26361                 # generate uneven MDTs, create till $threshold% diff
26362                 echo -n "weight diff=$diff% must be > $threshold% ..."
26363                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26364                 testdir=$DIR/$tdir-fillmdt/$i
26365                 [ -d $testdir ] && continue
26366                 $LFS mkdir -i $min_index $testdir ||
26367                         error "mkdir $testdir failed"
26368                 $LFS setstripe -E 1M -L mdt $testdir ||
26369                         error "setstripe $testdir failed"
26370                 start=$SECONDS
26371                 for ((F=0; F < TEST413_COUNT; F++)); do
26372                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26373                                 /dev/null 2>&1 || error "dd $F failed"
26374                 done
26375                 sync; sleep 1; sync
26376
26377                 # wait for QOS to update
26378                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26379
26380                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26381                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26382                 max=$(((${ffree[max_index]} >> 8) *
26383                         (${bavail[max_index]} * bsize >> 16)))
26384                 min=$(((${ffree[min_index]} >> 8) *
26385                         (${bavail[min_index]} * bsize >> 16)))
26386                 diff=$(((max - min) * 100 / min))
26387                 i=$((i + 1))
26388         done
26389
26390         echo "MDT filesfree available: ${ffree[*]}"
26391         echo "MDT blocks available: ${bavail[*]}"
26392         echo "weight diff=$diff%"
26393 }
26394
26395 test_qos_mkdir() {
26396         local mkdir_cmd=$1
26397         local stripe_count=$2
26398         local mdts=$(comma_list $(mdts_nodes))
26399
26400         local testdir
26401         local lmv_qos_prio_free
26402         local lmv_qos_threshold_rr
26403         local lmv_qos_maxage
26404         local lod_qos_prio_free
26405         local lod_qos_threshold_rr
26406         local lod_qos_maxage
26407         local count
26408         local i
26409
26410         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26411         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26412         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26413                 head -n1)
26414         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26415         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26416         stack_trap "$LCTL set_param \
26417                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26418         stack_trap "$LCTL set_param \
26419                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26420         stack_trap "$LCTL set_param \
26421                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26422
26423         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26424                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26425         lod_qos_prio_free=${lod_qos_prio_free%%%}
26426         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26427                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26428         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26429         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26430                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26431         stack_trap "do_nodes $mdts $LCTL set_param \
26432                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26433         stack_trap "do_nodes $mdts $LCTL set_param \
26434                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26435         stack_trap "do_nodes $mdts $LCTL set_param \
26436                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26437
26438         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26439         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26440
26441         testdir=$DIR/$tdir-s$stripe_count/rr
26442
26443         local stripe_index=$($LFS getstripe -m $testdir)
26444         local test_mkdir_rr=true
26445
26446         getfattr -d -m dmv -e hex $testdir | grep dmv
26447         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26448                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26449                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26450                         test_mkdir_rr=false
26451         fi
26452
26453         echo
26454         $test_mkdir_rr &&
26455                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26456                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26457
26458         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26459         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26460                 eval $mkdir_cmd $testdir/subdir$i ||
26461                         error "$mkdir_cmd subdir$i failed"
26462         done
26463
26464         for (( i = 0; i < $MDSCOUNT; i++ )); do
26465                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26466                 echo "$count directories created on MDT$i"
26467                 if $test_mkdir_rr; then
26468                         (( $count == 100 )) ||
26469                                 error "subdirs are not evenly distributed"
26470                 elif (( $i == $stripe_index )); then
26471                         (( $count == 100 * MDSCOUNT )) ||
26472                                 error "$count subdirs created on MDT$i"
26473                 else
26474                         (( $count == 0 )) ||
26475                                 error "$count subdirs created on MDT$i"
26476                 fi
26477
26478                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26479                         count=$($LFS getdirstripe $testdir/* |
26480                                 grep -c -P "^\s+$i\t")
26481                         echo "$count stripes created on MDT$i"
26482                         # deviation should < 5% of average
26483                         (( $count >= 95 * stripe_count &&
26484                            $count <= 105 * stripe_count)) ||
26485                                 error "stripes are not evenly distributed"
26486                 fi
26487         done
26488
26489         echo
26490         echo "Check for uneven MDTs: "
26491
26492         local ffree
26493         local bavail
26494         local max
26495         local min
26496         local max_index
26497         local min_index
26498         local tmp
26499
26500         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26501         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26502         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26503
26504         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26505         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26506         max_index=0
26507         min_index=0
26508         for ((i = 1; i < ${#ffree[@]}; i++)); do
26509                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26510                 if [ $tmp -gt $max ]; then
26511                         max=$tmp
26512                         max_index=$i
26513                 fi
26514                 if [ $tmp -lt $min ]; then
26515                         min=$tmp
26516                         min_index=$i
26517                 fi
26518         done
26519
26520         (( ${ffree[min_index]} > 0 )) ||
26521                 skip "no free files in MDT$min_index"
26522         (( ${ffree[min_index]} < 10000000 )) ||
26523                 skip "too many free files in MDT$min_index"
26524
26525         echo "MDT filesfree available: ${ffree[*]}"
26526         echo "MDT blocks available: ${bavail[*]}"
26527         echo "weight diff=$(((max - min) * 100 / min))%"
26528         echo
26529         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26530
26531         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26532         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26533         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26534         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26535         # decrease statfs age, so that it can be updated in time
26536         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26537         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26538
26539         sleep 1
26540
26541         testdir=$DIR/$tdir-s$stripe_count/qos
26542         local num=200
26543
26544         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26545         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26546                 eval $mkdir_cmd $testdir/subdir$i ||
26547                         error "$mkdir_cmd subdir$i failed"
26548         done
26549
26550         max=0
26551         for (( i = 0; i < $MDSCOUNT; i++ )); do
26552                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26553                 (( count > max )) && max=$count
26554                 echo "$count directories created on MDT$i"
26555         done
26556
26557         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26558
26559         # D-value should > 10% of averge
26560         (( max - min > num / 10 )) ||
26561                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26562
26563         # ditto for stripes
26564         if (( stripe_count > 1 )); then
26565                 max=0
26566                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26567                         count=$($LFS getdirstripe $testdir/* |
26568                                 grep -c -P "^\s+$i\t")
26569                         (( count > max )) && max=$count
26570                         echo "$count stripes created on MDT$i"
26571                 done
26572
26573                 min=$($LFS getdirstripe $testdir/* |
26574                         grep -c -P "^\s+$min_index\t")
26575                 (( max - min > num * stripe_count / 10 )) ||
26576                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26577         fi
26578 }
26579
26580 most_full_mdt() {
26581         local ffree
26582         local bavail
26583         local bsize
26584         local min
26585         local min_index
26586         local tmp
26587
26588         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26589         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26590         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26591
26592         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26593         min_index=0
26594         for ((i = 1; i < ${#ffree[@]}; i++)); do
26595                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26596                 (( tmp < min )) && min=$tmp && min_index=$i
26597         done
26598
26599         echo -n $min_index
26600 }
26601
26602 test_413a() {
26603         [ $MDSCOUNT -lt 2 ] &&
26604                 skip "We need at least 2 MDTs for this test"
26605
26606         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26607                 skip "Need server version at least 2.12.52"
26608
26609         local stripe_count
26610
26611         generate_uneven_mdts 100
26612         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26613                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26614                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26615                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26616                         error "mkdir failed"
26617                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26618         done
26619 }
26620 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26621
26622 test_413b() {
26623         [ $MDSCOUNT -lt 2 ] &&
26624                 skip "We need at least 2 MDTs for this test"
26625
26626         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26627                 skip "Need server version at least 2.12.52"
26628
26629         local testdir
26630         local stripe_count
26631
26632         generate_uneven_mdts 100
26633         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26634                 testdir=$DIR/$tdir-s$stripe_count
26635                 mkdir $testdir || error "mkdir $testdir failed"
26636                 mkdir $testdir/rr || error "mkdir rr failed"
26637                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26638                         error "mkdir qos failed"
26639                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26640                         $testdir/rr || error "setdirstripe rr failed"
26641                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26642                         error "setdirstripe failed"
26643                 test_qos_mkdir "mkdir" $stripe_count
26644         done
26645 }
26646 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26647
26648 test_413c() {
26649         (( $MDSCOUNT >= 2 )) ||
26650                 skip "We need at least 2 MDTs for this test"
26651
26652         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26653                 skip "Need server version at least 2.14.51"
26654
26655         local testdir
26656         local inherit
26657         local inherit_rr
26658
26659         testdir=$DIR/${tdir}-s1
26660         mkdir $testdir || error "mkdir $testdir failed"
26661         mkdir $testdir/rr || error "mkdir rr failed"
26662         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26663         # default max_inherit is -1, default max_inherit_rr is 0
26664         $LFS setdirstripe -D -c 1 $testdir/rr ||
26665                 error "setdirstripe rr failed"
26666         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26667                 error "setdirstripe qos failed"
26668         test_qos_mkdir "mkdir" 1
26669
26670         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26671         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26672         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26673         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26674         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26675
26676         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26677         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26678         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26679         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26680         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26681         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26682         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26683                 error "level2 shouldn't have default LMV" || true
26684 }
26685 run_test 413c "mkdir with default LMV max inherit rr"
26686
26687 test_413d() {
26688         (( MDSCOUNT >= 2 )) ||
26689                 skip "We need at least 2 MDTs for this test"
26690
26691         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26692                 skip "Need server version at least 2.14.51"
26693
26694         local lmv_qos_threshold_rr
26695
26696         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26697                 head -n1)
26698         stack_trap "$LCTL set_param \
26699                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26700
26701         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26702         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26703         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26704                 error "$tdir shouldn't have default LMV"
26705         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26706                 error "mkdir sub failed"
26707
26708         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26709
26710         (( count == 100 )) || error "$count subdirs on MDT0"
26711 }
26712 run_test 413d "inherit ROOT default LMV"
26713
26714 test_413e() {
26715         (( MDSCOUNT >= 2 )) ||
26716                 skip "We need at least 2 MDTs for this test"
26717         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26718                 skip "Need server version at least 2.14.55"
26719
26720         local testdir=$DIR/$tdir
26721         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26722         local max_inherit
26723         local sub_max_inherit
26724
26725         mkdir -p $testdir || error "failed to create $testdir"
26726
26727         # set default max-inherit to -1 if stripe count is 0 or 1
26728         $LFS setdirstripe -D -c 1 $testdir ||
26729                 error "failed to set default LMV"
26730         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26731         (( max_inherit == -1 )) ||
26732                 error "wrong max_inherit value $max_inherit"
26733
26734         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26735         $LFS setdirstripe -D -c -1 $testdir ||
26736                 error "failed to set default LMV"
26737         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26738         (( max_inherit > 0 )) ||
26739                 error "wrong max_inherit value $max_inherit"
26740
26741         # and the subdir will decrease the max_inherit by 1
26742         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26743         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26744         (( sub_max_inherit == max_inherit - 1)) ||
26745                 error "wrong max-inherit of subdir $sub_max_inherit"
26746
26747         # check specified --max-inherit and warning message
26748         stack_trap "rm -f $tmpfile"
26749         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26750                 error "failed to set default LMV"
26751         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26752         (( max_inherit == -1 )) ||
26753                 error "wrong max_inherit value $max_inherit"
26754
26755         # check the warning messages
26756         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26757                 error "failed to detect warning string"
26758         fi
26759 }
26760 run_test 413e "check default max-inherit value"
26761
26762 test_fs_dmv_inherit()
26763 {
26764         local testdir=$DIR/$tdir
26765
26766         local count
26767         local inherit
26768         local inherit_rr
26769
26770         for i in 1 2 3; do
26771                 mkdir $testdir || error "mkdir $testdir failed"
26772                 count=$($LFS getdirstripe -D -c $testdir)
26773                 (( count == 1 )) ||
26774                         error "$testdir default LMV count mismatch $count != 1"
26775                 inherit=$($LFS getdirstripe -D -X $testdir)
26776                 (( inherit == 3 - i )) ||
26777                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26778                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26779                 (( inherit_rr == 3 - i )) ||
26780                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26781                 testdir=$testdir/sub
26782         done
26783
26784         mkdir $testdir || error "mkdir $testdir failed"
26785         count=$($LFS getdirstripe -D -c $testdir)
26786         (( count == 0 )) ||
26787                 error "$testdir default LMV count not zero: $count"
26788 }
26789
26790 test_413f() {
26791         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26792
26793         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26794                 skip "Need server version at least 2.14.55"
26795
26796         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26797                 error "dump $DIR default LMV failed"
26798         stack_trap "setfattr --restore=$TMP/dmv.ea"
26799
26800         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26801                 error "set $DIR default LMV failed"
26802
26803         test_fs_dmv_inherit
26804 }
26805 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26806
26807 test_413g() {
26808         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26809
26810         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26811         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26812                 error "dump $DIR default LMV failed"
26813         stack_trap "setfattr --restore=$TMP/dmv.ea"
26814
26815         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26816                 error "set $DIR default LMV failed"
26817
26818         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26819                 error "mount $MOUNT2 failed"
26820         stack_trap "umount_client $MOUNT2"
26821
26822         local saved_DIR=$DIR
26823
26824         export DIR=$MOUNT2
26825
26826         stack_trap "export DIR=$saved_DIR"
26827
26828         # first check filesystem-wide default LMV inheritance
26829         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26830
26831         # then check subdirs are spread to all MDTs
26832         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26833
26834         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26835
26836         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26837 }
26838 run_test 413g "enforce ROOT default LMV on subdir mount"
26839
26840 test_413h() {
26841         (( MDSCOUNT >= 2 )) ||
26842                 skip "We need at least 2 MDTs for this test"
26843
26844         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26845                 skip "Need server version at least 2.15.50.6"
26846
26847         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26848
26849         stack_trap "$LCTL set_param \
26850                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26851         $LCTL set_param lmv.*.qos_maxage=1
26852
26853         local depth=5
26854         local rr_depth=4
26855         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26856         local count=$((MDSCOUNT * 20))
26857
26858         generate_uneven_mdts 50
26859
26860         mkdir -p $dir || error "mkdir $dir failed"
26861         stack_trap "rm -rf $dir"
26862         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26863                 --max-inherit-rr=$rr_depth $dir
26864
26865         for ((d=0; d < depth + 2; d++)); do
26866                 log "dir=$dir:"
26867                 for ((sub=0; sub < count; sub++)); do
26868                         mkdir $dir/d$sub
26869                 done
26870                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26871                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26872                 # subdirs within $rr_depth should be created round-robin
26873                 if (( d < rr_depth )); then
26874                         (( ${num[0]} != count )) ||
26875                                 error "all objects created on MDT ${num[1]}"
26876                 fi
26877
26878                 dir=$dir/d0
26879         done
26880 }
26881 run_test 413h "don't stick to parent for round-robin dirs"
26882
26883 test_413z() {
26884         local pids=""
26885         local subdir
26886         local pid
26887
26888         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26889                 unlinkmany $subdir/f. $TEST413_COUNT &
26890                 pids="$pids $!"
26891         done
26892
26893         for pid in $pids; do
26894                 wait $pid
26895         done
26896 }
26897 run_test 413z "413 test cleanup"
26898
26899 test_414() {
26900 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26901         $LCTL set_param fail_loc=0x80000521
26902         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26903         rm -f $DIR/$tfile
26904 }
26905 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26906
26907 test_415() {
26908         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26909         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
26910                 skip "Need server version at least 2.11.52"
26911
26912         # LU-11102
26913         local total=500
26914         local max=120
26915
26916         # this test may be slow on ZFS
26917         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
26918
26919         # though this test is designed for striped directory, let's test normal
26920         # directory too since lock is always saved as CoS lock.
26921         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26922         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26923         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
26924         # if looping with ONLY_REPEAT, wait for previous deletions to finish
26925         wait_delete_completed_mds
26926
26927         # run a loop without concurrent touch to measure rename duration.
26928         # only for test debug/robustness, NOT part of COS functional test.
26929         local start_time=$SECONDS
26930         for ((i = 0; i < total; i++)); do
26931                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26932                         > /dev/null
26933         done
26934         local baseline=$((SECONDS - start_time))
26935         echo "rename $total files without 'touch' took $baseline sec"
26936
26937         (
26938                 while true; do
26939                         touch $DIR/$tdir
26940                 done
26941         ) &
26942         local setattr_pid=$!
26943
26944         # rename files back to original name so unlinkmany works
26945         start_time=$SECONDS
26946         for ((i = 0; i < total; i++)); do
26947                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
26948                         > /dev/null
26949         done
26950         local duration=$((SECONDS - start_time))
26951
26952         kill -9 $setattr_pid
26953
26954         echo "rename $total files with 'touch' took $duration sec"
26955         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
26956         (( duration <= max )) || error "rename took $duration > $max sec"
26957 }
26958 run_test 415 "lock revoke is not missing"
26959
26960 test_416() {
26961         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26962                 skip "Need server version at least 2.11.55"
26963
26964         # define OBD_FAIL_OSD_TXN_START    0x19a
26965         do_facet mds1 lctl set_param fail_loc=0x19a
26966
26967         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26968
26969         true
26970 }
26971 run_test 416 "transaction start failure won't cause system hung"
26972
26973 cleanup_417() {
26974         trap 0
26975         do_nodes $(comma_list $(mdts_nodes)) \
26976                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26977         do_nodes $(comma_list $(mdts_nodes)) \
26978                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26979         do_nodes $(comma_list $(mdts_nodes)) \
26980                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26981 }
26982
26983 test_417() {
26984         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26985         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26986                 skip "Need MDS version at least 2.11.56"
26987
26988         trap cleanup_417 RETURN EXIT
26989
26990         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26991         do_nodes $(comma_list $(mdts_nodes)) \
26992                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26993         $LFS migrate -m 0 $DIR/$tdir.1 &&
26994                 error "migrate dir $tdir.1 should fail"
26995
26996         do_nodes $(comma_list $(mdts_nodes)) \
26997                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26998         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26999                 error "create remote dir $tdir.2 should fail"
27000
27001         do_nodes $(comma_list $(mdts_nodes)) \
27002                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27003         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27004                 error "create striped dir $tdir.3 should fail"
27005         true
27006 }
27007 run_test 417 "disable remote dir, striped dir and dir migration"
27008
27009 # Checks that the outputs of df [-i] and lfs df [-i] match
27010 #
27011 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27012 check_lfs_df() {
27013         local dir=$2
27014         local inodes
27015         local df_out
27016         local lfs_df_out
27017         local count
27018         local passed=false
27019
27020         # blocks or inodes
27021         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27022
27023         for count in {1..100}; do
27024                 do_nodes "$CLIENTS" \
27025                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27026                 sync; sleep 0.2
27027
27028                 # read the lines of interest
27029                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27030                         error "df $inodes $dir | tail -n +2 failed"
27031                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27032                         error "lfs df $inodes $dir | grep summary: failed"
27033
27034                 # skip first substrings of each output as they are different
27035                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27036                 # compare the two outputs
27037                 passed=true
27038                 #  skip "available" on MDT until LU-13997 is fixed.
27039                 #for i in {1..5}; do
27040                 for i in 1 2 4 5; do
27041                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27042                 done
27043                 $passed && break
27044         done
27045
27046         if ! $passed; then
27047                 df -P $inodes $dir
27048                 echo
27049                 lfs df $inodes $dir
27050                 error "df and lfs df $1 output mismatch: "      \
27051                       "df ${inodes}: ${df_out[*]}, "            \
27052                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27053         fi
27054 }
27055
27056 test_418() {
27057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27058
27059         local dir=$DIR/$tdir
27060         local numfiles=$((RANDOM % 4096 + 2))
27061         local numblocks=$((RANDOM % 256 + 1))
27062
27063         wait_delete_completed
27064         test_mkdir $dir
27065
27066         # check block output
27067         check_lfs_df blocks $dir
27068         # check inode output
27069         check_lfs_df inodes $dir
27070
27071         # create a single file and retest
27072         echo "Creating a single file and testing"
27073         createmany -o $dir/$tfile- 1 &>/dev/null ||
27074                 error "creating 1 file in $dir failed"
27075         check_lfs_df blocks $dir
27076         check_lfs_df inodes $dir
27077
27078         # create a random number of files
27079         echo "Creating $((numfiles - 1)) files and testing"
27080         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27081                 error "creating $((numfiles - 1)) files in $dir failed"
27082
27083         # write a random number of blocks to the first test file
27084         echo "Writing $numblocks 4K blocks and testing"
27085         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27086                 count=$numblocks &>/dev/null ||
27087                 error "dd to $dir/${tfile}-0 failed"
27088
27089         # retest
27090         check_lfs_df blocks $dir
27091         check_lfs_df inodes $dir
27092
27093         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27094                 error "unlinking $numfiles files in $dir failed"
27095 }
27096 run_test 418 "df and lfs df outputs match"
27097
27098 test_419()
27099 {
27100         local dir=$DIR/$tdir
27101
27102         mkdir -p $dir
27103         touch $dir/file
27104
27105         cancel_lru_locks mdc
27106
27107         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27108         $LCTL set_param fail_loc=0x1410
27109         cat $dir/file
27110         $LCTL set_param fail_loc=0
27111         rm -rf $dir
27112 }
27113 run_test 419 "Verify open file by name doesn't crash kernel"
27114
27115 test_420()
27116 {
27117         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27118                 skip "Need MDS version at least 2.12.53"
27119
27120         local SAVE_UMASK=$(umask)
27121         local dir=$DIR/$tdir
27122         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27123
27124         mkdir -p $dir
27125         umask 0000
27126         mkdir -m03777 $dir/testdir
27127         ls -dn $dir/testdir
27128         # Need to remove trailing '.' when SELinux is enabled
27129         local dirperms=$(ls -dn $dir/testdir |
27130                          awk '{ sub(/\.$/, "", $1); print $1}')
27131         [ $dirperms == "drwxrwsrwt" ] ||
27132                 error "incorrect perms on $dir/testdir"
27133
27134         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27135                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27136         ls -n $dir/testdir/testfile
27137         local fileperms=$(ls -n $dir/testdir/testfile |
27138                           awk '{ sub(/\.$/, "", $1); print $1}')
27139         [ $fileperms == "-rwxr-xr-x" ] ||
27140                 error "incorrect perms on $dir/testdir/testfile"
27141
27142         umask $SAVE_UMASK
27143 }
27144 run_test 420 "clear SGID bit on non-directories for non-members"
27145
27146 test_421a() {
27147         local cnt
27148         local fid1
27149         local fid2
27150
27151         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27152                 skip "Need MDS version at least 2.12.54"
27153
27154         test_mkdir $DIR/$tdir
27155         createmany -o $DIR/$tdir/f 3
27156         cnt=$(ls -1 $DIR/$tdir | wc -l)
27157         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27158
27159         fid1=$(lfs path2fid $DIR/$tdir/f1)
27160         fid2=$(lfs path2fid $DIR/$tdir/f2)
27161         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27162
27163         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27164         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27165
27166         cnt=$(ls -1 $DIR/$tdir | wc -l)
27167         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27168
27169         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27170         createmany -o $DIR/$tdir/f 3
27171         cnt=$(ls -1 $DIR/$tdir | wc -l)
27172         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27173
27174         fid1=$(lfs path2fid $DIR/$tdir/f1)
27175         fid2=$(lfs path2fid $DIR/$tdir/f2)
27176         echo "remove using fsname $FSNAME"
27177         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27178
27179         cnt=$(ls -1 $DIR/$tdir | wc -l)
27180         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27181 }
27182 run_test 421a "simple rm by fid"
27183
27184 test_421b() {
27185         local cnt
27186         local FID1
27187         local FID2
27188
27189         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27190                 skip "Need MDS version at least 2.12.54"
27191
27192         test_mkdir $DIR/$tdir
27193         createmany -o $DIR/$tdir/f 3
27194         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27195         MULTIPID=$!
27196
27197         FID1=$(lfs path2fid $DIR/$tdir/f1)
27198         FID2=$(lfs path2fid $DIR/$tdir/f2)
27199         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27200
27201         kill -USR1 $MULTIPID
27202         wait
27203
27204         cnt=$(ls $DIR/$tdir | wc -l)
27205         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27206 }
27207 run_test 421b "rm by fid on open file"
27208
27209 test_421c() {
27210         local cnt
27211         local FIDS
27212
27213         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27214                 skip "Need MDS version at least 2.12.54"
27215
27216         test_mkdir $DIR/$tdir
27217         createmany -o $DIR/$tdir/f 3
27218         touch $DIR/$tdir/$tfile
27219         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27220         cnt=$(ls -1 $DIR/$tdir | wc -l)
27221         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27222
27223         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27224         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27225
27226         cnt=$(ls $DIR/$tdir | wc -l)
27227         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27228 }
27229 run_test 421c "rm by fid against hardlinked files"
27230
27231 test_421d() {
27232         local cnt
27233         local FIDS
27234
27235         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27236                 skip "Need MDS version at least 2.12.54"
27237
27238         test_mkdir $DIR/$tdir
27239         createmany -o $DIR/$tdir/f 4097
27240         cnt=$(ls -1 $DIR/$tdir | wc -l)
27241         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27242
27243         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27244         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27245
27246         cnt=$(ls $DIR/$tdir | wc -l)
27247         rm -rf $DIR/$tdir
27248         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27249 }
27250 run_test 421d "rmfid en masse"
27251
27252 test_421e() {
27253         local cnt
27254         local FID
27255
27256         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27257         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27258                 skip "Need MDS version at least 2.12.54"
27259
27260         mkdir -p $DIR/$tdir
27261         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27262         createmany -o $DIR/$tdir/striped_dir/f 512
27263         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27264         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27265
27266         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27267                 sed "s/[/][^:]*://g")
27268         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27269
27270         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27271         rm -rf $DIR/$tdir
27272         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27273 }
27274 run_test 421e "rmfid in DNE"
27275
27276 test_421f() {
27277         local cnt
27278         local FID
27279
27280         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27281                 skip "Need MDS version at least 2.12.54"
27282
27283         test_mkdir $DIR/$tdir
27284         touch $DIR/$tdir/f
27285         cnt=$(ls -1 $DIR/$tdir | wc -l)
27286         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27287
27288         FID=$(lfs path2fid $DIR/$tdir/f)
27289         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27290         # rmfid should fail
27291         cnt=$(ls -1 $DIR/$tdir | wc -l)
27292         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27293
27294         chmod a+rw $DIR/$tdir
27295         ls -la $DIR/$tdir
27296         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27297         # rmfid should fail
27298         cnt=$(ls -1 $DIR/$tdir | wc -l)
27299         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27300
27301         rm -f $DIR/$tdir/f
27302         $RUNAS touch $DIR/$tdir/f
27303         FID=$(lfs path2fid $DIR/$tdir/f)
27304         echo "rmfid as root"
27305         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27306         cnt=$(ls -1 $DIR/$tdir | wc -l)
27307         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27308
27309         rm -f $DIR/$tdir/f
27310         $RUNAS touch $DIR/$tdir/f
27311         cnt=$(ls -1 $DIR/$tdir | wc -l)
27312         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27313         FID=$(lfs path2fid $DIR/$tdir/f)
27314         # rmfid w/o user_fid2path mount option should fail
27315         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27316         cnt=$(ls -1 $DIR/$tdir | wc -l)
27317         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27318
27319         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27320         stack_trap "rmdir $tmpdir"
27321         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27322                 error "failed to mount client'"
27323         stack_trap "umount_client $tmpdir"
27324
27325         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27326         # rmfid should succeed
27327         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27328         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27329
27330         # rmfid shouldn't allow to remove files due to dir's permission
27331         chmod a+rwx $tmpdir/$tdir
27332         touch $tmpdir/$tdir/f
27333         ls -la $tmpdir/$tdir
27334         FID=$(lfs path2fid $tmpdir/$tdir/f)
27335         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27336         return 0
27337 }
27338 run_test 421f "rmfid checks permissions"
27339
27340 test_421g() {
27341         local cnt
27342         local FIDS
27343
27344         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27345         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27346                 skip "Need MDS version at least 2.12.54"
27347
27348         mkdir -p $DIR/$tdir
27349         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27350         createmany -o $DIR/$tdir/striped_dir/f 512
27351         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27352         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27353
27354         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27355                 sed "s/[/][^:]*://g")
27356
27357         rm -f $DIR/$tdir/striped_dir/f1*
27358         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27359         removed=$((512 - cnt))
27360
27361         # few files have been just removed, so we expect
27362         # rmfid to fail on their fids
27363         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27364         [ $removed != $errors ] && error "$errors != $removed"
27365
27366         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27367         rm -rf $DIR/$tdir
27368         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27369 }
27370 run_test 421g "rmfid to return errors properly"
27371
27372 test_422() {
27373         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27374         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27375         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27376         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27377         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27378
27379         local amc=$(at_max_get client)
27380         local amo=$(at_max_get mds1)
27381         local timeout=`lctl get_param -n timeout`
27382
27383         at_max_set 0 client
27384         at_max_set 0 mds1
27385
27386 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27387         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27388                         fail_val=$(((2*timeout + 10)*1000))
27389         touch $DIR/$tdir/d3/file &
27390         sleep 2
27391 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27392         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27393                         fail_val=$((2*timeout + 5))
27394         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27395         local pid=$!
27396         sleep 1
27397         kill -9 $pid
27398         sleep $((2 * timeout))
27399         echo kill $pid
27400         kill -9 $pid
27401         lctl mark touch
27402         touch $DIR/$tdir/d2/file3
27403         touch $DIR/$tdir/d2/file4
27404         touch $DIR/$tdir/d2/file5
27405
27406         wait
27407         at_max_set $amc client
27408         at_max_set $amo mds1
27409
27410         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27411         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27412                 error "Watchdog is always throttled"
27413 }
27414 run_test 422 "kill a process with RPC in progress"
27415
27416 stat_test() {
27417     df -h $MOUNT &
27418     df -h $MOUNT &
27419     df -h $MOUNT &
27420     df -h $MOUNT &
27421     df -h $MOUNT &
27422     df -h $MOUNT &
27423 }
27424
27425 test_423() {
27426     local _stats
27427     # ensure statfs cache is expired
27428     sleep 2;
27429
27430     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27431     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27432
27433     return 0
27434 }
27435 run_test 423 "statfs should return a right data"
27436
27437 test_424() {
27438 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27439         $LCTL set_param fail_loc=0x80000522
27440         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27441         rm -f $DIR/$tfile
27442 }
27443 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27444
27445 test_425() {
27446         test_mkdir -c -1 $DIR/$tdir
27447         $LFS setstripe -c -1 $DIR/$tdir
27448
27449         lru_resize_disable "" 100
27450         stack_trap "lru_resize_enable" EXIT
27451
27452         sleep 5
27453
27454         for i in $(seq $((MDSCOUNT * 125))); do
27455                 local t=$DIR/$tdir/$tfile_$i
27456
27457                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27458                         error_noexit "Create file $t"
27459         done
27460         stack_trap "rm -rf $DIR/$tdir" EXIT
27461
27462         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27463                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27464                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27465
27466                 [ $lock_count -le $lru_size ] ||
27467                         error "osc lock count $lock_count > lru size $lru_size"
27468         done
27469
27470         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27471                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27472                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27473
27474                 [ $lock_count -le $lru_size ] ||
27475                         error "mdc lock count $lock_count > lru size $lru_size"
27476         done
27477 }
27478 run_test 425 "lock count should not exceed lru size"
27479
27480 test_426() {
27481         splice-test -r $DIR/$tfile
27482         splice-test -rd $DIR/$tfile
27483         splice-test $DIR/$tfile
27484         splice-test -d $DIR/$tfile
27485 }
27486 run_test 426 "splice test on Lustre"
27487
27488 test_427() {
27489         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27490         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27491                 skip "Need MDS version at least 2.12.4"
27492         local log
27493
27494         mkdir $DIR/$tdir
27495         mkdir $DIR/$tdir/1
27496         mkdir $DIR/$tdir/2
27497         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27498         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27499
27500         $LFS getdirstripe $DIR/$tdir/1/dir
27501
27502         #first setfattr for creating updatelog
27503         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27504
27505 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27506         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27507         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27508         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27509
27510         sleep 2
27511         fail mds2
27512         wait_recovery_complete mds2 $((2*TIMEOUT))
27513
27514         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27515         echo $log | grep "get update log failed" &&
27516                 error "update log corruption is detected" || true
27517 }
27518 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27519
27520 test_428() {
27521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27522         local cache_limit=$CACHE_MAX
27523
27524         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27525         $LCTL set_param -n llite.*.max_cached_mb=64
27526
27527         mkdir $DIR/$tdir
27528         $LFS setstripe -c 1 $DIR/$tdir
27529         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27530         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27531         #test write
27532         for f in $(seq 4); do
27533                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27534         done
27535         wait
27536
27537         cancel_lru_locks osc
27538         # Test read
27539         for f in $(seq 4); do
27540                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27541         done
27542         wait
27543 }
27544 run_test 428 "large block size IO should not hang"
27545
27546 test_429() { # LU-7915 / LU-10948
27547         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27548         local testfile=$DIR/$tfile
27549         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27550         local new_flag=1
27551         local first_rpc
27552         local second_rpc
27553         local third_rpc
27554
27555         $LCTL get_param $ll_opencache_threshold_count ||
27556                 skip "client does not have opencache parameter"
27557
27558         set_opencache $new_flag
27559         stack_trap "restore_opencache"
27560         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27561                 error "enable opencache failed"
27562         touch $testfile
27563         # drop MDC DLM locks
27564         cancel_lru_locks mdc
27565         # clear MDC RPC stats counters
27566         $LCTL set_param $mdc_rpcstats=clear
27567
27568         # According to the current implementation, we need to run 3 times
27569         # open & close file to verify if opencache is enabled correctly.
27570         # 1st, RPCs are sent for lookup/open and open handle is released on
27571         #      close finally.
27572         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27573         #      so open handle won't be released thereafter.
27574         # 3rd, No RPC is sent out.
27575         $MULTIOP $testfile oc || error "multiop failed"
27576         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27577         echo "1st: $first_rpc RPCs in flight"
27578
27579         $MULTIOP $testfile oc || error "multiop failed"
27580         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27581         echo "2nd: $second_rpc RPCs in flight"
27582
27583         $MULTIOP $testfile oc || error "multiop failed"
27584         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27585         echo "3rd: $third_rpc RPCs in flight"
27586
27587         #verify no MDC RPC is sent
27588         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27589 }
27590 run_test 429 "verify if opencache flag on client side does work"
27591
27592 lseek_test_430() {
27593         local offset
27594         local file=$1
27595
27596         # data at [200K, 400K)
27597         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27598                 error "256K->512K dd fails"
27599         # data at [2M, 3M)
27600         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27601                 error "2M->3M dd fails"
27602         # data at [4M, 5M)
27603         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27604                 error "4M->5M dd fails"
27605         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27606         # start at first component hole #1
27607         printf "Seeking hole from 1000 ... "
27608         offset=$(lseek_test -l 1000 $file)
27609         echo $offset
27610         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27611         printf "Seeking data from 1000 ... "
27612         offset=$(lseek_test -d 1000 $file)
27613         echo $offset
27614         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27615
27616         # start at first component data block
27617         printf "Seeking hole from 300000 ... "
27618         offset=$(lseek_test -l 300000 $file)
27619         echo $offset
27620         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27621         printf "Seeking data from 300000 ... "
27622         offset=$(lseek_test -d 300000 $file)
27623         echo $offset
27624         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27625
27626         # start at the first component but beyond end of object size
27627         printf "Seeking hole from 1000000 ... "
27628         offset=$(lseek_test -l 1000000 $file)
27629         echo $offset
27630         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27631         printf "Seeking data from 1000000 ... "
27632         offset=$(lseek_test -d 1000000 $file)
27633         echo $offset
27634         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27635
27636         # start at second component stripe 2 (empty file)
27637         printf "Seeking hole from 1500000 ... "
27638         offset=$(lseek_test -l 1500000 $file)
27639         echo $offset
27640         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27641         printf "Seeking data from 1500000 ... "
27642         offset=$(lseek_test -d 1500000 $file)
27643         echo $offset
27644         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27645
27646         # start at second component stripe 1 (all data)
27647         printf "Seeking hole from 3000000 ... "
27648         offset=$(lseek_test -l 3000000 $file)
27649         echo $offset
27650         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27651         printf "Seeking data from 3000000 ... "
27652         offset=$(lseek_test -d 3000000 $file)
27653         echo $offset
27654         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27655
27656         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27657                 error "2nd dd fails"
27658         echo "Add data block at 640K...1280K"
27659
27660         # start at before new data block, in hole
27661         printf "Seeking hole from 600000 ... "
27662         offset=$(lseek_test -l 600000 $file)
27663         echo $offset
27664         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27665         printf "Seeking data from 600000 ... "
27666         offset=$(lseek_test -d 600000 $file)
27667         echo $offset
27668         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27669
27670         # start at the first component new data block
27671         printf "Seeking hole from 1000000 ... "
27672         offset=$(lseek_test -l 1000000 $file)
27673         echo $offset
27674         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27675         printf "Seeking data from 1000000 ... "
27676         offset=$(lseek_test -d 1000000 $file)
27677         echo $offset
27678         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27679
27680         # start at second component stripe 2, new data
27681         printf "Seeking hole from 1200000 ... "
27682         offset=$(lseek_test -l 1200000 $file)
27683         echo $offset
27684         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27685         printf "Seeking data from 1200000 ... "
27686         offset=$(lseek_test -d 1200000 $file)
27687         echo $offset
27688         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27689
27690         # start beyond file end
27691         printf "Using offset > filesize ... "
27692         lseek_test -l 4000000 $file && error "lseek should fail"
27693         printf "Using offset > filesize ... "
27694         lseek_test -d 4000000 $file && error "lseek should fail"
27695
27696         printf "Done\n\n"
27697 }
27698
27699 test_430a() {
27700         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27701                 skip "MDT does not support SEEK_HOLE"
27702
27703         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27704                 skip "OST does not support SEEK_HOLE"
27705
27706         local file=$DIR/$tdir/$tfile
27707
27708         mkdir -p $DIR/$tdir
27709
27710         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27711         # OST stripe #1 will have continuous data at [1M, 3M)
27712         # OST stripe #2 is empty
27713         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27714         lseek_test_430 $file
27715         rm $file
27716         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27717         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27718         lseek_test_430 $file
27719         rm $file
27720         $LFS setstripe -c2 -S 512K $file
27721         echo "Two stripes, stripe size 512K"
27722         lseek_test_430 $file
27723         rm $file
27724         # FLR with stale mirror
27725         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27726                        -N -c2 -S 1M $file
27727         echo "Mirrored file:"
27728         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27729         echo "Plain 2 stripes 1M"
27730         lseek_test_430 $file
27731         rm $file
27732 }
27733 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27734
27735 test_430b() {
27736         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27737                 skip "OST does not support SEEK_HOLE"
27738
27739         local offset
27740         local file=$DIR/$tdir/$tfile
27741
27742         mkdir -p $DIR/$tdir
27743         # Empty layout lseek should fail
27744         $MCREATE $file
27745         # seek from 0
27746         printf "Seeking hole from 0 ... "
27747         lseek_test -l 0 $file && error "lseek should fail"
27748         printf "Seeking data from 0 ... "
27749         lseek_test -d 0 $file && error "lseek should fail"
27750         rm $file
27751
27752         # 1M-hole file
27753         $LFS setstripe -E 1M -c2 -E eof $file
27754         $TRUNCATE $file 1048576
27755         printf "Seeking hole from 1000000 ... "
27756         offset=$(lseek_test -l 1000000 $file)
27757         echo $offset
27758         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27759         printf "Seeking data from 1000000 ... "
27760         lseek_test -d 1000000 $file && error "lseek should fail"
27761         rm $file
27762
27763         # full component followed by non-inited one
27764         $LFS setstripe -E 1M -c2 -E eof $file
27765         dd if=/dev/urandom of=$file bs=1M count=1
27766         printf "Seeking hole from 1000000 ... "
27767         offset=$(lseek_test -l 1000000 $file)
27768         echo $offset
27769         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27770         printf "Seeking hole from 1048576 ... "
27771         lseek_test -l 1048576 $file && error "lseek should fail"
27772         # init second component and truncate back
27773         echo "123" >> $file
27774         $TRUNCATE $file 1048576
27775         printf "Seeking hole from 1000000 ... "
27776         offset=$(lseek_test -l 1000000 $file)
27777         echo $offset
27778         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27779         printf "Seeking hole from 1048576 ... "
27780         lseek_test -l 1048576 $file && error "lseek should fail"
27781         # boundary checks for big values
27782         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27783         offset=$(lseek_test -d 0 $file.10g)
27784         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27785         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27786         offset=$(lseek_test -d 0 $file.100g)
27787         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27788         return 0
27789 }
27790 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27791
27792 test_430c() {
27793         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27794                 skip "OST does not support SEEK_HOLE"
27795
27796         local file=$DIR/$tdir/$tfile
27797         local start
27798
27799         mkdir -p $DIR/$tdir
27800         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27801
27802         # cp version 8.33+ prefers lseek over fiemap
27803         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27804                 start=$SECONDS
27805                 time cp $file /dev/null
27806                 (( SECONDS - start < 5 )) ||
27807                         error "cp: too long runtime $((SECONDS - start))"
27808
27809         fi
27810         # tar version 1.29+ supports SEEK_HOLE/DATA
27811         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27812                 start=$SECONDS
27813                 time tar cS $file - | cat > /dev/null
27814                 (( SECONDS - start < 5 )) ||
27815                         error "tar: too long runtime $((SECONDS - start))"
27816         fi
27817 }
27818 run_test 430c "lseek: external tools check"
27819
27820 test_431() { # LU-14187
27821         local file=$DIR/$tdir/$tfile
27822
27823         mkdir -p $DIR/$tdir
27824         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27825         dd if=/dev/urandom of=$file bs=4k count=1
27826         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27827         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27828         #define OBD_FAIL_OST_RESTART_IO 0x251
27829         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27830         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27831         cp $file $file.0
27832         cancel_lru_locks
27833         sync_all_data
27834         echo 3 > /proc/sys/vm/drop_caches
27835         diff  $file $file.0 || error "data diff"
27836 }
27837 run_test 431 "Restart transaction for IO"
27838
27839 cleanup_test_432() {
27840         do_facet mgs $LCTL nodemap_activate 0
27841         wait_nm_sync active
27842 }
27843
27844 test_432() {
27845         local tmpdir=$TMP/dir432
27846
27847         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27848                 skip "Need MDS version at least 2.14.52"
27849
27850         stack_trap cleanup_test_432 EXIT
27851         mkdir $DIR/$tdir
27852         mkdir $tmpdir
27853
27854         do_facet mgs $LCTL nodemap_activate 1
27855         wait_nm_sync active
27856         do_facet mgs $LCTL nodemap_modify --name default \
27857                 --property admin --value 1
27858         do_facet mgs $LCTL nodemap_modify --name default \
27859                 --property trusted --value 1
27860         cancel_lru_locks mdc
27861         wait_nm_sync default admin_nodemap
27862         wait_nm_sync default trusted_nodemap
27863
27864         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27865                grep -ci "Operation not permitted") -ne 0 ]; then
27866                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27867         fi
27868 }
27869 run_test 432 "mv dir from outside Lustre"
27870
27871 test_433() {
27872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27873
27874         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27875                 skip "inode cache not supported"
27876
27877         $LCTL set_param llite.*.inode_cache=0
27878         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27879
27880         local count=256
27881         local before
27882         local after
27883
27884         cancel_lru_locks mdc
27885         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27886         createmany -m $DIR/$tdir/f $count
27887         createmany -d $DIR/$tdir/d $count
27888         ls -l $DIR/$tdir > /dev/null
27889         stack_trap "rm -rf $DIR/$tdir"
27890
27891         before=$(num_objects)
27892         cancel_lru_locks mdc
27893         after=$(num_objects)
27894
27895         # sometimes even @before is less than 2 * count
27896         while (( before - after < count )); do
27897                 sleep 1
27898                 after=$(num_objects)
27899                 wait=$((wait + 1))
27900                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27901                 if (( wait > 60 )); then
27902                         error "inode slab grew from $before to $after"
27903                 fi
27904         done
27905
27906         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27907 }
27908 run_test 433 "ldlm lock cancel releases dentries and inodes"
27909
27910 test_434() {
27911         local file
27912         local getxattr_count
27913         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27914         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27915
27916         [[ $(getenforce) == "Disabled" ]] ||
27917                 skip "lsm selinux module have to be disabled for this test"
27918
27919         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27920                 error "fail to create $DIR/$tdir/ on MDT0000"
27921
27922         touch $DIR/$tdir/$tfile-{001..100}
27923
27924         # disable the xattr cache
27925         save_lustre_params client "llite.*.xattr_cache" > $p
27926         lctl set_param llite.*.xattr_cache=0
27927         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27928
27929         # clear clients mdc stats
27930         clear_stats $mdc_stat_param ||
27931                 error "fail to clear stats on mdc MDT0000"
27932
27933         for file in $DIR/$tdir/$tfile-{001..100}; do
27934                 getfattr -n security.selinux $file |&
27935                         grep -q "Operation not supported" ||
27936                         error "getxattr on security.selinux should return EOPNOTSUPP"
27937         done
27938
27939         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27940         (( getxattr_count < 100 )) ||
27941                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27942 }
27943 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27944
27945 test_440() {
27946         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
27947                 source $LUSTRE/scripts/bash-completion/lustre
27948         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
27949                 source /usr/share/bash-completion/completions/lustre
27950         else
27951                 skip "bash completion scripts not found"
27952         fi
27953
27954         local lctl_completions
27955         local lfs_completions
27956
27957         lctl_completions=$(_lustre_cmds lctl)
27958         if [[ ! $lctl_completions =~ "get_param" ]]; then
27959                 error "lctl bash completion failed"
27960         fi
27961
27962         lfs_completions=$(_lustre_cmds lfs)
27963         if [[ ! $lfs_completions =~ "setstripe" ]]; then
27964                 error "lfs bash completion failed"
27965         fi
27966 }
27967 run_test 440 "bash completion for lfs, lctl"
27968
27969 prep_801() {
27970         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27971         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27972                 skip "Need server version at least 2.9.55"
27973
27974         start_full_debug_logging
27975 }
27976
27977 post_801() {
27978         stop_full_debug_logging
27979 }
27980
27981 barrier_stat() {
27982         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27983                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27984                            awk '/The barrier for/ { print $7 }')
27985                 echo $st
27986         else
27987                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27988                 echo \'$st\'
27989         fi
27990 }
27991
27992 barrier_expired() {
27993         local expired
27994
27995         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27996                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27997                           awk '/will be expired/ { print $7 }')
27998         else
27999                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28000         fi
28001
28002         echo $expired
28003 }
28004
28005 test_801a() {
28006         prep_801
28007
28008         echo "Start barrier_freeze at: $(date)"
28009         #define OBD_FAIL_BARRIER_DELAY          0x2202
28010         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28011         # Do not reduce barrier time - See LU-11873
28012         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28013
28014         sleep 2
28015         local b_status=$(barrier_stat)
28016         echo "Got barrier status at: $(date)"
28017         [ "$b_status" = "'freezing_p1'" ] ||
28018                 error "(1) unexpected barrier status $b_status"
28019
28020         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28021         wait
28022         b_status=$(barrier_stat)
28023         [ "$b_status" = "'frozen'" ] ||
28024                 error "(2) unexpected barrier status $b_status"
28025
28026         local expired=$(barrier_expired)
28027         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28028         sleep $((expired + 3))
28029
28030         b_status=$(barrier_stat)
28031         [ "$b_status" = "'expired'" ] ||
28032                 error "(3) unexpected barrier status $b_status"
28033
28034         # Do not reduce barrier time - See LU-11873
28035         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28036                 error "(4) fail to freeze barrier"
28037
28038         b_status=$(barrier_stat)
28039         [ "$b_status" = "'frozen'" ] ||
28040                 error "(5) unexpected barrier status $b_status"
28041
28042         echo "Start barrier_thaw at: $(date)"
28043         #define OBD_FAIL_BARRIER_DELAY          0x2202
28044         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28045         do_facet mgs $LCTL barrier_thaw $FSNAME &
28046
28047         sleep 2
28048         b_status=$(barrier_stat)
28049         echo "Got barrier status at: $(date)"
28050         [ "$b_status" = "'thawing'" ] ||
28051                 error "(6) unexpected barrier status $b_status"
28052
28053         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28054         wait
28055         b_status=$(barrier_stat)
28056         [ "$b_status" = "'thawed'" ] ||
28057                 error "(7) unexpected barrier status $b_status"
28058
28059         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28060         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28061         do_facet mgs $LCTL barrier_freeze $FSNAME
28062
28063         b_status=$(barrier_stat)
28064         [ "$b_status" = "'failed'" ] ||
28065                 error "(8) unexpected barrier status $b_status"
28066
28067         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28068         do_facet mgs $LCTL barrier_thaw $FSNAME
28069
28070         post_801
28071 }
28072 run_test 801a "write barrier user interfaces and stat machine"
28073
28074 test_801b() {
28075         prep_801
28076
28077         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28078         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28079         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28080         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28081         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28082
28083         cancel_lru_locks mdc
28084
28085         # 180 seconds should be long enough
28086         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28087
28088         local b_status=$(barrier_stat)
28089         [ "$b_status" = "'frozen'" ] ||
28090                 error "(6) unexpected barrier status $b_status"
28091
28092         mkdir $DIR/$tdir/d0/d10 &
28093         mkdir_pid=$!
28094
28095         touch $DIR/$tdir/d1/f13 &
28096         touch_pid=$!
28097
28098         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28099         ln_pid=$!
28100
28101         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28102         mv_pid=$!
28103
28104         rm -f $DIR/$tdir/d4/f12 &
28105         rm_pid=$!
28106
28107         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28108
28109         # To guarantee taht the 'stat' is not blocked
28110         b_status=$(barrier_stat)
28111         [ "$b_status" = "'frozen'" ] ||
28112                 error "(8) unexpected barrier status $b_status"
28113
28114         # let above commands to run at background
28115         sleep 5
28116
28117         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28118         ps -p $touch_pid || error "(10) touch should be blocked"
28119         ps -p $ln_pid || error "(11) link should be blocked"
28120         ps -p $mv_pid || error "(12) rename should be blocked"
28121         ps -p $rm_pid || error "(13) unlink should be blocked"
28122
28123         b_status=$(barrier_stat)
28124         [ "$b_status" = "'frozen'" ] ||
28125                 error "(14) unexpected barrier status $b_status"
28126
28127         do_facet mgs $LCTL barrier_thaw $FSNAME
28128         b_status=$(barrier_stat)
28129         [ "$b_status" = "'thawed'" ] ||
28130                 error "(15) unexpected barrier status $b_status"
28131
28132         wait $mkdir_pid || error "(16) mkdir should succeed"
28133         wait $touch_pid || error "(17) touch should succeed"
28134         wait $ln_pid || error "(18) link should succeed"
28135         wait $mv_pid || error "(19) rename should succeed"
28136         wait $rm_pid || error "(20) unlink should succeed"
28137
28138         post_801
28139 }
28140 run_test 801b "modification will be blocked by write barrier"
28141
28142 test_801c() {
28143         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28144
28145         prep_801
28146
28147         stop mds2 || error "(1) Fail to stop mds2"
28148
28149         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28150
28151         local b_status=$(barrier_stat)
28152         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28153                 do_facet mgs $LCTL barrier_thaw $FSNAME
28154                 error "(2) unexpected barrier status $b_status"
28155         }
28156
28157         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28158                 error "(3) Fail to rescan barrier bitmap"
28159
28160         # Do not reduce barrier time - See LU-11873
28161         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28162
28163         b_status=$(barrier_stat)
28164         [ "$b_status" = "'frozen'" ] ||
28165                 error "(4) unexpected barrier status $b_status"
28166
28167         do_facet mgs $LCTL barrier_thaw $FSNAME
28168         b_status=$(barrier_stat)
28169         [ "$b_status" = "'thawed'" ] ||
28170                 error "(5) unexpected barrier status $b_status"
28171
28172         local devname=$(mdsdevname 2)
28173
28174         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28175
28176         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28177                 error "(7) Fail to rescan barrier bitmap"
28178
28179         post_801
28180 }
28181 run_test 801c "rescan barrier bitmap"
28182
28183 test_802b() {
28184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28185         remote_mds_nodsh && skip "remote MDS with nodsh"
28186
28187         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28188                 skip "readonly option not available"
28189
28190         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28191
28192         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28193                 error "(2) Fail to copy"
28194
28195         # write back all cached data before setting MDT to readonly
28196         cancel_lru_locks
28197         sync_all_data
28198
28199         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28200         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28201
28202         echo "Modify should be refused"
28203         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28204
28205         echo "Read should be allowed"
28206         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28207                 error "(7) Read should succeed under ro mode"
28208
28209         # disable readonly
28210         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28211 }
28212 run_test 802b "be able to set MDTs to readonly"
28213
28214 test_803a() {
28215         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28216         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28217                 skip "MDS needs to be newer than 2.10.54"
28218
28219         mkdir_on_mdt0 $DIR/$tdir
28220         # Create some objects on all MDTs to trigger related logs objects
28221         for idx in $(seq $MDSCOUNT); do
28222                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28223                         $DIR/$tdir/dir${idx} ||
28224                         error "Fail to create $DIR/$tdir/dir${idx}"
28225         done
28226
28227         wait_delete_completed # ensure old test cleanups are finished
28228         sleep 3
28229         echo "before create:"
28230         $LFS df -i $MOUNT
28231         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28232
28233         for i in {1..10}; do
28234                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28235                         error "Fail to create $DIR/$tdir/foo$i"
28236         done
28237
28238         # sync ZFS-on-MDS to refresh statfs data
28239         wait_zfs_commit mds1
28240         sleep 3
28241         echo "after create:"
28242         $LFS df -i $MOUNT
28243         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28244
28245         # allow for an llog to be cleaned up during the test
28246         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28247                 error "before ($before_used) + 10 > after ($after_used)"
28248
28249         for i in {1..10}; do
28250                 rm -rf $DIR/$tdir/foo$i ||
28251                         error "Fail to remove $DIR/$tdir/foo$i"
28252         done
28253
28254         # sync ZFS-on-MDS to refresh statfs data
28255         wait_zfs_commit mds1
28256         wait_delete_completed
28257         sleep 3 # avoid MDT return cached statfs
28258         echo "after unlink:"
28259         $LFS df -i $MOUNT
28260         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28261
28262         # allow for an llog to be created during the test
28263         [ $after_used -le $((before_used + 1)) ] ||
28264                 error "after ($after_used) > before ($before_used) + 1"
28265 }
28266 run_test 803a "verify agent object for remote object"
28267
28268 test_803b() {
28269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28270         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28271                 skip "MDS needs to be newer than 2.13.56"
28272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28273
28274         for i in $(seq 0 $((MDSCOUNT - 1))); do
28275                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28276         done
28277
28278         local before=0
28279         local after=0
28280
28281         local tmp
28282
28283         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28284         for i in $(seq 0 $((MDSCOUNT - 1))); do
28285                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28286                         awk '/getattr/ { print $2 }')
28287                 before=$((before + tmp))
28288         done
28289         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28290         for i in $(seq 0 $((MDSCOUNT - 1))); do
28291                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28292                         awk '/getattr/ { print $2 }')
28293                 after=$((after + tmp))
28294         done
28295
28296         [ $before -eq $after ] || error "getattr count $before != $after"
28297 }
28298 run_test 803b "remote object can getattr from cache"
28299
28300 test_804() {
28301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28302         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28303                 skip "MDS needs to be newer than 2.10.54"
28304         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28305
28306         mkdir -p $DIR/$tdir
28307         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28308                 error "Fail to create $DIR/$tdir/dir0"
28309
28310         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28311         local dev=$(mdsdevname 2)
28312
28313         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28314                 grep ${fid} || error "NOT found agent entry for dir0"
28315
28316         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28317                 error "Fail to create $DIR/$tdir/dir1"
28318
28319         touch $DIR/$tdir/dir1/foo0 ||
28320                 error "Fail to create $DIR/$tdir/dir1/foo0"
28321         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28322         local rc=0
28323
28324         for idx in $(seq $MDSCOUNT); do
28325                 dev=$(mdsdevname $idx)
28326                 do_facet mds${idx} \
28327                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28328                         grep ${fid} && rc=$idx
28329         done
28330
28331         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28332                 error "Fail to rename foo0 to foo1"
28333         if [ $rc -eq 0 ]; then
28334                 for idx in $(seq $MDSCOUNT); do
28335                         dev=$(mdsdevname $idx)
28336                         do_facet mds${idx} \
28337                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28338                         grep ${fid} && rc=$idx
28339                 done
28340         fi
28341
28342         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28343                 error "Fail to rename foo1 to foo2"
28344         if [ $rc -eq 0 ]; then
28345                 for idx in $(seq $MDSCOUNT); do
28346                         dev=$(mdsdevname $idx)
28347                         do_facet mds${idx} \
28348                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28349                         grep ${fid} && rc=$idx
28350                 done
28351         fi
28352
28353         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28354
28355         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28356                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28357         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28358                 error "Fail to rename foo2 to foo0"
28359         unlink $DIR/$tdir/dir1/foo0 ||
28360                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28361         rm -rf $DIR/$tdir/dir0 ||
28362                 error "Fail to rm $DIR/$tdir/dir0"
28363
28364         for idx in $(seq $MDSCOUNT); do
28365                 rc=0
28366
28367                 stop mds${idx}
28368                 dev=$(mdsdevname $idx)
28369                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28370                         rc=$?
28371                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28372                         error "mount mds$idx failed"
28373                 df $MOUNT > /dev/null 2>&1
28374
28375                 # e2fsck should not return error
28376                 [ $rc -eq 0 ] ||
28377                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28378         done
28379 }
28380 run_test 804 "verify agent entry for remote entry"
28381
28382 cleanup_805() {
28383         do_facet $SINGLEMDS zfs set quota=$old $fsset
28384         unlinkmany $DIR/$tdir/f- 1000000
28385         trap 0
28386 }
28387
28388 test_805() {
28389         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28390         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28391         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28392                 skip "netfree not implemented before 0.7"
28393         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28394                 skip "Need MDS version at least 2.10.57"
28395
28396         local fsset
28397         local freekb
28398         local usedkb
28399         local old
28400         local quota
28401         local pref="osd-zfs.$FSNAME-MDT0000."
28402
28403         # limit available space on MDS dataset to meet nospace issue
28404         # quickly. then ZFS 0.7.2 can use reserved space if asked
28405         # properly (using netfree flag in osd_declare_destroy()
28406         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28407         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28408                 gawk '{print $3}')
28409         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28410         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28411         let "usedkb=usedkb-freekb"
28412         let "freekb=freekb/2"
28413         if let "freekb > 5000"; then
28414                 let "freekb=5000"
28415         fi
28416         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28417         trap cleanup_805 EXIT
28418         mkdir_on_mdt0 $DIR/$tdir
28419         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28420                 error "Can't set PFL layout"
28421         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28422         rm -rf $DIR/$tdir || error "not able to remove"
28423         do_facet $SINGLEMDS zfs set quota=$old $fsset
28424         trap 0
28425 }
28426 run_test 805 "ZFS can remove from full fs"
28427
28428 # Size-on-MDS test
28429 check_lsom_data()
28430 {
28431         local file=$1
28432         local expect=$(stat -c %s $file)
28433
28434         check_lsom_size $1 $expect
28435
28436         local blocks=$($LFS getsom -b $file)
28437         expect=$(stat -c %b $file)
28438         [[ $blocks == $expect ]] ||
28439                 error "$file expected blocks: $expect, got: $blocks"
28440 }
28441
28442 check_lsom_size()
28443 {
28444         local size
28445         local expect=$2
28446
28447         cancel_lru_locks mdc
28448
28449         size=$($LFS getsom -s $1)
28450         [[ $size == $expect ]] ||
28451                 error "$file expected size: $expect, got: $size"
28452 }
28453
28454 test_806() {
28455         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28456                 skip "Need MDS version at least 2.11.52"
28457
28458         local bs=1048576
28459
28460         touch $DIR/$tfile || error "touch $tfile failed"
28461
28462         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28463         save_lustre_params client "llite.*.xattr_cache" > $save
28464         lctl set_param llite.*.xattr_cache=0
28465         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28466
28467         # single-threaded write
28468         echo "Test SOM for single-threaded write"
28469         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28470                 error "write $tfile failed"
28471         check_lsom_size $DIR/$tfile $bs
28472
28473         local num=32
28474         local size=$(($num * $bs))
28475         local offset=0
28476         local i
28477
28478         echo "Test SOM for single client multi-threaded($num) write"
28479         $TRUNCATE $DIR/$tfile 0
28480         for ((i = 0; i < $num; i++)); do
28481                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28482                 local pids[$i]=$!
28483                 offset=$((offset + $bs))
28484         done
28485         for (( i=0; i < $num; i++ )); do
28486                 wait ${pids[$i]}
28487         done
28488         check_lsom_size $DIR/$tfile $size
28489
28490         $TRUNCATE $DIR/$tfile 0
28491         for ((i = 0; i < $num; i++)); do
28492                 offset=$((offset - $bs))
28493                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28494                 local pids[$i]=$!
28495         done
28496         for (( i=0; i < $num; i++ )); do
28497                 wait ${pids[$i]}
28498         done
28499         check_lsom_size $DIR/$tfile $size
28500
28501         # multi-client writes
28502         num=$(get_node_count ${CLIENTS//,/ })
28503         size=$(($num * $bs))
28504         offset=0
28505         i=0
28506
28507         echo "Test SOM for multi-client ($num) writes"
28508         $TRUNCATE $DIR/$tfile 0
28509         for client in ${CLIENTS//,/ }; do
28510                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28511                 local pids[$i]=$!
28512                 i=$((i + 1))
28513                 offset=$((offset + $bs))
28514         done
28515         for (( i=0; i < $num; i++ )); do
28516                 wait ${pids[$i]}
28517         done
28518         check_lsom_size $DIR/$tfile $offset
28519
28520         i=0
28521         $TRUNCATE $DIR/$tfile 0
28522         for client in ${CLIENTS//,/ }; do
28523                 offset=$((offset - $bs))
28524                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28525                 local pids[$i]=$!
28526                 i=$((i + 1))
28527         done
28528         for (( i=0; i < $num; i++ )); do
28529                 wait ${pids[$i]}
28530         done
28531         check_lsom_size $DIR/$tfile $size
28532
28533         # verify truncate
28534         echo "Test SOM for truncate"
28535         $TRUNCATE $DIR/$tfile 1048576
28536         check_lsom_size $DIR/$tfile 1048576
28537         $TRUNCATE $DIR/$tfile 1234
28538         check_lsom_size $DIR/$tfile 1234
28539
28540         # verify SOM blocks count
28541         echo "Verify SOM block count"
28542         $TRUNCATE $DIR/$tfile 0
28543         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28544                 error "failed to write file $tfile"
28545         check_lsom_data $DIR/$tfile
28546 }
28547 run_test 806 "Verify Lazy Size on MDS"
28548
28549 test_807() {
28550         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28551         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28552                 skip "Need MDS version at least 2.11.52"
28553
28554         # Registration step
28555         changelog_register || error "changelog_register failed"
28556         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28557         changelog_users $SINGLEMDS | grep -q $cl_user ||
28558                 error "User $cl_user not found in changelog_users"
28559
28560         rm -rf $DIR/$tdir || error "rm $tdir failed"
28561         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28562         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28563         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28564         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28565                 error "truncate $tdir/trunc failed"
28566
28567         local bs=1048576
28568         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28569                 error "write $tfile failed"
28570
28571         # multi-client wirtes
28572         local num=$(get_node_count ${CLIENTS//,/ })
28573         local offset=0
28574         local i=0
28575
28576         echo "Test SOM for multi-client ($num) writes"
28577         touch $DIR/$tfile || error "touch $tfile failed"
28578         $TRUNCATE $DIR/$tfile 0
28579         for client in ${CLIENTS//,/ }; do
28580                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28581                 local pids[$i]=$!
28582                 i=$((i + 1))
28583                 offset=$((offset + $bs))
28584         done
28585         for (( i=0; i < $num; i++ )); do
28586                 wait ${pids[$i]}
28587         done
28588
28589         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28590         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28591         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28592         check_lsom_data $DIR/$tdir/trunc
28593         check_lsom_data $DIR/$tdir/single_dd
28594         check_lsom_data $DIR/$tfile
28595
28596         rm -rf $DIR/$tdir
28597         # Deregistration step
28598         changelog_deregister || error "changelog_deregister failed"
28599 }
28600 run_test 807 "verify LSOM syncing tool"
28601
28602 check_som_nologged()
28603 {
28604         local lines=$($LFS changelog $FSNAME-MDT0000 |
28605                 grep 'x=trusted.som' | wc -l)
28606         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28607 }
28608
28609 test_808() {
28610         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28611                 skip "Need MDS version at least 2.11.55"
28612
28613         # Registration step
28614         changelog_register || error "changelog_register failed"
28615
28616         touch $DIR/$tfile || error "touch $tfile failed"
28617         check_som_nologged
28618
28619         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28620                 error "write $tfile failed"
28621         check_som_nologged
28622
28623         $TRUNCATE $DIR/$tfile 1234
28624         check_som_nologged
28625
28626         $TRUNCATE $DIR/$tfile 1048576
28627         check_som_nologged
28628
28629         # Deregistration step
28630         changelog_deregister || error "changelog_deregister failed"
28631 }
28632 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28633
28634 check_som_nodata()
28635 {
28636         $LFS getsom $1
28637         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28638 }
28639
28640 test_809() {
28641         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28642                 skip "Need MDS version at least 2.11.56"
28643
28644         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28645                 error "failed to create DoM-only file $DIR/$tfile"
28646         touch $DIR/$tfile || error "touch $tfile failed"
28647         check_som_nodata $DIR/$tfile
28648
28649         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28650                 error "write $tfile failed"
28651         check_som_nodata $DIR/$tfile
28652
28653         $TRUNCATE $DIR/$tfile 1234
28654         check_som_nodata $DIR/$tfile
28655
28656         $TRUNCATE $DIR/$tfile 4097
28657         check_som_nodata $DIR/$file
28658 }
28659 run_test 809 "Verify no SOM xattr store for DoM-only files"
28660
28661 test_810() {
28662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28663         $GSS && skip_env "could not run with gss"
28664         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28665                 skip "OST < 2.12.58 doesn't align checksum"
28666
28667         set_checksums 1
28668         stack_trap "set_checksums $ORIG_CSUM" EXIT
28669         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28670
28671         local csum
28672         local before
28673         local after
28674         for csum in $CKSUM_TYPES; do
28675                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28676                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28677                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28678                         eval set -- $i
28679                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28680                         before=$(md5sum $DIR/$tfile)
28681                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28682                         after=$(md5sum $DIR/$tfile)
28683                         [ "$before" == "$after" ] ||
28684                                 error "$csum: $before != $after bs=$1 seek=$2"
28685                 done
28686         done
28687 }
28688 run_test 810 "partial page writes on ZFS (LU-11663)"
28689
28690 test_812a() {
28691         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28692                 skip "OST < 2.12.51 doesn't support this fail_loc"
28693
28694         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28695         # ensure ost1 is connected
28696         stat $DIR/$tfile >/dev/null || error "can't stat"
28697         wait_osc_import_state client ost1 FULL
28698         # no locks, no reqs to let the connection idle
28699         cancel_lru_locks osc
28700
28701         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28702 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28703         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28704         wait_osc_import_state client ost1 CONNECTING
28705         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28706
28707         stat $DIR/$tfile >/dev/null || error "can't stat file"
28708 }
28709 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28710
28711 test_812b() { # LU-12378
28712         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28713                 skip "OST < 2.12.51 doesn't support this fail_loc"
28714
28715         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28716         # ensure ost1 is connected
28717         stat $DIR/$tfile >/dev/null || error "can't stat"
28718         wait_osc_import_state client ost1 FULL
28719         # no locks, no reqs to let the connection idle
28720         cancel_lru_locks osc
28721
28722         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28723 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28724         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28725         wait_osc_import_state client ost1 CONNECTING
28726         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28727
28728         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28729         wait_osc_import_state client ost1 IDLE
28730 }
28731 run_test 812b "do not drop no resend request for idle connect"
28732
28733 test_812c() {
28734         local old
28735
28736         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28737
28738         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28739         $LFS getstripe $DIR/$tfile
28740         $LCTL set_param osc.*.idle_timeout=10
28741         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28742         # ensure ost1 is connected
28743         stat $DIR/$tfile >/dev/null || error "can't stat"
28744         wait_osc_import_state client ost1 FULL
28745         # no locks, no reqs to let the connection idle
28746         cancel_lru_locks osc
28747
28748 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28749         $LCTL set_param fail_loc=0x80000533
28750         sleep 15
28751         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28752 }
28753 run_test 812c "idle import vs lock enqueue race"
28754
28755 test_813() {
28756         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28757         [ -z "$file_heat_sav" ] && skip "no file heat support"
28758
28759         local readsample
28760         local writesample
28761         local readbyte
28762         local writebyte
28763         local readsample1
28764         local writesample1
28765         local readbyte1
28766         local writebyte1
28767
28768         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28769         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28770
28771         $LCTL set_param -n llite.*.file_heat=1
28772         echo "Turn on file heat"
28773         echo "Period second: $period_second, Decay percentage: $decay_pct"
28774
28775         echo "QQQQ" > $DIR/$tfile
28776         echo "QQQQ" > $DIR/$tfile
28777         echo "QQQQ" > $DIR/$tfile
28778         cat $DIR/$tfile > /dev/null
28779         cat $DIR/$tfile > /dev/null
28780         cat $DIR/$tfile > /dev/null
28781         cat $DIR/$tfile > /dev/null
28782
28783         local out=$($LFS heat_get $DIR/$tfile)
28784
28785         $LFS heat_get $DIR/$tfile
28786         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28787         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28788         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28789         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28790
28791         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28792         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28793         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28794         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28795
28796         sleep $((period_second + 3))
28797         echo "Sleep $((period_second + 3)) seconds..."
28798         # The recursion formula to calculate the heat of the file f is as
28799         # follow:
28800         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28801         # Where Hi is the heat value in the period between time points i*I and
28802         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28803         # to the weight of Ci.
28804         out=$($LFS heat_get $DIR/$tfile)
28805         $LFS heat_get $DIR/$tfile
28806         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28807         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28808         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28809         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28810
28811         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28812                 error "read sample ($readsample) is wrong"
28813         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28814                 error "write sample ($writesample) is wrong"
28815         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28816                 error "read bytes ($readbyte) is wrong"
28817         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28818                 error "write bytes ($writebyte) is wrong"
28819
28820         echo "QQQQ" > $DIR/$tfile
28821         echo "QQQQ" > $DIR/$tfile
28822         echo "QQQQ" > $DIR/$tfile
28823         cat $DIR/$tfile > /dev/null
28824         cat $DIR/$tfile > /dev/null
28825         cat $DIR/$tfile > /dev/null
28826         cat $DIR/$tfile > /dev/null
28827
28828         sleep $((period_second + 3))
28829         echo "Sleep $((period_second + 3)) seconds..."
28830
28831         out=$($LFS heat_get $DIR/$tfile)
28832         $LFS heat_get $DIR/$tfile
28833         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28834         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28835         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28836         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28837
28838         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28839                 4 * $decay_pct) / 100") -eq 1 ] ||
28840                 error "read sample ($readsample1) is wrong"
28841         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28842                 3 * $decay_pct) / 100") -eq 1 ] ||
28843                 error "write sample ($writesample1) is wrong"
28844         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28845                 20 * $decay_pct) / 100") -eq 1 ] ||
28846                 error "read bytes ($readbyte1) is wrong"
28847         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28848                 15 * $decay_pct) / 100") -eq 1 ] ||
28849                 error "write bytes ($writebyte1) is wrong"
28850
28851         echo "Turn off file heat for the file $DIR/$tfile"
28852         $LFS heat_set -o $DIR/$tfile
28853
28854         echo "QQQQ" > $DIR/$tfile
28855         echo "QQQQ" > $DIR/$tfile
28856         echo "QQQQ" > $DIR/$tfile
28857         cat $DIR/$tfile > /dev/null
28858         cat $DIR/$tfile > /dev/null
28859         cat $DIR/$tfile > /dev/null
28860         cat $DIR/$tfile > /dev/null
28861
28862         out=$($LFS heat_get $DIR/$tfile)
28863         $LFS heat_get $DIR/$tfile
28864         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28865         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28866         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28867         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28868
28869         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28870         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28871         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28872         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28873
28874         echo "Trun on file heat for the file $DIR/$tfile"
28875         $LFS heat_set -O $DIR/$tfile
28876
28877         echo "QQQQ" > $DIR/$tfile
28878         echo "QQQQ" > $DIR/$tfile
28879         echo "QQQQ" > $DIR/$tfile
28880         cat $DIR/$tfile > /dev/null
28881         cat $DIR/$tfile > /dev/null
28882         cat $DIR/$tfile > /dev/null
28883         cat $DIR/$tfile > /dev/null
28884
28885         out=$($LFS heat_get $DIR/$tfile)
28886         $LFS heat_get $DIR/$tfile
28887         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28888         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28889         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28890         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28891
28892         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28893         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28894         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28895         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28896
28897         $LFS heat_set -c $DIR/$tfile
28898         $LCTL set_param -n llite.*.file_heat=0
28899         echo "Turn off file heat support for the Lustre filesystem"
28900
28901         echo "QQQQ" > $DIR/$tfile
28902         echo "QQQQ" > $DIR/$tfile
28903         echo "QQQQ" > $DIR/$tfile
28904         cat $DIR/$tfile > /dev/null
28905         cat $DIR/$tfile > /dev/null
28906         cat $DIR/$tfile > /dev/null
28907         cat $DIR/$tfile > /dev/null
28908
28909         out=$($LFS heat_get $DIR/$tfile)
28910         $LFS heat_get $DIR/$tfile
28911         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28912         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28913         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28914         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28915
28916         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28917         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28918         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28919         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28920
28921         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28922         rm -f $DIR/$tfile
28923 }
28924 run_test 813 "File heat verfication"
28925
28926 test_814()
28927 {
28928         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28929         echo -n y >> $DIR/$tfile
28930         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28931         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28932 }
28933 run_test 814 "sparse cp works as expected (LU-12361)"
28934
28935 test_815()
28936 {
28937         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28938         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28939 }
28940 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28941
28942 test_816() {
28943         local ost1_imp=$(get_osc_import_name client ost1)
28944         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28945                          cut -d'.' -f2)
28946
28947         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28948         # ensure ost1 is connected
28949
28950         stat $DIR/$tfile >/dev/null || error "can't stat"
28951         wait_osc_import_state client ost1 FULL
28952         # no locks, no reqs to let the connection idle
28953         cancel_lru_locks osc
28954         lru_resize_disable osc
28955         local before
28956         local now
28957         before=$($LCTL get_param -n \
28958                  ldlm.namespaces.$imp_name.lru_size)
28959
28960         wait_osc_import_state client ost1 IDLE
28961         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28962         now=$($LCTL get_param -n \
28963               ldlm.namespaces.$imp_name.lru_size)
28964         [ $before == $now ] || error "lru_size changed $before != $now"
28965 }
28966 run_test 816 "do not reset lru_resize on idle reconnect"
28967
28968 cleanup_817() {
28969         umount $tmpdir
28970         exportfs -u localhost:$DIR/nfsexp
28971         rm -rf $DIR/nfsexp
28972 }
28973
28974 test_817() {
28975         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28976
28977         mkdir -p $DIR/nfsexp
28978         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28979                 error "failed to export nfs"
28980
28981         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28982         stack_trap cleanup_817 EXIT
28983
28984         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28985                 error "failed to mount nfs to $tmpdir"
28986
28987         cp /bin/true $tmpdir
28988         $DIR/nfsexp/true || error "failed to execute 'true' command"
28989 }
28990 run_test 817 "nfsd won't cache write lock for exec file"
28991
28992 test_818() {
28993         test_mkdir -i0 -c1 $DIR/$tdir
28994         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28995         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28996         stop $SINGLEMDS
28997
28998         # restore osp-syn threads
28999         stack_trap "fail $SINGLEMDS"
29000
29001         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29002         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29003         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29004                 error "start $SINGLEMDS failed"
29005         rm -rf $DIR/$tdir
29006
29007         local testid=$(echo $TESTNAME | tr '_' ' ')
29008
29009         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29010                 grep "run LFSCK" || error "run LFSCK is not suggested"
29011 }
29012 run_test 818 "unlink with failed llog"
29013
29014 test_819a() {
29015         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29016         cancel_lru_locks osc
29017         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29018         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29019         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29020         rm -f $TDIR/$tfile
29021 }
29022 run_test 819a "too big niobuf in read"
29023
29024 test_819b() {
29025         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29026         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29027         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29028         cancel_lru_locks osc
29029         sleep 1
29030         rm -f $TDIR/$tfile
29031 }
29032 run_test 819b "too big niobuf in write"
29033
29034
29035 function test_820_start_ost() {
29036         sleep 5
29037
29038         for num in $(seq $OSTCOUNT); do
29039                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29040         done
29041 }
29042
29043 test_820() {
29044         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29045
29046         mkdir $DIR/$tdir
29047         umount_client $MOUNT || error "umount failed"
29048         for num in $(seq $OSTCOUNT); do
29049                 stop ost$num
29050         done
29051
29052         # mount client with no active OSTs
29053         # so that the client can't initialize max LOV EA size
29054         # from OSC notifications
29055         mount_client $MOUNT || error "mount failed"
29056         # delay OST starting to keep this 0 max EA size for a while
29057         test_820_start_ost &
29058
29059         # create a directory on MDS2
29060         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29061                 error "Failed to create directory"
29062         # open intent should update default EA size
29063         # see mdc_update_max_ea_from_body()
29064         # notice this is the very first RPC to MDS2
29065         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29066         ret=$?
29067         echo $out
29068         # With SSK, this situation can lead to -EPERM being returned.
29069         # In that case, simply retry.
29070         if [ $ret -ne 0 ] && $SHARED_KEY; then
29071                 if echo "$out" | grep -q "not permitted"; then
29072                         cp /etc/services $DIR/$tdir/mds2
29073                         ret=$?
29074                 fi
29075         fi
29076         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29077 }
29078 run_test 820 "update max EA from open intent"
29079
29080 test_823() {
29081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29082         local OST_MAX_PRECREATE=20000
29083
29084         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29085                 skip "Need MDS version at least 2.14.56"
29086
29087         save_lustre_params mds1 \
29088                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29089         do_facet $SINGLEMDS "$LCTL set_param -n \
29090                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29091         do_facet $SINGLEMDS "$LCTL set_param -n \
29092                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29093
29094         stack_trap "restore_lustre_params < $p; rm $p"
29095
29096         do_facet $SINGLEMDS "$LCTL set_param -n \
29097                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29098
29099         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29100                       osp.$FSNAME-OST0000*MDT0000.create_count")
29101         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29102                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29103         local expect_count=$(((($max/2)/256) * 256))
29104
29105         log "setting create_count to 100200:"
29106         log " -result- count: $count with max: $max, expecting: $expect_count"
29107
29108         [[ $count -eq expect_count ]] ||
29109                 error "Create count not set to max precreate."
29110 }
29111 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29112
29113 test_831() {
29114         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29115                 skip "Need MDS version 2.14.56"
29116
29117         local sync_changes=$(do_facet $SINGLEMDS \
29118                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29119
29120         [ "$sync_changes" -gt 100 ] &&
29121                 skip "Sync changes $sync_changes > 100 already"
29122
29123         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29124
29125         $LFS mkdir -i 0 $DIR/$tdir
29126         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29127
29128         save_lustre_params mds1 \
29129                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29130         save_lustre_params mds1 \
29131                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29132
29133         do_facet mds1 "$LCTL set_param -n \
29134                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29135                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29136         stack_trap "restore_lustre_params < $p" EXIT
29137
29138         createmany -o $DIR/$tdir/f- 1000
29139         unlinkmany $DIR/$tdir/f- 1000 &
29140         local UNLINK_PID=$!
29141
29142         while sleep 1; do
29143                 sync_changes=$(do_facet mds1 \
29144                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29145                 # the check in the code is racy, fail the test
29146                 # if the value above the limit by 10.
29147                 [ $sync_changes -gt 110 ] && {
29148                         kill -2 $UNLINK_PID
29149                         wait
29150                         error "osp changes throttling failed, $sync_changes>110"
29151                 }
29152                 kill -0 $UNLINK_PID 2> /dev/null || break
29153         done
29154         wait
29155 }
29156 run_test 831 "throttling unlink/setattr queuing on OSP"
29157
29158 test_832() {
29159         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29160         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29161                 skip "Need MDS version 2.15.52+"
29162         is_rmentry_supported || skip "rm_entry not supported"
29163
29164         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29165         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29166         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29167                 error "mkdir remote_dir failed"
29168         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29169                 error "mkdir striped_dir failed"
29170         touch $DIR/$tdir/file || error "touch file failed"
29171         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29172         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29173 }
29174 run_test 832 "lfs rm_entry"
29175
29176 #
29177 # tests that do cleanup/setup should be run at the end
29178 #
29179
29180 test_900() {
29181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29182         local ls
29183
29184         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29185         $LCTL set_param fail_loc=0x903
29186
29187         cancel_lru_locks MGC
29188
29189         FAIL_ON_ERROR=true cleanup
29190         FAIL_ON_ERROR=true setup
29191 }
29192 run_test 900 "umount should not race with any mgc requeue thread"
29193
29194 # LUS-6253/LU-11185
29195 test_901() {
29196         local old
29197         local count
29198         local oldc
29199         local newc
29200         local olds
29201         local news
29202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29203
29204         # some get_param have a bug to handle dot in param name
29205         cancel_lru_locks MGC
29206         old=$(mount -t lustre | wc -l)
29207         # 1 config+sptlrpc
29208         # 2 params
29209         # 3 nodemap
29210         # 4 IR
29211         old=$((old * 4))
29212         oldc=0
29213         count=0
29214         while [ $old -ne $oldc ]; do
29215                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29216                 sleep 1
29217                 ((count++))
29218                 if [ $count -ge $TIMEOUT ]; then
29219                         error "too large timeout"
29220                 fi
29221         done
29222         umount_client $MOUNT || error "umount failed"
29223         mount_client $MOUNT || error "mount failed"
29224         cancel_lru_locks MGC
29225         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29226
29227         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29228
29229         return 0
29230 }
29231 run_test 901 "don't leak a mgc lock on client umount"
29232
29233 # LU-13377
29234 test_902() {
29235         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29236                 skip "client does not have LU-13377 fix"
29237         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29238         $LCTL set_param fail_loc=0x1415
29239         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29240         cancel_lru_locks osc
29241         rm -f $DIR/$tfile
29242 }
29243 run_test 902 "test short write doesn't hang lustre"
29244
29245 # LU-14711
29246 test_903() {
29247         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29248         echo "blah" > $DIR/${tfile}-2
29249         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29250         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29251         $LCTL set_param fail_loc=0x417 fail_val=20
29252
29253         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29254         sleep 1 # To start the destroy
29255         wait_destroy_complete 150 || error "Destroy taking too long"
29256         cat $DIR/$tfile > /dev/null || error "Evicted"
29257 }
29258 run_test 903 "Test long page discard does not cause evictions"
29259
29260 test_904() {
29261         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29262         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29263                 grep -q project || skip "skip project quota not supported"
29264
29265         local testfile="$DIR/$tdir/$tfile"
29266         local xattr="trusted.projid"
29267         local projid
29268         local mdts=$(comma_list $(mdts_nodes))
29269         local saved=$(do_facet mds1 $LCTL get_param -n \
29270                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29271
29272         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29273         stack_trap "do_nodes $mdts $LCTL set_param \
29274                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29275
29276         mkdir -p $DIR/$tdir
29277         touch $testfile
29278         #hide projid xattr on server
29279         $LFS project -p 1 $testfile ||
29280                 error "set $testfile project id failed"
29281         getfattr -m - $testfile | grep $xattr &&
29282                 error "do not show trusted.projid when disabled on server"
29283         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29284         #should be hidden when projid is 0
29285         $LFS project -p 0 $testfile ||
29286                 error "set $testfile project id failed"
29287         getfattr -m - $testfile | grep $xattr &&
29288                 error "do not show trusted.projid with project ID 0"
29289
29290         #still can getxattr explicitly
29291         projid=$(getfattr -n $xattr $testfile |
29292                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29293         [ $projid == "0" ] ||
29294                 error "projid expected 0 not $projid"
29295
29296         #set the projid via setxattr
29297         setfattr -n $xattr -v "1000" $testfile ||
29298                 error "setattr failed with $?"
29299         projid=($($LFS project $testfile))
29300         [ ${projid[0]} == "1000" ] ||
29301                 error "projid expected 1000 not $projid"
29302
29303         #check the new projid via getxattr
29304         $LFS project -p 1001 $testfile ||
29305                 error "set $testfile project id failed"
29306         getfattr -m - $testfile | grep $xattr ||
29307                 error "should show trusted.projid when project ID != 0"
29308         projid=$(getfattr -n $xattr $testfile |
29309                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29310         [ $projid == "1001" ] ||
29311                 error "projid expected 1001 not $projid"
29312
29313         #try to set invalid projid
29314         setfattr -n $xattr -v "4294967295" $testfile &&
29315                 error "set invalid projid should fail"
29316
29317         #remove the xattr means setting projid to 0
29318         setfattr -x $xattr $testfile ||
29319                 error "setfattr failed with $?"
29320         projid=($($LFS project $testfile))
29321         [ ${projid[0]} == "0" ] ||
29322                 error "projid expected 0 not $projid"
29323
29324         #should be hidden when parent has inherit flag and same projid
29325         $LFS project -srp 1002 $DIR/$tdir ||
29326                 error "set $tdir project id failed"
29327         getfattr -m - $testfile | grep $xattr &&
29328                 error "do not show trusted.projid with inherit flag"
29329
29330         #still can getxattr explicitly
29331         projid=$(getfattr -n $xattr $testfile |
29332                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29333         [ $projid == "1002" ] ||
29334                 error "projid expected 1002 not $projid"
29335 }
29336 run_test 904 "virtual project ID xattr"
29337
29338 # LU-8582
29339 test_905() {
29340         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29341                 skip "lustre < 2.8.54 does not support ladvise"
29342
29343         remote_ost_nodsh && skip "remote OST with nodsh"
29344         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29345
29346         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29347
29348         #define OBD_FAIL_OST_OPCODE 0x253
29349         # OST_LADVISE = 21
29350         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29351         $LFS ladvise -a willread $DIR/$tfile &&
29352                 error "unexpected success of ladvise with fault injection"
29353         $LFS ladvise -a willread $DIR/$tfile |&
29354                 grep -q "Operation not supported"
29355         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29356 }
29357 run_test 905 "bad or new opcode should not stuck client"
29358
29359 test_906() {
29360         grep -q io_uring_setup /proc/kallsyms ||
29361                 skip "Client OS does not support io_uring I/O engine"
29362         io_uring_probe || skip "kernel does not support io_uring fully"
29363         which fio || skip_env "no fio installed"
29364         fio --enghelp | grep -q io_uring ||
29365                 skip_env "fio does not support io_uring I/O engine"
29366
29367         local file=$DIR/$tfile
29368         local ioengine="io_uring"
29369         local numjobs=2
29370         local size=50M
29371
29372         fio --name=seqwrite --ioengine=$ioengine        \
29373                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29374                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29375                 error "fio seqwrite $file failed"
29376
29377         fio --name=seqread --ioengine=$ioengine \
29378                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29379                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29380                 error "fio seqread $file failed"
29381
29382         rm -f $file || error "rm -f $file failed"
29383 }
29384 run_test 906 "Simple test for io_uring I/O engine via fio"
29385
29386
29387 complete $SECONDS
29388 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29389 check_and_cleanup_lustre
29390 if [ "$I_MOUNTED" != "yes" ]; then
29391         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29392 fi
29393 exit_status