Whamcloud - gitweb
63b36ac7107f39ae80d2a8712a64829ef2baf41d
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 #                                  5              12     8   12  15   (min)"
66 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
67
68 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
69         #                                               13    (min)"
70         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
71 fi
72
73 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
74         always_except LU-1941 130b 130c 130d 130e 130f 130g
75         always_except LU-9054 312
76 fi
77
78 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
79
80 # Get the SLES distro version
81 #
82 # Returns a version string that should only be used in comparing
83 # strings returned by version_code()
84 sles_version_code()
85 {
86         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
87
88         # All SuSE Linux versions have one decimal. version_code expects two
89         local sles_version=$version.0
90         version_code $sles_version
91 }
92
93 # Check if we are running on Ubuntu or SLES so we can make decisions on
94 # what tests to run
95 if [ -r /etc/SuSE-release ]; then
96         sles_version=$(sles_version_code)
97         [ $sles_version -lt $(version_code 11.4.0) ] &&
98                 always_except LU-4341 170
99
100         [ $sles_version -lt $(version_code 12.0.0) ] &&
101                 always_except LU-3703 234
102 elif [ -r /etc/os-release ]; then
103         if grep -qi ubuntu /etc/os-release; then
104                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
105                                                 -e 's/^VERSION=//p' \
106                                                 /etc/os-release |
107                                                 awk '{ print $1 }'))
108
109                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
110                         always_except LU-10366 410
111                 fi
112         fi
113 fi
114
115 build_test_filter
116 FAIL_ON_ERROR=false
117
118 cleanup() {
119         echo -n "cln.."
120         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
121         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
122 }
123 setup() {
124         echo -n "mnt.."
125         load_modules
126         setupall || exit 10
127         echo "done"
128 }
129
130 check_swap_layouts_support()
131 {
132         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
133                 skip "Does not support layout lock."
134 }
135
136 check_swap_layout_no_dom()
137 {
138         local FOLDER=$1
139         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
140         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
141 }
142
143 check_and_setup_lustre
144 DIR=${DIR:-$MOUNT}
145 assert_DIR
146
147 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
148
149 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
150 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
151 rm -rf $DIR/[Rdfs][0-9]*
152
153 # $RUNAS_ID may get set incorrectly somewhere else
154 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
155         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
156
157 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
158
159 if [ "${ONLY}" = "MOUNT" ] ; then
160         echo "Lustre is up, please go on"
161         exit
162 fi
163
164 echo "preparing for tests involving mounts"
165 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
166 touch $EXT2_DEV
167 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
168 echo # add a newline after mke2fs.
169
170 umask 077
171
172 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
173 lctl set_param debug=-1 2> /dev/null || true
174 test_0a() {
175         touch $DIR/$tfile
176         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
177         rm $DIR/$tfile
178         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
179 }
180 run_test 0a "touch; rm ====================="
181
182 test_0b() {
183         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
184         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
185 }
186 run_test 0b "chmod 0755 $DIR ============================="
187
188 test_0c() {
189         $LCTL get_param mdc.*.import | grep "state: FULL" ||
190                 error "import not FULL"
191         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
192                 error "bad target"
193 }
194 run_test 0c "check import proc"
195
196 test_0d() { # LU-3397
197         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
198                 skip "proc exports not supported before 2.10.57"
199
200         local mgs_exp="mgs.MGS.exports"
201         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
202         local exp_client_nid
203         local exp_client_version
204         local exp_val
205         local imp_val
206         local temp_imp=$DIR/$tfile.import
207         local temp_exp=$DIR/$tfile.export
208
209         # save mgc import file to $temp_imp
210         $LCTL get_param mgc.*.import | tee $temp_imp
211         # Check if client uuid is found in MGS export
212         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
213                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
214                         $client_uuid ] &&
215                         break;
216         done
217         # save mgs export file to $temp_exp
218         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
219
220         # Compare the value of field "connect_flags"
221         imp_val=$(grep "connect_flags" $temp_imp)
222         exp_val=$(grep "connect_flags" $temp_exp)
223         [ "$exp_val" == "$imp_val" ] ||
224                 error "export flags '$exp_val' != import flags '$imp_val'"
225
226         # Compare client versions.  Only compare top-3 fields for compatibility
227         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
228         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
229         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
230         [ "$exp_val" == "$imp_val" ] ||
231                 error "exp version '$exp_client_version'($exp_val) != " \
232                         "'$(lustre_build_version client)'($imp_val)"
233 }
234 run_test 0d "check export proc ============================="
235
236 test_0e() { # LU-13417
237         (( $MDSCOUNT > 1 )) ||
238                 skip "We need at least 2 MDTs for this test"
239
240         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
241                 skip "Need server version at least 2.14.51"
242
243         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
244         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
245
246         [ $default_lmv_count -eq 1 ] ||
247                 error "$MOUNT default stripe count $default_lmv_count"
248
249         [ $default_lmv_index -eq -1 ] ||
250                 error "$MOUNT default stripe index $default_lmv_index"
251
252         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
253         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
254
255         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
256         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
257
258         [ $mdt_index1 -eq $mdt_index2 ] &&
259                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
260
261         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
262 }
263 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
264
265 test_1() {
266         test_mkdir $DIR/$tdir
267         test_mkdir $DIR/$tdir/d2
268         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
269         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
270         rmdir $DIR/$tdir/d2
271         rmdir $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
273 }
274 run_test 1 "mkdir; remkdir; rmdir"
275
276 test_2() {
277         test_mkdir $DIR/$tdir
278         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
279         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
280         rm -r $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
282 }
283 run_test 2 "mkdir; touch; rmdir; check file"
284
285 test_3() {
286         test_mkdir $DIR/$tdir
287         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
288         touch $DIR/$tdir/$tfile
289         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
290         rm -r $DIR/$tdir
291         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
292 }
293 run_test 3 "mkdir; touch; rmdir; check dir"
294
295 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
296 test_4() {
297         test_mkdir -i 1 $DIR/$tdir
298
299         touch $DIR/$tdir/$tfile ||
300                 error "Create file under remote directory failed"
301
302         rmdir $DIR/$tdir &&
303                 error "Expect error removing in-use dir $DIR/$tdir"
304
305         test -d $DIR/$tdir || error "Remote directory disappeared"
306
307         rm -rf $DIR/$tdir || error "remove remote dir error"
308 }
309 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
310
311 test_5() {
312         test_mkdir $DIR/$tdir
313         test_mkdir $DIR/$tdir/d2
314         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
315         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
316         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
317 }
318 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
319
320 test_6a() {
321         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
322         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
323         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
324                 error "$tfile does not have perm 0666 or UID $UID"
325         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile should be 0666 and owned by UID $UID"
328 }
329 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
330
331 test_6c() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         touch $DIR/$tfile
335         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
336         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
337                 error "$tfile should be owned by UID $RUNAS_ID"
338         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341 }
342 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
343
344 test_6e() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by GID $UID"
351         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
354 }
355 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
356
357 test_6g() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         test_mkdir $DIR/$tdir
361         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
362         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
363         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
364         test_mkdir $DIR/$tdir/d/subdir
365         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
366                 error "$tdir/d/subdir should be GID $RUNAS_GID"
367         if [[ $MDSCOUNT -gt 1 ]]; then
368                 # check remote dir sgid inherite
369                 $LFS mkdir -i 0 $DIR/$tdir.local ||
370                         error "mkdir $tdir.local failed"
371                 chmod g+s $DIR/$tdir.local ||
372                         error "chmod $tdir.local failed"
373                 chgrp $RUNAS_GID $DIR/$tdir.local ||
374                         error "chgrp $tdir.local failed"
375                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
376                         error "mkdir $tdir.remote failed"
377                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
378                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
379                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
380                         error "$tdir.remote should be mode 02755"
381         fi
382 }
383 run_test 6g "verify new dir in sgid dir inherits group"
384
385 test_6h() { # bug 7331
386         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
387
388         touch $DIR/$tfile || error "touch failed"
389         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
390         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
391                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
392         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
393                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
394 }
395 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
396
397 test_7a() {
398         test_mkdir $DIR/$tdir
399         $MCREATE $DIR/$tdir/$tfile
400         chmod 0666 $DIR/$tdir/$tfile
401         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
402                 error "$tdir/$tfile should be mode 0666"
403 }
404 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
405
406 test_7b() {
407         if [ ! -d $DIR/$tdir ]; then
408                 test_mkdir $DIR/$tdir
409         fi
410         $MCREATE $DIR/$tdir/$tfile
411         echo -n foo > $DIR/$tdir/$tfile
412         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
413         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
414 }
415 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
416
417 test_8() {
418         test_mkdir $DIR/$tdir
419         touch $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tfile mode not 0666"
423 }
424 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
425
426 test_9() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         test_mkdir $DIR/$tdir/d2/d3
430         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
431 }
432 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
433
434 test_10() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         touch $DIR/$tdir/d2/$tfile
438         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
439                 error "$tdir/d2/$tfile not a file"
440 }
441 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
442
443 test_11() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         chmod 0666 $DIR/$tdir/d2
447         chmod 0705 $DIR/$tdir/d2
448         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
449                 error "$tdir/d2 mode not 0705"
450 }
451 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
452
453 test_12() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         chmod 0666 $DIR/$tdir/$tfile
457         chmod 0654 $DIR/$tdir/$tfile
458         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
459                 error "$tdir/d2 mode not 0654"
460 }
461 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
462
463 test_13() {
464         test_mkdir $DIR/$tdir
465         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
466         >  $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
468                 error "$tdir/$tfile size not 0 after truncate"
469 }
470 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
471
472 test_14() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         rm $DIR/$tdir/$tfile
476         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
477 }
478 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
479
480 test_15() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
484         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
485                 error "$tdir/${tfile_2} not a file after rename"
486         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
487 }
488 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
489
490 test_16() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         rm -rf $DIR/$tdir/$tfile
494         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
495 }
496 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
497
498 test_17a() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
502         ls -l $DIR/$tdir
503         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
504                 error "$tdir/l-exist not a symlink"
505         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
506                 error "$tdir/l-exist not referencing a file"
507         rm -f $DIR/$tdir/l-exist
508         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
509 }
510 run_test 17a "symlinks: create, remove (real)"
511
512 test_17b() {
513         test_mkdir $DIR/$tdir
514         ln -s no-such-file $DIR/$tdir/l-dangle
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
517                 error "$tdir/l-dangle not referencing no-such-file"
518         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
519                 error "$tdir/l-dangle not referencing non-existent file"
520         rm -f $DIR/$tdir/l-dangle
521         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
522 }
523 run_test 17b "symlinks: create, remove (dangling)"
524
525 test_17c() { # bug 3440 - don't save failed open RPC for replay
526         test_mkdir $DIR/$tdir
527         ln -s foo $DIR/$tdir/$tfile
528         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
529 }
530 run_test 17c "symlinks: open dangling (should return error)"
531
532 test_17d() {
533         test_mkdir $DIR/$tdir
534         ln -s foo $DIR/$tdir/$tfile
535         touch $DIR/$tdir/$tfile || error "creating to new symlink"
536 }
537 run_test 17d "symlinks: create dangling"
538
539 test_17e() {
540         test_mkdir $DIR/$tdir
541         local foo=$DIR/$tdir/$tfile
542         ln -s $foo $foo || error "create symlink failed"
543         ls -l $foo || error "ls -l failed"
544         ls $foo && error "ls not failed" || true
545 }
546 run_test 17e "symlinks: create recursive symlink (should return error)"
547
548 test_17f() {
549         test_mkdir $DIR/$tdir
550         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
556         ls -l  $DIR/$tdir
557 }
558 run_test 17f "symlinks: long and very long symlink name"
559
560 # str_repeat(S, N) generate a string that is string S repeated N times
561 str_repeat() {
562         local s=$1
563         local n=$2
564         local ret=''
565         while [ $((n -= 1)) -ge 0 ]; do
566                 ret=$ret$s
567         done
568         echo $ret
569 }
570
571 # Long symlinks and LU-2241
572 test_17g() {
573         test_mkdir $DIR/$tdir
574         local TESTS="59 60 61 4094 4095"
575
576         # Fix for inode size boundary in 2.1.4
577         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
578                 TESTS="4094 4095"
579
580         # Patch not applied to 2.2 or 2.3 branches
581         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
582         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
583                 TESTS="4094 4095"
584
585         for i in $TESTS; do
586                 local SYMNAME=$(str_repeat 'x' $i)
587                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
588                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
589         done
590 }
591 run_test 17g "symlinks: really long symlink name and inode boundaries"
592
593 test_17h() { #bug 17378
594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
595         remote_mds_nodsh && skip "remote MDS with nodsh"
596
597         local mdt_idx
598
599         test_mkdir $DIR/$tdir
600         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
601         $LFS setstripe -c -1 $DIR/$tdir
602         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
603         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
604         touch $DIR/$tdir/$tfile || true
605 }
606 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
607
608 test_17i() { #bug 20018
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         remote_mds_nodsh && skip "remote MDS with nodsh"
611
612         local foo=$DIR/$tdir/$tfile
613         local mdt_idx
614
615         test_mkdir -c1 $DIR/$tdir
616         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
617         ln -s $foo $foo || error "create symlink failed"
618 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
619         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
620         ls -l $foo && error "error not detected"
621         return 0
622 }
623 run_test 17i "don't panic on short symlink (should return error)"
624
625 test_17k() { #bug 22301
626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
627         [[ -z "$(which rsync 2>/dev/null)" ]] &&
628                 skip "no rsync command"
629         rsync --help | grep -q xattr ||
630                 skip_env "$(rsync --version | head -n1) does not support xattrs"
631         test_mkdir $DIR/$tdir
632         test_mkdir $DIR/$tdir.new
633         touch $DIR/$tdir/$tfile
634         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
635         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
636                 error "rsync failed with xattrs enabled"
637 }
638 run_test 17k "symlinks: rsync with xattrs enabled"
639
640 test_17l() { # LU-279
641         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
642                 skip "no getfattr command"
643
644         test_mkdir $DIR/$tdir
645         touch $DIR/$tdir/$tfile
646         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
647         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
648                 # -h to not follow symlinks. -m '' to list all the xattrs.
649                 # grep to remove first line: '# file: $path'.
650                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
651                 do
652                         lgetxattr_size_check $path $xattr ||
653                                 error "lgetxattr_size_check $path $xattr failed"
654                 done
655         done
656 }
657 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
658
659 # LU-1540
660 test_17m() {
661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
663         remote_mds_nodsh && skip "remote MDS with nodsh"
664         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
665         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
666                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
667
668         local short_sym="0123456789"
669         local wdir=$DIR/$tdir
670         local i
671
672         test_mkdir $wdir
673         long_sym=$short_sym
674         # create a long symlink file
675         for ((i = 0; i < 4; ++i)); do
676                 long_sym=${long_sym}${long_sym}
677         done
678
679         echo "create 512 short and long symlink files under $wdir"
680         for ((i = 0; i < 256; ++i)); do
681                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
682                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
683         done
684
685         echo "erase them"
686         rm -f $wdir/*
687         sync
688         wait_delete_completed
689
690         echo "recreate the 512 symlink files with a shorter string"
691         for ((i = 0; i < 512; ++i)); do
692                 # rewrite the symlink file with a shorter string
693                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
694                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
695         done
696
697         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
698
699         echo "stop and checking mds${mds_index}:"
700         # e2fsck should not return error
701         stop mds${mds_index}
702         local devname=$(mdsdevname $mds_index)
703         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
704         rc=$?
705
706         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
707                 error "start mds${mds_index} failed"
708         df $MOUNT > /dev/null 2>&1
709         [ $rc -eq 0 ] ||
710                 error "e2fsck detected error for short/long symlink: rc=$rc"
711         rm -f $wdir/*
712 }
713 run_test 17m "run e2fsck against MDT which contains short/long symlink"
714
715 check_fs_consistency_17n() {
716         local mdt_index
717         local rc=0
718
719         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
720         # so it only check MDT1/MDT2 instead of all of MDTs.
721         for mdt_index in 1 2; do
722                 # e2fsck should not return error
723                 stop mds${mdt_index}
724                 local devname=$(mdsdevname $mdt_index)
725                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
726                         rc=$((rc + $?))
727
728                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
729                         error "mount mds$mdt_index failed"
730                 df $MOUNT > /dev/null 2>&1
731         done
732         return $rc
733 }
734
735 test_17n() {
736         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
738         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
739         remote_mds_nodsh && skip "remote MDS with nodsh"
740         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
741         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
742                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
743
744         local i
745
746         test_mkdir $DIR/$tdir
747         for ((i=0; i<10; i++)); do
748                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
749                         error "create remote dir error $i"
750                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
751                         error "create files under remote dir failed $i"
752         done
753
754         check_fs_consistency_17n ||
755                 error "e2fsck report error after create files under remote dir"
756
757         for ((i = 0; i < 10; i++)); do
758                 rm -rf $DIR/$tdir/remote_dir_${i} ||
759                         error "destroy remote dir error $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after unlink files under remote dir"
764
765         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
766                 skip "lustre < 2.4.50 does not support migrate mv"
767
768         for ((i = 0; i < 10; i++)); do
769                 mkdir -p $DIR/$tdir/remote_dir_${i}
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
773                         error "migrate remote dir error $i"
774         done
775         check_fs_consistency_17n || error "e2fsck report error after migration"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n || error "e2fsck report error after unlink"
783 }
784 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
785
786 test_17o() {
787         remote_mds_nodsh && skip "remote MDS with nodsh"
788         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
789                 skip "Need MDS version at least 2.3.64"
790
791         local wdir=$DIR/${tdir}o
792         local mdt_index
793         local rc=0
794
795         test_mkdir $wdir
796         touch $wdir/$tfile
797         mdt_index=$($LFS getstripe -m $wdir/$tfile)
798         mdt_index=$((mdt_index + 1))
799
800         cancel_lru_locks mdc
801         #fail mds will wait the failover finish then set
802         #following fail_loc to avoid interfer the recovery process.
803         fail mds${mdt_index}
804
805         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
806         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
807         ls -l $wdir/$tfile && rc=1
808         do_facet mds${mdt_index} lctl set_param fail_loc=0
809         [[ $rc -eq 0 ]] || error "stat file should fail"
810 }
811 run_test 17o "stat file with incompat LMA feature"
812
813 test_18() {
814         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
815         ls $DIR || error "Failed to ls $DIR: $?"
816 }
817 run_test 18 "touch .../f ; ls ... =============================="
818
819 test_19a() {
820         touch $DIR/$tfile
821         ls -l $DIR
822         rm $DIR/$tfile
823         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
824 }
825 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
826
827 test_19b() {
828         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
829 }
830 run_test 19b "ls -l .../f19 (should return error) =============="
831
832 test_19c() {
833         [ $RUNAS_ID -eq $UID ] &&
834                 skip_env "RUNAS_ID = UID = $UID -- skipping"
835
836         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
837 }
838 run_test 19c "$RUNAS touch .../f19 (should return error) =="
839
840 test_19d() {
841         cat $DIR/f19 && error || true
842 }
843 run_test 19d "cat .../f19 (should return error) =============="
844
845 test_20() {
846         touch $DIR/$tfile
847         rm $DIR/$tfile
848         touch $DIR/$tfile
849         rm $DIR/$tfile
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
853 }
854 run_test 20 "touch .../f ; ls -l ..."
855
856 test_21() {
857         test_mkdir $DIR/$tdir
858         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
859         ln -s dangle $DIR/$tdir/link
860         echo foo >> $DIR/$tdir/link
861         cat $DIR/$tdir/dangle
862         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
863         $CHECKSTAT -f -t file $DIR/$tdir/link ||
864                 error "$tdir/link not linked to a file"
865 }
866 run_test 21 "write to dangling link"
867
868 test_22() {
869         local wdir=$DIR/$tdir
870         test_mkdir $wdir
871         chown $RUNAS_ID:$RUNAS_GID $wdir
872         (cd $wdir || error "cd $wdir failed";
873                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
874                 $RUNAS tar xf -)
875         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
876         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
877         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
878                 error "checkstat -u failed"
879 }
880 run_test 22 "unpack tar archive as non-root user"
881
882 # was test_23
883 test_23a() {
884         test_mkdir $DIR/$tdir
885         local file=$DIR/$tdir/$tfile
886
887         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
888         openfile -f O_CREAT:O_EXCL $file &&
889                 error "$file recreate succeeded" || true
890 }
891 run_test 23a "O_CREAT|O_EXCL in subdir"
892
893 test_23b() { # bug 18988
894         test_mkdir $DIR/$tdir
895         local file=$DIR/$tdir/$tfile
896
897         rm -f $file
898         echo foo > $file || error "write filed"
899         echo bar >> $file || error "append filed"
900         $CHECKSTAT -s 8 $file || error "wrong size"
901         rm $file
902 }
903 run_test 23b "O_APPEND check"
904
905 # LU-9409, size with O_APPEND and tiny writes
906 test_23c() {
907         local file=$DIR/$tfile
908
909         # single dd
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
911         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
912         rm -f $file
913
914         # racing tiny writes
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
917         wait
918         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
919         rm -f $file
920
921         #racing tiny & normal writes
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
924         wait
925         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
926         rm -f $file
927
928         #racing tiny & normal writes 2, ugly numbers
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
931         wait
932         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
933         rm -f $file
934 }
935 run_test 23c "O_APPEND size checks for tiny writes"
936
937 # LU-11069 file offset is correct after appending writes
938 test_23d() {
939         local file=$DIR/$tfile
940         local offset
941
942         echo CentaurHauls > $file
943         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
944         if ((offset != 26)); then
945                 error "wrong offset, expected 26, got '$offset'"
946         fi
947 }
948 run_test 23d "file offset is correct after appending writes"
949
950 # rename sanity
951 test_24a() {
952         echo '-- same directory rename'
953         test_mkdir $DIR/$tdir
954         touch $DIR/$tdir/$tfile.1
955         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
956         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
957 }
958 run_test 24a "rename file to non-existent target"
959
960 test_24b() {
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.{1,2}
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24b "rename file to existing target"
968
969 test_24c() {
970         test_mkdir $DIR/$tdir
971         test_mkdir $DIR/$tdir/d$testnum.1
972         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
973         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
974         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
975 }
976 run_test 24c "rename directory to non-existent target"
977
978 test_24d() {
979         test_mkdir -c1 $DIR/$tdir
980         test_mkdir -c1 $DIR/$tdir/d$testnum.1
981         test_mkdir -c1 $DIR/$tdir/d$testnum.2
982         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
983         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
984         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
985 }
986 run_test 24d "rename directory to existing target"
987
988 test_24e() {
989         echo '-- cross directory renames --'
990         test_mkdir $DIR/R5a
991         test_mkdir $DIR/R5b
992         touch $DIR/R5a/f
993         mv $DIR/R5a/f $DIR/R5b/g
994         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
995         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
996 }
997 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
998
999 test_24f() {
1000         test_mkdir $DIR/R6a
1001         test_mkdir $DIR/R6b
1002         touch $DIR/R6a/f $DIR/R6b/g
1003         mv $DIR/R6a/f $DIR/R6b/g
1004         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1005         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1006 }
1007 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1008
1009 test_24g() {
1010         test_mkdir $DIR/R7a
1011         test_mkdir $DIR/R7b
1012         test_mkdir $DIR/R7a/d
1013         mv $DIR/R7a/d $DIR/R7b/e
1014         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1015         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1016 }
1017 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1018
1019 test_24h() {
1020         test_mkdir -c1 $DIR/R8a
1021         test_mkdir -c1 $DIR/R8b
1022         test_mkdir -c1 $DIR/R8a/d
1023         test_mkdir -c1 $DIR/R8b/e
1024         mrename $DIR/R8a/d $DIR/R8b/e
1025         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1026         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1027 }
1028 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1029
1030 test_24i() {
1031         echo "-- rename error cases"
1032         test_mkdir $DIR/R9
1033         test_mkdir $DIR/R9/a
1034         touch $DIR/R9/f
1035         mrename $DIR/R9/f $DIR/R9/a
1036         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1037         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1038         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1039 }
1040 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1041
1042 test_24j() {
1043         test_mkdir $DIR/R10
1044         mrename $DIR/R10/f $DIR/R10/g
1045         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1046         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1047         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1048 }
1049 run_test 24j "source does not exist ============================"
1050
1051 test_24k() {
1052         test_mkdir $DIR/R11a
1053         test_mkdir $DIR/R11a/d
1054         touch $DIR/R11a/f
1055         mv $DIR/R11a/f $DIR/R11a/d
1056         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1057         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1058 }
1059 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1060
1061 # bug 2429 - rename foo foo foo creates invalid file
1062 test_24l() {
1063         f="$DIR/f24l"
1064         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1065 }
1066 run_test 24l "Renaming a file to itself ========================"
1067
1068 test_24m() {
1069         f="$DIR/f24m"
1070         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1071         # on ext3 this does not remove either the source or target files
1072         # though the "expected" operation would be to remove the source
1073         $CHECKSTAT -t file ${f} || error "${f} missing"
1074         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1075 }
1076 run_test 24m "Renaming a file to a hard link to itself ========="
1077
1078 test_24n() {
1079     f="$DIR/f24n"
1080     # this stats the old file after it was renamed, so it should fail
1081     touch ${f}
1082     $CHECKSTAT ${f} || error "${f} missing"
1083     mv ${f} ${f}.rename
1084     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1085     $CHECKSTAT -a ${f} || error "${f} exists"
1086 }
1087 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1088
1089 test_24o() {
1090         test_mkdir $DIR/$tdir
1091         rename_many -s random -v -n 10 $DIR/$tdir
1092 }
1093 run_test 24o "rename of files during htree split"
1094
1095 test_24p() {
1096         test_mkdir $DIR/R12a
1097         test_mkdir $DIR/R12b
1098         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1099         mrename $DIR/R12a $DIR/R12b
1100         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1101         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1102         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1103         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1104 }
1105 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1106
1107 cleanup_multiop_pause() {
1108         trap 0
1109         kill -USR1 $MULTIPID
1110 }
1111
1112 test_24q() {
1113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1114
1115         test_mkdir $DIR/R13a
1116         test_mkdir $DIR/R13b
1117         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1118         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1119         MULTIPID=$!
1120
1121         trap cleanup_multiop_pause EXIT
1122         mrename $DIR/R13a $DIR/R13b
1123         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1124         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1125         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1126         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1127         cleanup_multiop_pause
1128         wait $MULTIPID || error "multiop close failed"
1129 }
1130 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1131
1132 test_24r() { #bug 3789
1133         test_mkdir $DIR/R14a
1134         test_mkdir $DIR/R14a/b
1135         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1137         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1138 }
1139 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1140
1141 test_24s() {
1142         test_mkdir $DIR/R15a
1143         test_mkdir $DIR/R15a/b
1144         test_mkdir $DIR/R15a/b/c
1145         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1147         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1148 }
1149 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1150
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27d() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1716                 error "setstripe failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719 }
1720 run_test 27d "create file with default settings"
1721
1722 test_27e() {
1723         # LU-5839 adds check for existed layout before setting it
1724         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1725                 skip "Need MDS version at least 2.7.56"
1726
1727         test_mkdir $DIR/$tdir
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1729         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1730         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1731 }
1732 run_test 27e "setstripe existing file (should return error)"
1733
1734 test_27f() {
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1737                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1738         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1739                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1741         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1742 }
1743 run_test 27f "setstripe with bad stripe size (should return error)"
1744
1745 test_27g() {
1746         test_mkdir $DIR/$tdir
1747         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1748         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1749                 error "$DIR/$tdir/$tfile has object"
1750 }
1751 run_test 27g "$LFS getstripe with no objects"
1752
1753 test_27ga() {
1754         test_mkdir $DIR/$tdir
1755         touch $DIR/$tdir/$tfile || error "touch failed"
1756         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1757         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1758         local rc=$?
1759         (( rc == 2 )) || error "getstripe did not return ENOENT"
1760 }
1761 run_test 27ga "$LFS getstripe with missing file (should return error)"
1762
1763 test_27i() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1767                 error "missing objects"
1768 }
1769 run_test 27i "$LFS getstripe with some objects"
1770
1771 test_27j() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1774                 error "setstripe failed" || true
1775 }
1776 run_test 27j "setstripe with bad stripe offset (should return error)"
1777
1778 test_27k() { # bug 2844
1779         test_mkdir $DIR/$tdir
1780         local file=$DIR/$tdir/$tfile
1781         local ll_max_blksize=$((4 * 1024 * 1024))
1782         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1783         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1784         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1785         dd if=/dev/zero of=$file bs=4k count=1
1786         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1787         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1788 }
1789 run_test 27k "limit i_blksize for broken user apps"
1790
1791 test_27l() {
1792         mcreate $DIR/$tfile || error "creating file"
1793         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1794                 error "setstripe should have failed" || true
1795 }
1796 run_test 27l "check setstripe permissions (should return error)"
1797
1798 test_27m() {
1799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1800
1801         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1802                 skip_env "multiple clients -- skipping"
1803
1804         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1805                    head -n1)
1806         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1807                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1808         fi
1809         stack_trap simple_cleanup_common
1810         test_mkdir $DIR/$tdir
1811         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1813                 error "dd should fill OST0"
1814         i=2
1815         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1816                 i=$((i + 1))
1817                 [ $i -gt 256 ] && break
1818         done
1819         i=$((i + 1))
1820         touch $DIR/$tdir/$tfile.$i
1821         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1822             awk '{print $1}'| grep -w "0") ] &&
1823                 error "OST0 was full but new created file still use it"
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it" || true
1829 }
1830 run_test 27m "create file while OST0 was full"
1831
1832 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1833 # if the OST isn't full anymore.
1834 reset_enospc() {
1835         local ostidx=${1:-""}
1836         local delay
1837         local ready
1838         local get_prealloc
1839
1840         local list=$(comma_list $(osts_nodes))
1841         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1842
1843         do_nodes $list lctl set_param fail_loc=0
1844         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1845         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1846                 awk '{print $1 * 2;exit;}')
1847         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1848                         grep -v \"^0$\""
1849         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1850 }
1851
1852 test_27n() {
1853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1855         remote_mds_nodsh && skip "remote MDS with nodsh"
1856         remote_ost_nodsh && skip "remote OST with nodsh"
1857
1858         reset_enospc
1859         rm -f $DIR/$tdir/$tfile
1860         exhaust_precreations 0 0x80000215
1861         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1862         touch $DIR/$tdir/$tfile || error "touch failed"
1863         $LFS getstripe $DIR/$tdir/$tfile
1864         reset_enospc
1865 }
1866 run_test 27n "create file with some full OSTs"
1867
1868 test_27o() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876         exhaust_all_precreations 0x215
1877
1878         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1879
1880         reset_enospc
1881         rm -rf $DIR/$tdir/*
1882 }
1883 run_test 27o "create file with all full OSTs (should error)"
1884
1885 function create_and_checktime() {
1886         local fname=$1
1887         local loops=$2
1888         local i
1889
1890         for ((i=0; i < $loops; i++)); do
1891                 local start=$SECONDS
1892                 multiop $fname-$i Oc
1893                 ((SECONDS-start < TIMEOUT)) ||
1894                         error "creation took " $((SECONDS-$start)) && return 1
1895         done
1896 }
1897
1898 test_27oo() {
1899         local mdts=$(comma_list $(mdts_nodes))
1900
1901         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1902                 skip "Need MDS version at least 2.13.57"
1903
1904         local f0=$DIR/${tfile}-0
1905         local f1=$DIR/${tfile}-1
1906
1907         wait_delete_completed
1908
1909         # refill precreated objects
1910         $LFS setstripe -i0 -c1 $f0
1911
1912         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1913         # force QoS allocation policy
1914         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1915         stack_trap "do_nodes $mdts $LCTL set_param \
1916                 lov.*.qos_threshold_rr=$saved" EXIT
1917         sleep_maxage
1918
1919         # one OST is unavailable, but still have few objects preallocated
1920         stop ost1
1921         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1922                 rm -rf $f1 $DIR/$tdir*" EXIT
1923
1924         for ((i=0; i < 7; i++)); do
1925                 mkdir $DIR/$tdir$i || error "can't create dir"
1926                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1927                         error "can't set striping"
1928         done
1929         for ((i=0; i < 7; i++)); do
1930                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1931         done
1932         wait
1933 }
1934 run_test 27oo "don't let few threads to reserve too many objects"
1935
1936 test_27p() {
1937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1939         remote_mds_nodsh && skip "remote MDS with nodsh"
1940         remote_ost_nodsh && skip "remote OST with nodsh"
1941
1942         reset_enospc
1943         rm -f $DIR/$tdir/$tfile
1944         test_mkdir $DIR/$tdir
1945
1946         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1947         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1948         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1949
1950         exhaust_precreations 0 0x80000215
1951         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1952         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1953         $LFS getstripe $DIR/$tdir/$tfile
1954
1955         reset_enospc
1956 }
1957 run_test 27p "append to a truncated file with some full OSTs"
1958
1959 test_27q() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967
1968         mkdir_on_mdt0 $DIR/$tdir
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1971                 error "truncate $DIR/$tdir/$tfile failed"
1972         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1973
1974         exhaust_all_precreations 0x215
1975
1976         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1978
1979         reset_enospc
1980 }
1981 run_test 27q "append to truncated file with all OSTs full (should error)"
1982
1983 test_27r() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         exhaust_precreations 0 0x80000215
1992
1993         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1994
1995         reset_enospc
1996 }
1997 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1998
1999 test_27s() { # bug 10725
2000         test_mkdir $DIR/$tdir
2001         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2002         local stripe_count=0
2003         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2004         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2005                 error "stripe width >= 2^32 succeeded" || true
2006
2007 }
2008 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2009
2010 test_27t() { # bug 10864
2011         WDIR=$(pwd)
2012         WLFS=$(which lfs)
2013         cd $DIR
2014         touch $tfile
2015         $WLFS getstripe $tfile
2016         cd $WDIR
2017 }
2018 run_test 27t "check that utils parse path correctly"
2019
2020 test_27u() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023
2024         local index
2025         local list=$(comma_list $(mdts_nodes))
2026
2027 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2028         do_nodes $list $LCTL set_param fail_loc=0x139
2029         test_mkdir -p $DIR/$tdir
2030         stack_trap "simple_cleanup_common 1000"
2031         createmany -o $DIR/$tdir/$tfile 1000
2032         do_nodes $list $LCTL set_param fail_loc=0
2033
2034         TLOG=$TMP/$tfile.getstripe
2035         $LFS getstripe $DIR/$tdir > $TLOG
2036         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2037         [[ $OBJS -gt 0 ]] &&
2038                 error "$OBJS objects created on OST-0. See $TLOG" ||
2039                 rm -f $TLOG
2040 }
2041 run_test 27u "skip object creation on OSC w/o objects"
2042
2043 test_27v() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2046         remote_mds_nodsh && skip "remote MDS with nodsh"
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048
2049         exhaust_all_precreations 0x215
2050         reset_enospc
2051
2052         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2053
2054         touch $DIR/$tdir/$tfile
2055         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2056         # all except ost1
2057         for (( i=1; i < OSTCOUNT; i++ )); do
2058                 do_facet ost$i lctl set_param fail_loc=0x705
2059         done
2060         local START=`date +%s`
2061         createmany -o $DIR/$tdir/$tfile 32
2062
2063         local FINISH=`date +%s`
2064         local TIMEOUT=`lctl get_param -n timeout`
2065         local PROCESS=$((FINISH - START))
2066         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2067                error "$FINISH - $START >= $TIMEOUT / 2"
2068         sleep $((TIMEOUT / 2 - PROCESS))
2069         reset_enospc
2070 }
2071 run_test 27v "skip object creation on slow OST"
2072
2073 test_27w() { # bug 10997
2074         test_mkdir $DIR/$tdir
2075         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2076         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2077                 error "stripe size $size != 65536" || true
2078         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2079                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2080 }
2081 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2082
2083 test_27wa() {
2084         [[ $OSTCOUNT -lt 2 ]] &&
2085                 skip_env "skipping multiple stripe count/offset test"
2086
2087         test_mkdir $DIR/$tdir
2088         for i in $(seq 1 $OSTCOUNT); do
2089                 offset=$((i - 1))
2090                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2091                         error "setstripe -c $i -i $offset failed"
2092                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2093                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2094                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2095                 [ $index -ne $offset ] &&
2096                         error "stripe offset $index != $offset" || true
2097         done
2098 }
2099 run_test 27wa "check $LFS setstripe -c -i options"
2100
2101 test_27x() {
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         OFFSET=$(($OSTCOUNT - 1))
2107         OSTIDX=0
2108         local OST=$(ostname_from_index $OSTIDX)
2109
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2112         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2113         sleep_maxage
2114         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2115         for i in $(seq 0 $OFFSET); do
2116                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2117                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2118                 error "OST0 was degraded but new created file still use it"
2119         done
2120         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2121 }
2122 run_test 27x "create files while OST0 is degraded"
2123
2124 test_27y() {
2125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2126         remote_mds_nodsh && skip "remote MDS with nodsh"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2129
2130         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2131         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2132                 osp.$mdtosc.prealloc_last_id)
2133         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2134                 osp.$mdtosc.prealloc_next_id)
2135         local fcount=$((last_id - next_id))
2136         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2137         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2138
2139         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2140                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2141         local OST_DEACTIVE_IDX=-1
2142         local OSC
2143         local OSTIDX
2144         local OST
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2150                         OST_DEACTIVE_IDX=$OSTIDX
2151                 fi
2152                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2153                         echo $OSC "is Deactivated:"
2154                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2155                 fi
2156         done
2157
2158         OSTIDX=$(index_from_ostuuid $OST)
2159         test_mkdir $DIR/$tdir
2160         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2161
2162         for OSC in $MDS_OSCS; do
2163                 OST=$(osc_to_ost $OSC)
2164                 OSTIDX=$(index_from_ostuuid $OST)
2165                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2166                         echo $OST "is degraded:"
2167                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2168                                                 obdfilter.$OST.degraded=1
2169                 fi
2170         done
2171
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $fcount
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is recovered from degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=0
2182                 else
2183                         do_facet $SINGLEMDS lctl --device %$OSC activate
2184                 fi
2185         done
2186
2187         # all osp devices get activated, hence -1 stripe count restored
2188         local stripe_count=0
2189
2190         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2191         # devices get activated.
2192         sleep_maxage
2193         $LFS setstripe -c -1 $DIR/$tfile
2194         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2195         rm -f $DIR/$tfile
2196         [ $stripe_count -ne $OSTCOUNT ] &&
2197                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2198         return 0
2199 }
2200 run_test 27y "create files while OST0 is degraded and the rest inactive"
2201
2202 check_seq_oid()
2203 {
2204         log "check file $1"
2205
2206         lmm_count=$($LFS getstripe -c $1)
2207         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2208         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2209
2210         local old_ifs="$IFS"
2211         IFS=$'[:]'
2212         fid=($($LFS path2fid $1))
2213         IFS="$old_ifs"
2214
2215         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2216         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2217
2218         # compare lmm_seq and lu_fid->f_seq
2219         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2220         # compare lmm_object_id and lu_fid->oid
2221         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2222
2223         # check the trusted.fid attribute of the OST objects of the file
2224         local have_obdidx=false
2225         local stripe_nr=0
2226         $LFS getstripe $1 | while read obdidx oid hex seq; do
2227                 # skip lines up to and including "obdidx"
2228                 [ -z "$obdidx" ] && break
2229                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2230                 $have_obdidx || continue
2231
2232                 local ost=$((obdidx + 1))
2233                 local dev=$(ostdevname $ost)
2234                 local oid_hex
2235
2236                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2237
2238                 seq=$(echo $seq | sed -e "s/^0x//g")
2239                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2240                         oid_hex=$(echo $oid)
2241                 else
2242                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2243                 fi
2244                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2245
2246                 local ff=""
2247                 #
2248                 # Don't unmount/remount the OSTs if we don't need to do that.
2249                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2250                 # update too, until that use mount/ll_decode_filter_fid/mount.
2251                 # Re-enable when debugfs will understand new filter_fid.
2252                 #
2253                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2254                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2255                                 $dev 2>/dev/null" | grep "parent=")
2256                 fi
2257                 if [ -z "$ff" ]; then
2258                         stop ost$ost
2259                         mount_fstype ost$ost
2260                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2261                                 $(facet_mntpt ost$ost)/$obj_file)
2262                         unmount_fstype ost$ost
2263                         start ost$ost $dev $OST_MOUNT_OPTS
2264                         clients_up
2265                 fi
2266
2267                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2268
2269                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2270
2271                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2272                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2273                 #
2274                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2275                 #       stripe_size=1048576 component_id=1 component_start=0 \
2276                 #       component_end=33554432
2277                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2278                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2279                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2280                 local ff_pstripe
2281                 if grep -q 'stripe=' <<<$ff; then
2282                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2283                 else
2284                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2285                         # into f_ver in this case.  See comment on ff_parent.
2286                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2287                 fi
2288
2289                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2290                 [ $ff_pseq = $lmm_seq ] ||
2291                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2292                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2293                 [ $ff_poid = $lmm_oid ] ||
2294                         error "FF parent OID $ff_poid != $lmm_oid"
2295                 (($ff_pstripe == $stripe_nr)) ||
2296                         error "FF stripe $ff_pstripe != $stripe_nr"
2297
2298                 stripe_nr=$((stripe_nr + 1))
2299                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2300                         continue
2301                 if grep -q 'stripe_count=' <<<$ff; then
2302                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2303                                             -e 's/ .*//' <<<$ff)
2304                         [ $lmm_count = $ff_scnt ] ||
2305                                 error "FF stripe count $lmm_count != $ff_scnt"
2306                 fi
2307         done
2308 }
2309
2310 test_27z() {
2311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2312         remote_ost_nodsh && skip "remote OST with nodsh"
2313
2314         test_mkdir $DIR/$tdir
2315         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2316                 { error "setstripe -c -1 failed"; return 1; }
2317         # We need to send a write to every object to get parent FID info set.
2318         # This _should_ also work for setattr, but does not currently.
2319         # touch $DIR/$tdir/$tfile-1 ||
2320         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2321                 { error "dd $tfile-1 failed"; return 2; }
2322         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2323                 { error "setstripe -c -1 failed"; return 3; }
2324         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2325                 { error "dd $tfile-2 failed"; return 4; }
2326
2327         # make sure write RPCs have been sent to OSTs
2328         sync; sleep 5; sync
2329
2330         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2331         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2332 }
2333 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2334
2335 test_27A() { # b=19102
2336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2337
2338         save_layout_restore_at_exit $MOUNT
2339         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2340         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2341                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2342         local default_size=$($LFS getstripe -S $MOUNT)
2343         local default_offset=$($LFS getstripe -i $MOUNT)
2344         local dsize=$(do_facet $SINGLEMDS \
2345                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2346         [ $default_size -eq $dsize ] ||
2347                 error "stripe size $default_size != $dsize"
2348         [ $default_offset -eq -1 ] ||
2349                 error "stripe offset $default_offset != -1"
2350 }
2351 run_test 27A "check filesystem-wide default LOV EA values"
2352
2353 test_27B() { # LU-2523
2354         test_mkdir $DIR/$tdir
2355         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2356         touch $DIR/$tdir/f0
2357         # open f1 with O_LOV_DELAY_CREATE
2358         # rename f0 onto f1
2359         # call setstripe ioctl on open file descriptor for f1
2360         # close
2361         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2362                 $DIR/$tdir/f0
2363
2364         rm -f $DIR/$tdir/f1
2365         # open f1 with O_LOV_DELAY_CREATE
2366         # unlink f1
2367         # call setstripe ioctl on open file descriptor for f1
2368         # close
2369         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2370
2371         # Allow multiop to fail in imitation of NFS's busted semantics.
2372         true
2373 }
2374 run_test 27B "call setstripe on open unlinked file/rename victim"
2375
2376 # 27C family tests full striping and overstriping
2377 test_27Ca() { #LU-2871
2378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2379
2380         declare -a ost_idx
2381         local index
2382         local found
2383         local i
2384         local j
2385
2386         test_mkdir $DIR/$tdir
2387         cd $DIR/$tdir
2388         for i in $(seq 0 $((OSTCOUNT - 1))); do
2389                 # set stripe across all OSTs starting from OST$i
2390                 $LFS setstripe -i $i -c -1 $tfile$i
2391                 # get striping information
2392                 ost_idx=($($LFS getstripe $tfile$i |
2393                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2394                 echo "OST Index: ${ost_idx[*]}"
2395
2396                 # check the layout
2397                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2398                         error "${#ost_idx[@]} != $OSTCOUNT"
2399
2400                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2401                         found=0
2402                         for j in "${ost_idx[@]}"; do
2403                                 if [ $index -eq $j ]; then
2404                                         found=1
2405                                         break
2406                                 fi
2407                         done
2408                         [ $found = 1 ] ||
2409                                 error "Can not find $index in ${ost_idx[*]}"
2410                 done
2411         done
2412 }
2413 run_test 27Ca "check full striping across all OSTs"
2414
2415 test_27Cb() {
2416         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2417                 skip "server does not support overstriping"
2418         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2419                 skip_env "too many osts, skipping"
2420
2421         test_mkdir -p $DIR/$tdir
2422         local setcount=$(($OSTCOUNT * 2))
2423         [ $setcount -lt 160 ] || large_xattr_enabled ||
2424                 skip_env "ea_inode feature disabled"
2425
2426         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2427                 error "setstripe failed"
2428
2429         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2430         [ $count -eq $setcount ] ||
2431                 error "stripe count $count, should be $setcount"
2432
2433         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2434                 error "overstriped should be set in pattern"
2435
2436         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2437                 error "dd failed"
2438 }
2439 run_test 27Cb "more stripes than OSTs with -C"
2440
2441 test_27Cc() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2445
2446         test_mkdir -p $DIR/$tdir
2447         local setcount=$(($OSTCOUNT - 1))
2448
2449         [ $setcount -lt 160 ] || large_xattr_enabled ||
2450                 skip_env "ea_inode feature disabled"
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2460                 error "overstriped should not be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464 }
2465 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2466
2467 test_27Cd() {
2468         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2469                 skip "server does not support overstriping"
2470         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2471         large_xattr_enabled || skip_env "ea_inode feature disabled"
2472
2473         test_mkdir -p $DIR/$tdir
2474         local setcount=$LOV_MAX_STRIPE_COUNT
2475
2476         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2477                 error "setstripe failed"
2478
2479         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2480         [ $count -eq $setcount ] ||
2481                 error "stripe count $count, should be $setcount"
2482
2483         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2484                 error "overstriped should be set in pattern"
2485
2486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2487                 error "dd failed"
2488
2489         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2490 }
2491 run_test 27Cd "test maximum stripe count"
2492
2493 test_27Ce() {
2494         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2495                 skip "server does not support overstriping"
2496         test_mkdir -p $DIR/$tdir
2497
2498         pool_add $TESTNAME || error "Pool creation failed"
2499         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2500
2501         local setcount=8
2502
2503         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2504                 error "setstripe failed"
2505
2506         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2507         [ $count -eq $setcount ] ||
2508                 error "stripe count $count, should be $setcount"
2509
2510         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2511                 error "overstriped should be set in pattern"
2512
2513         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2514                 error "dd failed"
2515
2516         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2517 }
2518 run_test 27Ce "test pool with overstriping"
2519
2520 test_27Cf() {
2521         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2522                 skip "server does not support overstriping"
2523         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2524                 skip_env "too many osts, skipping"
2525
2526         test_mkdir -p $DIR/$tdir
2527
2528         local setcount=$(($OSTCOUNT * 2))
2529         [ $setcount -lt 160 ] || large_xattr_enabled ||
2530                 skip_env "ea_inode feature disabled"
2531
2532         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2533                 error "setstripe failed"
2534
2535         echo 1 > $DIR/$tdir/$tfile
2536
2537         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2538         [ $count -eq $setcount ] ||
2539                 error "stripe count $count, should be $setcount"
2540
2541         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2542                 error "overstriped should be set in pattern"
2543
2544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2545                 error "dd failed"
2546
2547         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2548 }
2549 run_test 27Cf "test default inheritance with overstriping"
2550
2551 test_27D() {
2552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2553         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2554         remote_mds_nodsh && skip "remote MDS with nodsh"
2555
2556         local POOL=${POOL:-testpool}
2557         local first_ost=0
2558         local last_ost=$(($OSTCOUNT - 1))
2559         local ost_step=1
2560         local ost_list=$(seq $first_ost $ost_step $last_ost)
2561         local ost_range="$first_ost $last_ost $ost_step"
2562
2563         test_mkdir $DIR/$tdir
2564         pool_add $POOL || error "pool_add failed"
2565         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2566
2567         local skip27D
2568         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2569                 skip27D+="-s 29"
2570         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2571                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2572                         skip27D+=" -s 30,31"
2573         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2574           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2575                 skip27D+=" -s 32,33"
2576         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2577                 skip27D+=" -s 34"
2578         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2579                 error "llapi_layout_test failed"
2580
2581         destroy_test_pools || error "destroy test pools failed"
2582 }
2583 run_test 27D "validate llapi_layout API"
2584
2585 # Verify that default_easize is increased from its initial value after
2586 # accessing a widely striped file.
2587 test_27E() {
2588         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2589         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2590                 skip "client does not have LU-3338 fix"
2591
2592         # 72 bytes is the minimum space required to store striping
2593         # information for a file striped across one OST:
2594         # (sizeof(struct lov_user_md_v3) +
2595         #  sizeof(struct lov_user_ost_data_v1))
2596         local min_easize=72
2597         $LCTL set_param -n llite.*.default_easize $min_easize ||
2598                 error "lctl set_param failed"
2599         local easize=$($LCTL get_param -n llite.*.default_easize)
2600
2601         [ $easize -eq $min_easize ] ||
2602                 error "failed to set default_easize"
2603
2604         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2605                 error "setstripe failed"
2606         # In order to ensure stat() call actually talks to MDS we need to
2607         # do something drastic to this file to shake off all lock, e.g.
2608         # rename it (kills lookup lock forcing cache cleaning)
2609         mv $DIR/$tfile $DIR/${tfile}-1
2610         ls -l $DIR/${tfile}-1
2611         rm $DIR/${tfile}-1
2612
2613         easize=$($LCTL get_param -n llite.*.default_easize)
2614
2615         [ $easize -gt $min_easize ] ||
2616                 error "default_easize not updated"
2617 }
2618 run_test 27E "check that default extended attribute size properly increases"
2619
2620 test_27F() { # LU-5346/LU-7975
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2623         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2624                 skip "Need MDS version at least 2.8.51"
2625         remote_ost_nodsh && skip "remote OST with nodsh"
2626
2627         test_mkdir $DIR/$tdir
2628         rm -f $DIR/$tdir/f0
2629         $LFS setstripe -c 2 $DIR/$tdir
2630
2631         # stop all OSTs to reproduce situation for LU-7975 ticket
2632         for num in $(seq $OSTCOUNT); do
2633                 stop ost$num
2634         done
2635
2636         # open/create f0 with O_LOV_DELAY_CREATE
2637         # truncate f0 to a non-0 size
2638         # close
2639         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2640
2641         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2642         # open/write it again to force delayed layout creation
2643         cat /etc/hosts > $DIR/$tdir/f0 &
2644         catpid=$!
2645
2646         # restart OSTs
2647         for num in $(seq $OSTCOUNT); do
2648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2649                         error "ost$num failed to start"
2650         done
2651
2652         wait $catpid || error "cat failed"
2653
2654         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2655         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2656                 error "wrong stripecount"
2657
2658 }
2659 run_test 27F "Client resend delayed layout creation with non-zero size"
2660
2661 test_27G() { #LU-10629
2662         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2663                 skip "Need MDS version at least 2.11.51"
2664         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2665         remote_mds_nodsh && skip "remote MDS with nodsh"
2666         local POOL=${POOL:-testpool}
2667         local ostrange="0 0 1"
2668
2669         test_mkdir $DIR/$tdir
2670         touch $DIR/$tdir/$tfile.nopool
2671         pool_add $POOL || error "pool_add failed"
2672         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2673         $LFS setstripe -p $POOL $DIR/$tdir
2674
2675         local pool=$($LFS getstripe -p $DIR/$tdir)
2676
2677         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2678         touch $DIR/$tdir/$tfile.default
2679         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2680         $LFS find $DIR/$tdir -type f --pool $POOL
2681         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2682         [[ "$found" == "2" ]] ||
2683                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2684
2685         $LFS setstripe -d $DIR/$tdir
2686
2687         pool=$($LFS getstripe -p -d $DIR/$tdir)
2688
2689         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2690 }
2691 run_test 27G "Clear OST pool from stripe"
2692
2693 test_27H() {
2694         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2695                 skip "Need MDS version newer than 2.11.54"
2696         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2699         touch $DIR/$tdir/$tfile
2700         $LFS getstripe -c $DIR/$tdir/$tfile
2701         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2702                 error "two-stripe file doesn't have two stripes"
2703
2704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2705         $LFS getstripe -y $DIR/$tdir/$tfile
2706         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2707              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2708                 error "expected l_ost_idx: [02]$ not matched"
2709
2710         # make sure ost list has been cleared
2711         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2712         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2713                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2714         touch $DIR/$tdir/f3
2715         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2716 }
2717 run_test 27H "Set specific OSTs stripe"
2718
2719 test_27I() {
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2723                 skip "Need MDS version newer than 2.12.52"
2724         local pool=$TESTNAME
2725         local ostrange="1 1 1"
2726
2727         save_layout_restore_at_exit $MOUNT
2728         $LFS setstripe -c 2 -i 0 $MOUNT
2729         pool_add $pool || error "pool_add failed"
2730         pool_add_targets $pool $ostrange ||
2731                 error "pool_add_targets failed"
2732         test_mkdir $DIR/$tdir
2733         $LFS setstripe -p $pool $DIR/$tdir
2734         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2735         $LFS getstripe $DIR/$tdir/$tfile
2736 }
2737 run_test 27I "check that root dir striping does not break parent dir one"
2738
2739 test_27J() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2741                 skip "Need MDS version newer than 2.12.51"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign file (raw way)
2748         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2749                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2750
2751         ! $LFS setstripe --foreign --flags foo \
2752                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2753                         error "creating $tfile with '--flags foo' should fail"
2754
2755         ! $LFS setstripe --foreign --flags 0xffffffff \
2756                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2757                         error "creating $tfile w/ 0xffffffff flags should fail"
2758
2759         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2760                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2761
2762         # verify foreign file (raw way)
2763         parse_foreign_file -f $DIR/$tdir/$tfile |
2764                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2765                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2766         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2767                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_size: 73" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2771         parse_foreign_file -f $DIR/$tdir/$tfile |
2772                 grep "lov_foreign_type: 1" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_flags: 0x0000DA08" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2777         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_value: 0x" |
2779                 sed -e 's/lov_foreign_value: 0x//')
2780         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2781         [[ $lov = ${lov2// /} ]] ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2783
2784         # create foreign file (lfs + API)
2785         $LFS setstripe --foreign=none --flags 0xda08 \
2786                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: create failed"
2788
2789         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2790                 grep "lfm_magic:.*0x0BD70BD0" ||
2791                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2792         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2793         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2794                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2797         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2798                 grep "lfm_flags:.*0x0000DA08" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2800         $LFS getstripe $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2803
2804         # modify striping should fail
2805         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2806                 error "$DIR/$tdir/$tfile: setstripe should fail"
2807         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2808                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2809
2810         # R/W should fail
2811         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2812         cat $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: read should fail"
2814         cat /etc/passwd > $DIR/$tdir/$tfile &&
2815                 error "$DIR/$tdir/$tfile: write should fail"
2816         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2817                 error "$DIR/$tdir/${tfile}2: write should fail"
2818
2819         # chmod should work
2820         chmod 222 $DIR/$tdir/$tfile ||
2821                 error "$DIR/$tdir/$tfile: chmod failed"
2822         chmod 222 $DIR/$tdir/${tfile}2 ||
2823                 error "$DIR/$tdir/${tfile}2: chmod failed"
2824
2825         # chown should work
2826         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chown failed"
2828         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chown failed"
2830
2831         # rename should work
2832         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2833                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2834         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2835                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2836
2837         #remove foreign file
2838         rm $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2840         rm $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2842 }
2843 run_test 27J "basic ops on file with foreign LOV"
2844
2845 test_27K() {
2846         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2847                 skip "Need MDS version newer than 2.12.49"
2848
2849         test_mkdir $DIR/$tdir
2850         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2851         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2852
2853         # create foreign dir (raw way)
2854         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2855                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2856
2857         ! $LFS setdirstripe --foreign --flags foo \
2858                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2859                         error "creating $tdir with '--flags foo' should fail"
2860
2861         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2862                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2863                         error "creating $tdir w/ 0xffffffff flags should fail"
2864
2865         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2866                 error "create_foreign_dir FAILED"
2867
2868         # verify foreign dir (raw way)
2869         parse_foreign_dir -d $DIR/$tdir/$tdir |
2870                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2871                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2872         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2873                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2874         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2875                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_flags: 55813$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2879         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2880                 grep "lmv_foreign_value: 0x" |
2881                 sed 's/lmv_foreign_value: 0x//')
2882         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2883                 sed 's/ //g')
2884         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2885
2886         # create foreign dir (lfs + API)
2887         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2888                 $DIR/$tdir/${tdir}2 ||
2889                 error "$DIR/$tdir/${tdir}2: create failed"
2890
2891         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2892
2893         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2894                 grep "lfm_magic:.*0x0CD50CD0" ||
2895                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2896         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2897         # - sizeof(lfm_type) - sizeof(lfm_flags)
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2900         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_flags:.*0x0000DA05" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2905         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2908
2909         # file create in dir should fail
2910         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2911         touch $DIR/$tdir/${tdir}2/$tfile &&
2912                 error "$DIR/${tdir}2: file create should fail"
2913
2914         # chmod should work
2915         chmod 777 $DIR/$tdir/$tdir ||
2916                 error "$DIR/$tdir: chmod failed"
2917         chmod 777 $DIR/$tdir/${tdir}2 ||
2918                 error "$DIR/${tdir}2: chmod failed"
2919
2920         # chown should work
2921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chown failed"
2923         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chown failed"
2925
2926         # rename should work
2927         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2928                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2929         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2930                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2931
2932         #remove foreign dir
2933         rmdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2935         rmdir $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2937 }
2938 run_test 27K "basic ops on dir with foreign LMV"
2939
2940 test_27L() {
2941         remote_mds_nodsh && skip "remote MDS with nodsh"
2942
2943         local POOL=${POOL:-$TESTNAME}
2944
2945         pool_add $POOL || error "pool_add failed"
2946
2947         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2948                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2949                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2950 }
2951 run_test 27L "lfs pool_list gives correct pool name"
2952
2953 test_27M() {
2954         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2955                 skip "Need MDS version >= than 2.12.57"
2956         remote_mds_nodsh && skip "remote MDS with nodsh"
2957         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2958
2959         # Set default striping on directory
2960         local setcount=4
2961         local stripe_opt
2962         local mdts=$(comma_list $(mdts_nodes))
2963
2964         # if we run against a 2.12 server which lacks overstring support
2965         # then the connect_flag will not report overstriping, even if client
2966         # is 2.14+
2967         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2968                 stripe_opt="-C $setcount"
2969         elif (( $OSTCOUNT >= $setcount )); then
2970                 stripe_opt="-c $setcount"
2971         else
2972                 skip "server does not support overstriping"
2973         fi
2974
2975         test_mkdir $DIR/$tdir
2976
2977         # Validate existing append_* params and ensure restore
2978         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2979         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2980         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2981
2982         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2983         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2985
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         pool_add $TESTNAME || error "pool creation failed"
3071         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3072         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27T() {
3377         [ $(facet_host client) == $(facet_host ost1) ] &&
3378                 skip "need ost1 and client on different nodes"
3379
3380 #define OBD_FAIL_OSC_NO_GRANT            0x411
3381         $LCTL set_param fail_loc=0x20000411 fail_val=1
3382 #define OBD_FAIL_OST_ENOSPC              0x215
3383         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3385         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3386                 error "multiop failed"
3387 }
3388 run_test 27T "no eio on close on partial write due to enosp"
3389
3390 test_27U() {
3391         local dir=$DIR/$tdir
3392         local file=$dir/$tfile
3393         local append_pool=${TESTNAME}-append
3394         local normal_pool=${TESTNAME}-normal
3395         local pool
3396         local stripe_count
3397         local stripe_count2
3398         local mdts=$(comma_list $(mdts_nodes))
3399
3400         # FIMXE
3401         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3402         #       skip "Need MDS version at least 2.15.42"
3403
3404         # Validate existing append_* params and ensure restore
3405         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3406         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3407         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3408
3409         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3410         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3411         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3412
3413         pool_add $append_pool || error "pool creation failed"
3414         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3415
3416         pool_add $normal_pool || error "pool creation failed"
3417         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3418
3419         test_mkdir $dir
3420         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3421
3422         echo XXX >> $file.1
3423         $LFS getstripe $file.1
3424
3425         pool=$($LFS getstripe -p $file.1)
3426         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3427
3428         stripe_count2=$($LFS getstripe -c $file.1)
3429         ((stripe_count2 == stripe_count)) ||
3430                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3431
3432         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3433
3434         echo XXX >> $file.2
3435         $LFS getstripe $file.2
3436
3437         pool=$($LFS getstripe -p $file.2)
3438         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3439
3440         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3441
3442         echo XXX >> $file.3
3443         $LFS getstripe $file.3
3444
3445         stripe_count2=$($LFS getstripe -c $file.3)
3446         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3447 }
3448 run_test 27U "append pool and stripe count work with composite default layout"
3449
3450 # createtest also checks that device nodes are created and
3451 # then visible correctly (#2091)
3452 test_28() { # bug 2091
3453         test_mkdir $DIR/d28
3454         $CREATETEST $DIR/d28/ct || error "createtest failed"
3455 }
3456 run_test 28 "create/mknod/mkdir with bad file types ============"
3457
3458 test_29() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3462                 disable_opencache
3463                 stack_trap "restore_opencache"
3464         }
3465
3466         sync; sleep 1; sync # flush out any dirty pages from previous tests
3467         cancel_lru_locks
3468         test_mkdir $DIR/d29
3469         touch $DIR/d29/foo
3470         log 'first d29'
3471         ls -l $DIR/d29
3472
3473         declare -i LOCKCOUNTORIG=0
3474         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3475                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3476         done
3477         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3478
3479         declare -i LOCKUNUSEDCOUNTORIG=0
3480         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3481                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3482         done
3483
3484         log 'second d29'
3485         ls -l $DIR/d29
3486         log 'done'
3487
3488         declare -i LOCKCOUNTCURRENT=0
3489         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3490                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3491         done
3492
3493         declare -i LOCKUNUSEDCOUNTCURRENT=0
3494         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3495                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3496         done
3497
3498         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3499                 $LCTL set_param -n ldlm.dump_namespaces ""
3500                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3501                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3502                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3503                 return 2
3504         fi
3505         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3506                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3507                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3508                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3509                 return 3
3510         fi
3511 }
3512 run_test 29 "IT_GETATTR regression  ============================"
3513
3514 test_30a() { # was test_30
3515         cp $(which ls) $DIR || cp /bin/ls $DIR
3516         $DIR/ls / || error "Can't execute binary from lustre"
3517         rm $DIR/ls
3518 }
3519 run_test 30a "execute binary from Lustre (execve) =============="
3520
3521 test_30b() {
3522         cp `which ls` $DIR || cp /bin/ls $DIR
3523         chmod go+rx $DIR/ls
3524         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3525         rm $DIR/ls
3526 }
3527 run_test 30b "execute binary from Lustre as non-root ==========="
3528
3529 test_30c() { # b=22376
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         cp $(which ls) $DIR || cp /bin/ls $DIR
3533         chmod a-rw $DIR/ls
3534         cancel_lru_locks mdc
3535         cancel_lru_locks osc
3536         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3537         rm -f $DIR/ls
3538 }
3539 run_test 30c "execute binary from Lustre without read perms ===="
3540
3541 test_30d() {
3542         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3543
3544         for i in {1..10}; do
3545                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3546                 local PID=$!
3547                 sleep 1
3548                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3549                 wait $PID || error "executing dd from Lustre failed"
3550                 rm -f $DIR/$tfile
3551         done
3552
3553         rm -f $DIR/dd
3554 }
3555 run_test 30d "execute binary from Lustre while clear locks"
3556
3557 test_31a() {
3558         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3559         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3560 }
3561 run_test 31a "open-unlink file =================================="
3562
3563 test_31b() {
3564         touch $DIR/f31 || error "touch $DIR/f31 failed"
3565         ln $DIR/f31 $DIR/f31b || error "ln failed"
3566         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3567         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3568 }
3569 run_test 31b "unlink file with multiple links while open ======="
3570
3571 test_31c() {
3572         touch $DIR/f31 || error "touch $DIR/f31 failed"
3573         ln $DIR/f31 $DIR/f31c || error "ln failed"
3574         multiop_bg_pause $DIR/f31 O_uc ||
3575                 error "multiop_bg_pause for $DIR/f31 failed"
3576         MULTIPID=$!
3577         $MULTIOP $DIR/f31c Ouc
3578         kill -USR1 $MULTIPID
3579         wait $MULTIPID
3580 }
3581 run_test 31c "open-unlink file with multiple links ============="
3582
3583 test_31d() {
3584         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3585         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3586 }
3587 run_test 31d "remove of open directory ========================="
3588
3589 test_31e() { # bug 2904
3590         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3591 }
3592 run_test 31e "remove of open non-empty directory ==============="
3593
3594 test_31f() { # bug 4554
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         set -vx
3598         test_mkdir $DIR/d31f
3599         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3600         cp /etc/hosts $DIR/d31f
3601         ls -l $DIR/d31f
3602         $LFS getstripe $DIR/d31f/hosts
3603         multiop_bg_pause $DIR/d31f D_c || return 1
3604         MULTIPID=$!
3605
3606         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3607         test_mkdir $DIR/d31f
3608         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3609         cp /etc/hosts $DIR/d31f
3610         ls -l $DIR/d31f
3611         $LFS getstripe $DIR/d31f/hosts
3612         multiop_bg_pause $DIR/d31f D_c || return 1
3613         MULTIPID2=$!
3614
3615         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3616         wait $MULTIPID || error "first opendir $MULTIPID failed"
3617
3618         sleep 6
3619
3620         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3621         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3622         set +vx
3623 }
3624 run_test 31f "remove of open directory with open-unlink file ==="
3625
3626 test_31g() {
3627         echo "-- cross directory link --"
3628         test_mkdir -c1 $DIR/${tdir}ga
3629         test_mkdir -c1 $DIR/${tdir}gb
3630         touch $DIR/${tdir}ga/f
3631         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3632         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3633         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3634         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3635         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3636 }
3637 run_test 31g "cross directory link==============="
3638
3639 test_31h() {
3640         echo "-- cross directory link --"
3641         test_mkdir -c1 $DIR/${tdir}
3642         test_mkdir -c1 $DIR/${tdir}/dir
3643         touch $DIR/${tdir}/f
3644         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3645         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3646         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3647         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3648         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3649 }
3650 run_test 31h "cross directory link under child==============="
3651
3652 test_31i() {
3653         echo "-- cross directory link --"
3654         test_mkdir -c1 $DIR/$tdir
3655         test_mkdir -c1 $DIR/$tdir/dir
3656         touch $DIR/$tdir/dir/f
3657         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3658         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3659         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3660         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3661         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3662 }
3663 run_test 31i "cross directory link under parent==============="
3664
3665 test_31j() {
3666         test_mkdir -c1 -p $DIR/$tdir
3667         test_mkdir -c1 -p $DIR/$tdir/dir1
3668         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3669         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3671         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3672         return 0
3673 }
3674 run_test 31j "link for directory==============="
3675
3676 test_31k() {
3677         test_mkdir -c1 -p $DIR/$tdir
3678         touch $DIR/$tdir/s
3679         touch $DIR/$tdir/exist
3680         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3681         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3682         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3683         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3684         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3686         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3687         return 0
3688 }
3689 run_test 31k "link to file: the same, non-existing, dir==============="
3690
3691 test_31m() {
3692         mkdir $DIR/d31m
3693         touch $DIR/d31m/s
3694         mkdir $DIR/d31m2
3695         touch $DIR/d31m2/exist
3696         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3697         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3698         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3699         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3701         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3702         return 0
3703 }
3704 run_test 31m "link to file: the same, non-existing, dir==============="
3705
3706 test_31n() {
3707         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3708         nlink=$(stat --format=%h $DIR/$tfile)
3709         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3710         local fd=$(free_fd)
3711         local cmd="exec $fd<$DIR/$tfile"
3712         eval $cmd
3713         cmd="exec $fd<&-"
3714         trap "eval $cmd" EXIT
3715         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3716         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3717         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3718         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3719         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3720         eval $cmd
3721 }
3722 run_test 31n "check link count of unlinked file"
3723
3724 link_one() {
3725         local tempfile=$(mktemp $1_XXXXXX)
3726         mlink $tempfile $1 2> /dev/null &&
3727                 echo "$BASHPID: link $tempfile to $1 succeeded"
3728         munlink $tempfile
3729 }
3730
3731 test_31o() { # LU-2901
3732         test_mkdir $DIR/$tdir
3733         for LOOP in $(seq 100); do
3734                 rm -f $DIR/$tdir/$tfile*
3735                 for THREAD in $(seq 8); do
3736                         link_one $DIR/$tdir/$tfile.$LOOP &
3737                 done
3738                 wait
3739                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3740                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3741                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3742                         break || true
3743         done
3744 }
3745 run_test 31o "duplicate hard links with same filename"
3746
3747 test_31p() {
3748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3752         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3753
3754         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3755                 error "open unlink test1 failed"
3756         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3757                 error "open unlink test2 failed"
3758
3759         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3760                 error "test1 still exists"
3761         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3762                 error "test2 still exists"
3763 }
3764 run_test 31p "remove of open striped directory"
3765
3766 test_31q() {
3767         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3768
3769         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3770         index=$($LFS getdirstripe -i $DIR/$tdir)
3771         [ $index -eq 3 ] || error "first stripe index $index != 3"
3772         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3773         [ $index -eq 1 ] || error "second stripe index $index != 1"
3774
3775         # when "-c <stripe_count>" is set, the number of MDTs specified after
3776         # "-i" should equal to the stripe count
3777         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3778 }
3779 run_test 31q "create striped directory on specific MDTs"
3780
3781 #LU-14949
3782 test_31r() {
3783         touch $DIR/$tfile.target
3784         touch $DIR/$tfile.source
3785
3786         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3787         $LCTL set_param fail_loc=0x1419 fail_val=3
3788         cat $DIR/$tfile.target &
3789         CATPID=$!
3790
3791         # Guarantee open is waiting before we get here
3792         sleep 1
3793         mv $DIR/$tfile.source $DIR/$tfile.target
3794
3795         wait $CATPID
3796         RC=$?
3797         if [[ $RC -ne 0 ]]; then
3798                 error "open with cat failed, rc=$RC"
3799         fi
3800 }
3801 run_test 31r "open-rename(replace) race"
3802
3803 cleanup_test32_mount() {
3804         local rc=0
3805         trap 0
3806         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3807         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3808         losetup -d $loopdev || true
3809         rm -rf $DIR/$tdir
3810         return $rc
3811 }
3812
3813 test_32a() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         echo "== more mountpoints and symlinks ================="
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3823                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3824         cleanup_test32_mount
3825 }
3826 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3827
3828 test_32b() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3837                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3838         cleanup_test32_mount
3839 }
3840 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3841
3842 test_32c() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2/test_dir
3851         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3852                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3853         cleanup_test32_mount
3854 }
3855 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3856
3857 test_32d() {
3858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3859
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         test_mkdir -p $DIR/$tdir/d2/test_dir
3866         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3868         cleanup_test32_mount
3869 }
3870 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3871
3872 test_32e() {
3873         rm -fr $DIR/$tdir
3874         test_mkdir -p $DIR/$tdir/tmp
3875         local tmp_dir=$DIR/$tdir/tmp
3876         ln -s $DIR/$tdir $tmp_dir/symlink11
3877         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3878         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3879         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3880 }
3881 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3882
3883 test_32f() {
3884         rm -fr $DIR/$tdir
3885         test_mkdir -p $DIR/$tdir/tmp
3886         local tmp_dir=$DIR/$tdir/tmp
3887         ln -s $DIR/$tdir $tmp_dir/symlink11
3888         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3889         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3890         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3891 }
3892 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3893
3894 test_32g() {
3895         local tmp_dir=$DIR/$tdir/tmp
3896         test_mkdir -p $tmp_dir
3897         test_mkdir $DIR/${tdir}2
3898         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3899         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3900         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3901         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3902         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3903         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3904 }
3905 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3906
3907 test_32h() {
3908         rm -fr $DIR/$tdir $DIR/${tdir}2
3909         tmp_dir=$DIR/$tdir/tmp
3910         test_mkdir -p $tmp_dir
3911         test_mkdir $DIR/${tdir}2
3912         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3913         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3914         ls $tmp_dir/symlink12 || error "listing symlink12"
3915         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3916 }
3917 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3918
3919 test_32i() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         touch $DIR/$tdir/test_file
3928         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3929                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3930         cleanup_test32_mount
3931 }
3932 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3933
3934 test_32j() {
3935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3936
3937         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3938         trap cleanup_test32_mount EXIT
3939         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3940         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3941                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3942         touch $DIR/$tdir/test_file
3943         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3948
3949 test_32k() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         test_mkdir -p $DIR/$tdir/d2
3958         touch $DIR/$tdir/d2/test_file || error "touch failed"
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3964
3965 test_32l() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         test_mkdir -p $DIR/$tdir/d2
3974         touch $DIR/$tdir/d2/test_file || error "touch failed"
3975         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3976                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3977         cleanup_test32_mount
3978 }
3979 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3980
3981 test_32m() {
3982         rm -fr $DIR/d32m
3983         test_mkdir -p $DIR/d32m/tmp
3984         TMP_DIR=$DIR/d32m/tmp
3985         ln -s $DIR $TMP_DIR/symlink11
3986         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3987         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3988                 error "symlink11 not a link"
3989         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3990                 error "symlink01 not a link"
3991 }
3992 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3993
3994 test_32n() {
3995         rm -fr $DIR/d32n
3996         test_mkdir -p $DIR/d32n/tmp
3997         TMP_DIR=$DIR/d32n/tmp
3998         ln -s $DIR $TMP_DIR/symlink11
3999         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4000         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4001         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4002 }
4003 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4004
4005 test_32o() {
4006         touch $DIR/$tfile
4007         test_mkdir -p $DIR/d32o/tmp
4008         TMP_DIR=$DIR/d32o/tmp
4009         ln -s $DIR/$tfile $TMP_DIR/symlink12
4010         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4011         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4012                 error "symlink12 not a link"
4013         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4014         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4015                 error "$DIR/d32o/tmp/symlink12 not file type"
4016         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4017                 error "$DIR/d32o/symlink02 not file type"
4018 }
4019 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4020
4021 test_32p() {
4022         log 32p_1
4023         rm -fr $DIR/d32p
4024         log 32p_2
4025         rm -f $DIR/$tfile
4026         log 32p_3
4027         touch $DIR/$tfile
4028         log 32p_4
4029         test_mkdir -p $DIR/d32p/tmp
4030         log 32p_5
4031         TMP_DIR=$DIR/d32p/tmp
4032         log 32p_6
4033         ln -s $DIR/$tfile $TMP_DIR/symlink12
4034         log 32p_7
4035         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4036         log 32p_8
4037         cat $DIR/d32p/tmp/symlink12 ||
4038                 error "Can't open $DIR/d32p/tmp/symlink12"
4039         log 32p_9
4040         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4041         log 32p_10
4042 }
4043 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4044
4045 test_32q() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4055         cleanup_test32_mount
4056 }
4057 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4058
4059 test_32r() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4069         cleanup_test32_mount
4070 }
4071 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4072
4073 test_33aa() {
4074         rm -f $DIR/$tfile
4075         touch $DIR/$tfile
4076         chmod 444 $DIR/$tfile
4077         chown $RUNAS_ID $DIR/$tfile
4078         log 33_1
4079         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4080         log 33_2
4081 }
4082 run_test 33aa "write file with mode 444 (should return error)"
4083
4084 test_33a() {
4085         rm -fr $DIR/$tdir
4086         test_mkdir $DIR/$tdir
4087         chown $RUNAS_ID $DIR/$tdir
4088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4089                 error "$RUNAS create $tdir/$tfile failed"
4090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4091                 error "open RDWR" || true
4092 }
4093 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4094
4095 test_33b() {
4096         rm -fr $DIR/$tdir
4097         test_mkdir $DIR/$tdir
4098         chown $RUNAS_ID $DIR/$tdir
4099         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4100 }
4101 run_test 33b "test open file with malformed flags (No panic)"
4102
4103 test_33c() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105         remote_ost_nodsh && skip "remote OST with nodsh"
4106
4107         local ostnum
4108         local ostname
4109         local write_bytes
4110         local all_zeros
4111
4112         all_zeros=true
4113         test_mkdir $DIR/$tdir
4114         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4115
4116         sync
4117         for ostnum in $(seq $OSTCOUNT); do
4118                 # test-framework's OST numbering is one-based, while Lustre's
4119                 # is zero-based
4120                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4121                 # check if at least some write_bytes stats are counted
4122                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4123                               obdfilter.$ostname.stats |
4124                               awk '/^write_bytes/ {print $7}' )
4125                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4126                 if (( ${write_bytes:-0} > 0 )); then
4127                         all_zeros=false
4128                         break
4129                 fi
4130         done
4131
4132         $all_zeros || return 0
4133
4134         # Write four bytes
4135         echo foo > $DIR/$tdir/bar
4136         # Really write them
4137         sync
4138
4139         # Total up write_bytes after writing.  We'd better find non-zeros.
4140         for ostnum in $(seq $OSTCOUNT); do
4141                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4142                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4143                               obdfilter/$ostname/stats |
4144                               awk '/^write_bytes/ {print $7}' )
4145                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4146                 if (( ${write_bytes:-0} > 0 )); then
4147                         all_zeros=false
4148                         break
4149                 fi
4150         done
4151
4152         if $all_zeros; then
4153                 for ostnum in $(seq $OSTCOUNT); do
4154                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4155                         echo "Check write_bytes is in obdfilter.*.stats:"
4156                         do_facet ost$ostnum lctl get_param -n \
4157                                 obdfilter.$ostname.stats
4158                 done
4159                 error "OST not keeping write_bytes stats (b=22312)"
4160         fi
4161 }
4162 run_test 33c "test write_bytes stats"
4163
4164 test_33d() {
4165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4167
4168         local MDTIDX=1
4169         local remote_dir=$DIR/$tdir/remote_dir
4170
4171         test_mkdir $DIR/$tdir
4172         $LFS mkdir -i $MDTIDX $remote_dir ||
4173                 error "create remote directory failed"
4174
4175         touch $remote_dir/$tfile
4176         chmod 444 $remote_dir/$tfile
4177         chown $RUNAS_ID $remote_dir/$tfile
4178
4179         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4180
4181         chown $RUNAS_ID $remote_dir
4182         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4183                                         error "create" || true
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4185                                     error "open RDWR" || true
4186         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4187 }
4188 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4189
4190 test_33e() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192
4193         mkdir $DIR/$tdir
4194
4195         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4196         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4197         mkdir $DIR/$tdir/local_dir
4198
4199         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4200         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4201         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4202
4203         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4204                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4205
4206         rmdir $DIR/$tdir/* || error "rmdir failed"
4207
4208         umask 777
4209         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4210         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4211         mkdir $DIR/$tdir/local_dir
4212
4213         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4214         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4215         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4216
4217         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4218                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4219
4220         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4221
4222         umask 000
4223         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4224         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4225         mkdir $DIR/$tdir/local_dir
4226
4227         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4228         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4229         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4230
4231         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4232                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4233 }
4234 run_test 33e "mkdir and striped directory should have same mode"
4235
4236 cleanup_33f() {
4237         trap 0
4238         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4239 }
4240
4241 test_33f() {
4242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4243         remote_mds_nodsh && skip "remote MDS with nodsh"
4244
4245         mkdir $DIR/$tdir
4246         chmod go+rwx $DIR/$tdir
4247         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4248         trap cleanup_33f EXIT
4249
4250         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4251                 error "cannot create striped directory"
4252
4253         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4254                 error "cannot create files in striped directory"
4255
4256         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4257                 error "cannot remove files in striped directory"
4258
4259         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4260                 error "cannot remove striped directory"
4261
4262         cleanup_33f
4263 }
4264 run_test 33f "nonroot user can create, access, and remove a striped directory"
4265
4266 test_33g() {
4267         mkdir -p $DIR/$tdir/dir2
4268
4269         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4270         echo $err
4271         [[ $err =~ "exists" ]] || error "Not exists error"
4272 }
4273 run_test 33g "nonroot user create already existing root created file"
4274
4275 sub_33h() {
4276         local hash_type=$1
4277         local count=250
4278
4279         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4280                 error "lfs mkdir -H $hash_type $tdir failed"
4281         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4282
4283         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4284         local index2
4285         local fname
4286
4287         for fname in $DIR/$tdir/$tfile.bak \
4288                      $DIR/$tdir/$tfile.SAV \
4289                      $DIR/$tdir/$tfile.orig \
4290                      $DIR/$tdir/$tfile~; do
4291                 touch $fname || error "touch $fname failed"
4292                 index2=$($LFS getstripe -m $fname)
4293                 (( $index == $index2 )) ||
4294                         error "$fname MDT index mismatch $index != $index2"
4295         done
4296
4297         local failed=0
4298         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4299         local pattern
4300
4301         for pattern in ${patterns[*]}; do
4302                 echo "pattern $pattern"
4303                 fname=$DIR/$tdir/$pattern
4304                 for (( i = 0; i < $count; i++ )); do
4305                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4306                                 error "mktemp $DIR/$tdir/$pattern failed"
4307                         index2=$($LFS getstripe -m $fname)
4308                         (( $index == $index2 )) && continue
4309
4310                         failed=$((failed + 1))
4311                         echo "$fname MDT index mismatch $index != $index2"
4312                 done
4313         done
4314
4315         echo "$failed/$count MDT index mismatches, expect ~2-4"
4316         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4317
4318         local same=0
4319         local expect
4320
4321         # verify that "crush" is still broken with all files on same MDT,
4322         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4323         [[ "$hash_type" == "crush" ]] && expect=$count ||
4324                 expect=$((count / MDSCOUNT))
4325
4326         # crush2 doesn't put all-numeric suffixes on the same MDT,
4327         # filename like $tfile.12345678 should *not* be considered temp
4328         for pattern in ${patterns[*]}; do
4329                 local base=${pattern%%X*}
4330                 local suff=${pattern#$base}
4331
4332                 echo "pattern $pattern"
4333                 for (( i = 0; i < $count; i++ )); do
4334                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4335                         touch $fname || error "touch $fname failed"
4336                         index2=$($LFS getstripe -m $fname)
4337                         (( $index != $index2 )) && continue
4338
4339                         same=$((same + 1))
4340                 done
4341         done
4342
4343         # the number of "bad" hashes is random, as it depends on the random
4344         # filenames generated by "mktemp".  Allow some margin in the results.
4345         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4346         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4347            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4348                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4349         same=0
4350
4351         # crush2 doesn't put suffixes with special characters on the same MDT
4352         # filename like $tfile.txt.1234 should *not* be considered temp
4353         for pattern in ${patterns[*]}; do
4354                 local base=${pattern%%X*}
4355                 local suff=${pattern#$base}
4356
4357                 pattern=$base...${suff/XXX}
4358                 echo "pattern=$pattern"
4359                 for (( i = 0; i < $count; i++ )); do
4360                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4361                                 error "touch $fname failed"
4362                         index2=$($LFS getstripe -m $fname)
4363                         (( $index != $index2 )) && continue
4364
4365                         same=$((same + 1))
4366                 done
4367         done
4368
4369         # the number of "bad" hashes is random, as it depends on the random
4370         # filenames generated by "mktemp".  Allow some margin in the results.
4371         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4372         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4373            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4374                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4375 }
4376
4377 test_33h() {
4378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4379         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4380                 skip "Need MDS version at least 2.13.50"
4381
4382         sub_33h crush
4383 }
4384 run_test 33h "temp file is located on the same MDT as target (crush)"
4385
4386 test_33hh() {
4387         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4388         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4389         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4390                 skip "Need MDS version at least 2.15.0 for crush2"
4391
4392         sub_33h crush2
4393 }
4394 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4395
4396 test_33i()
4397 {
4398         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4399
4400         local FNAME=$(str_repeat 'f' 250)
4401
4402         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4403         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4404
4405         local count
4406         local total
4407
4408         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4409
4410         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4411
4412         lctl --device %$MDC deactivate
4413         stack_trap "lctl --device %$MDC activate"
4414         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4415         total=$(\ls -l $DIR/$tdir | wc -l)
4416         # "ls -l" will list total in the first line
4417         total=$((total - 1))
4418         (( total + count == 1000 )) ||
4419                 error "ls list $total files, $count files on MDT1"
4420 }
4421 run_test 33i "striped directory can be accessed when one MDT is down"
4422
4423 test_33j() {
4424         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4425
4426         mkdir -p $DIR/$tdir/
4427
4428         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4429                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4430
4431         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4432                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4433
4434         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4435                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4436
4437         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4438                 error "-D was not specified, but still failed"
4439 }
4440 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4441
4442 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4443 test_34a() {
4444         rm -f $DIR/f34
4445         $MCREATE $DIR/f34 || error "mcreate failed"
4446         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4447                 error "getstripe failed"
4448         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4449         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4450                 error "getstripe failed"
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453 }
4454 run_test 34a "truncate file that has not been opened ==========="
4455
4456 test_34b() {
4457         [ ! -f $DIR/f34 ] && test_34a
4458         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4459                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4460         $OPENFILE -f O_RDONLY $DIR/f34
4461         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4462                 error "getstripe failed"
4463         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4464                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4465 }
4466 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4467
4468 test_34c() {
4469         [ ! -f $DIR/f34 ] && test_34a
4470         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4471                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4472         $OPENFILE -f O_RDWR $DIR/f34
4473         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4474                 error "$LFS getstripe failed"
4475         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4476                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4477 }
4478 run_test 34c "O_RDWR opening file-with-size works =============="
4479
4480 test_34d() {
4481         [ ! -f $DIR/f34 ] && test_34a
4482         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4483                 error "dd failed"
4484         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4485                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4486         rm $DIR/f34
4487 }
4488 run_test 34d "write to sparse file ============================="
4489
4490 test_34e() {
4491         rm -f $DIR/f34e
4492         $MCREATE $DIR/f34e || error "mcreate failed"
4493         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4494         $CHECKSTAT -s 1000 $DIR/f34e ||
4495                 error "Size of $DIR/f34e not equal to 1000 bytes"
4496         $OPENFILE -f O_RDWR $DIR/f34e
4497         $CHECKSTAT -s 1000 $DIR/f34e ||
4498                 error "Size of $DIR/f34e not equal to 1000 bytes"
4499 }
4500 run_test 34e "create objects, some with size and some without =="
4501
4502 test_34f() { # bug 6242, 6243
4503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4504
4505         SIZE34F=48000
4506         rm -f $DIR/f34f
4507         $MCREATE $DIR/f34f || error "mcreate failed"
4508         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4509         dd if=$DIR/f34f of=$TMP/f34f
4510         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4511         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4512         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4513         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4514         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4515 }
4516 run_test 34f "read from a file with no objects until EOF ======="
4517
4518 test_34g() {
4519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4520
4521         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4522                 error "dd failed"
4523         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4524         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4525                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4526         cancel_lru_locks osc
4527         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4528                 error "wrong size after lock cancel"
4529
4530         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4531         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4532                 error "expanding truncate failed"
4533         cancel_lru_locks osc
4534         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4535                 error "wrong expanded size after lock cancel"
4536 }
4537 run_test 34g "truncate long file ==============================="
4538
4539 test_34h() {
4540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4541
4542         local gid=10
4543         local sz=1000
4544
4545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4546         sync # Flush the cache so that multiop below does not block on cache
4547              # flush when getting the group lock
4548         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4549         MULTIPID=$!
4550
4551         # Since just timed wait is not good enough, let's do a sync write
4552         # that way we are sure enough time for a roundtrip + processing
4553         # passed + 2 seconds of extra margin.
4554         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4555         rm $DIR/${tfile}-1
4556         sleep 2
4557
4558         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4559                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4560                 kill -9 $MULTIPID
4561         fi
4562         wait $MULTIPID
4563         local nsz=`stat -c %s $DIR/$tfile`
4564         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4565 }
4566 run_test 34h "ftruncate file under grouplock should not block"
4567
4568 test_35a() {
4569         cp /bin/sh $DIR/f35a
4570         chmod 444 $DIR/f35a
4571         chown $RUNAS_ID $DIR/f35a
4572         $RUNAS $DIR/f35a && error || true
4573         rm $DIR/f35a
4574 }
4575 run_test 35a "exec file with mode 444 (should return and not leak)"
4576
4577 test_36a() {
4578         rm -f $DIR/f36
4579         utime $DIR/f36 || error "utime failed for MDS"
4580 }
4581 run_test 36a "MDS utime check (mknod, utime)"
4582
4583 test_36b() {
4584         echo "" > $DIR/f36
4585         utime $DIR/f36 || error "utime failed for OST"
4586 }
4587 run_test 36b "OST utime check (open, utime)"
4588
4589 test_36c() {
4590         rm -f $DIR/d36/f36
4591         test_mkdir $DIR/d36
4592         chown $RUNAS_ID $DIR/d36
4593         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4594 }
4595 run_test 36c "non-root MDS utime check (mknod, utime)"
4596
4597 test_36d() {
4598         [ ! -d $DIR/d36 ] && test_36c
4599         echo "" > $DIR/d36/f36
4600         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4601 }
4602 run_test 36d "non-root OST utime check (open, utime)"
4603
4604 test_36e() {
4605         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4606
4607         test_mkdir $DIR/$tdir
4608         touch $DIR/$tdir/$tfile
4609         $RUNAS utime $DIR/$tdir/$tfile &&
4610                 error "utime worked, expected failure" || true
4611 }
4612 run_test 36e "utime on non-owned file (should return error)"
4613
4614 subr_36fh() {
4615         local fl="$1"
4616         local LANG_SAVE=$LANG
4617         local LC_LANG_SAVE=$LC_LANG
4618         export LANG=C LC_LANG=C # for date language
4619
4620         DATESTR="Dec 20  2000"
4621         test_mkdir $DIR/$tdir
4622         lctl set_param fail_loc=$fl
4623         date; date +%s
4624         cp /etc/hosts $DIR/$tdir/$tfile
4625         sync & # write RPC generated with "current" inode timestamp, but delayed
4626         sleep 1
4627         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4628         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4629         cancel_lru_locks $OSC
4630         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4631         date; date +%s
4632         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4633                 echo "BEFORE: $LS_BEFORE" && \
4634                 echo "AFTER : $LS_AFTER" && \
4635                 echo "WANT  : $DATESTR" && \
4636                 error "$DIR/$tdir/$tfile timestamps changed" || true
4637
4638         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4639 }
4640
4641 test_36f() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643
4644         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4645         subr_36fh "0x80000214"
4646 }
4647 run_test 36f "utime on file racing with OST BRW write =========="
4648
4649 test_36g() {
4650         remote_ost_nodsh && skip "remote OST with nodsh"
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4653                 skip "Need MDS version at least 2.12.51"
4654
4655         local fmd_max_age
4656         local fmd
4657         local facet="ost1"
4658         local tgt="obdfilter"
4659
4660         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4661
4662         test_mkdir $DIR/$tdir
4663         fmd_max_age=$(do_facet $facet \
4664                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4665                 head -n 1")
4666
4667         echo "FMD max age: ${fmd_max_age}s"
4668         touch $DIR/$tdir/$tfile
4669         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4670                 gawk '{cnt=cnt+$1}  END{print cnt}')
4671         echo "FMD before: $fmd"
4672         [[ $fmd == 0 ]] &&
4673                 error "FMD wasn't create by touch"
4674         sleep $((fmd_max_age + 12))
4675         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4676                 gawk '{cnt=cnt+$1}  END{print cnt}')
4677         echo "FMD after: $fmd"
4678         [[ $fmd == 0 ]] ||
4679                 error "FMD wasn't expired by ping"
4680 }
4681 run_test 36g "FMD cache expiry ====================="
4682
4683 test_36h() {
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685
4686         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4687         subr_36fh "0x80000227"
4688 }
4689 run_test 36h "utime on file racing with OST BRW write =========="
4690
4691 test_36i() {
4692         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4693
4694         test_mkdir $DIR/$tdir
4695         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4696
4697         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4698         local new_mtime=$((mtime + 200))
4699
4700         #change Modify time of striped dir
4701         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4702                         error "change mtime failed"
4703
4704         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4705
4706         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4707 }
4708 run_test 36i "change mtime on striped directory"
4709
4710 # test_37 - duplicate with tests 32q 32r
4711
4712 test_38() {
4713         local file=$DIR/$tfile
4714         touch $file
4715         openfile -f O_DIRECTORY $file
4716         local RC=$?
4717         local ENOTDIR=20
4718         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4719         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4720 }
4721 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4722
4723 test_39a() { # was test_39
4724         touch $DIR/$tfile
4725         touch $DIR/${tfile}2
4726 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4727 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4728 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4729         sleep 2
4730         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4731         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4732                 echo "mtime"
4733                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4734                 echo "atime"
4735                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4736                 echo "ctime"
4737                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4738                 error "O_TRUNC didn't change timestamps"
4739         fi
4740 }
4741 run_test 39a "mtime changed on create"
4742
4743 test_39b() {
4744         test_mkdir -c1 $DIR/$tdir
4745         cp -p /etc/passwd $DIR/$tdir/fopen
4746         cp -p /etc/passwd $DIR/$tdir/flink
4747         cp -p /etc/passwd $DIR/$tdir/funlink
4748         cp -p /etc/passwd $DIR/$tdir/frename
4749         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4750
4751         sleep 1
4752         echo "aaaaaa" >> $DIR/$tdir/fopen
4753         echo "aaaaaa" >> $DIR/$tdir/flink
4754         echo "aaaaaa" >> $DIR/$tdir/funlink
4755         echo "aaaaaa" >> $DIR/$tdir/frename
4756
4757         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4758         local link_new=`stat -c %Y $DIR/$tdir/flink`
4759         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4760         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4761
4762         cat $DIR/$tdir/fopen > /dev/null
4763         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4764         rm -f $DIR/$tdir/funlink2
4765         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4766
4767         for (( i=0; i < 2; i++ )) ; do
4768                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4769                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4770                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4771                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4772
4773                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4774                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4775                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4776                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4777
4778                 cancel_lru_locks $OSC
4779                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4780         done
4781 }
4782 run_test 39b "mtime change on open, link, unlink, rename  ======"
4783
4784 # this should be set to past
4785 TEST_39_MTIME=`date -d "1 year ago" +%s`
4786
4787 # bug 11063
4788 test_39c() {
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local mtime0=`stat -c %Y $DIR1/$tfile`
4792
4793         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4794         local mtime1=`stat -c %Y $DIR1/$tfile`
4795         [ "$mtime1" = $TEST_39_MTIME ] || \
4796                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4797
4798         local d1=`date +%s`
4799         echo hello >> $DIR1/$tfile
4800         local d2=`date +%s`
4801         local mtime2=`stat -c %Y $DIR1/$tfile`
4802         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4803                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4804
4805         mv $DIR1/$tfile $DIR1/$tfile-1
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4809                 [ "$mtime2" = "$mtime3" ] || \
4810                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39c "mtime change on rename ==========================="
4817
4818 # bug 21114
4819 test_39d() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4824
4825         for (( i=0; i < 2; i++ )) ; do
4826                 local mtime=`stat -c %Y $DIR1/$tfile`
4827                 [ $mtime = $TEST_39_MTIME ] || \
4828                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4829
4830                 cancel_lru_locks $OSC
4831                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4832         done
4833 }
4834 run_test 39d "create, utime, stat =============================="
4835
4836 # bug 21114
4837 test_39e() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         touch $DIR1/$tfile
4841         local mtime1=`stat -c %Y $DIR1/$tfile`
4842
4843         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4844
4845         for (( i=0; i < 2; i++ )) ; do
4846                 local mtime2=`stat -c %Y $DIR1/$tfile`
4847                 [ $mtime2 = $TEST_39_MTIME ] || \
4848                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4849
4850                 cancel_lru_locks $OSC
4851                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4852         done
4853 }
4854 run_test 39e "create, stat, utime, stat ========================"
4855
4856 # bug 21114
4857 test_39f() {
4858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4859
4860         touch $DIR1/$tfile
4861         mtime1=`stat -c %Y $DIR1/$tfile`
4862
4863         sleep 2
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865
4866         for (( i=0; i < 2; i++ )) ; do
4867                 local mtime2=`stat -c %Y $DIR1/$tfile`
4868                 [ $mtime2 = $TEST_39_MTIME ] || \
4869                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4870
4871                 cancel_lru_locks $OSC
4872                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4873         done
4874 }
4875 run_test 39f "create, stat, sleep, utime, stat ================="
4876
4877 # bug 11063
4878 test_39g() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         echo hello >> $DIR1/$tfile
4882         local mtime1=`stat -c %Y $DIR1/$tfile`
4883
4884         sleep 2
4885         chmod o+r $DIR1/$tfile
4886
4887         for (( i=0; i < 2; i++ )) ; do
4888                 local mtime2=`stat -c %Y $DIR1/$tfile`
4889                 [ "$mtime1" = "$mtime2" ] || \
4890                         error "lost mtime: $mtime2, should be $mtime1"
4891
4892                 cancel_lru_locks $OSC
4893                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4894         done
4895 }
4896 run_test 39g "write, chmod, stat ==============================="
4897
4898 # bug 11063
4899 test_39h() {
4900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4901
4902         touch $DIR1/$tfile
4903         sleep 1
4904
4905         local d1=`date`
4906         echo hello >> $DIR1/$tfile
4907         local mtime1=`stat -c %Y $DIR1/$tfile`
4908
4909         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4910         local d2=`date`
4911         if [ "$d1" != "$d2" ]; then
4912                 echo "write and touch not within one second"
4913         else
4914                 for (( i=0; i < 2; i++ )) ; do
4915                         local mtime2=`stat -c %Y $DIR1/$tfile`
4916                         [ "$mtime2" = $TEST_39_MTIME ] || \
4917                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4918
4919                         cancel_lru_locks $OSC
4920                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4921                 done
4922         fi
4923 }
4924 run_test 39h "write, utime within one second, stat ============="
4925
4926 test_39i() {
4927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4928
4929         touch $DIR1/$tfile
4930         sleep 1
4931
4932         echo hello >> $DIR1/$tfile
4933         local mtime1=`stat -c %Y $DIR1/$tfile`
4934
4935         mv $DIR1/$tfile $DIR1/$tfile-1
4936
4937         for (( i=0; i < 2; i++ )) ; do
4938                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4939
4940                 [ "$mtime1" = "$mtime2" ] || \
4941                         error "lost mtime: $mtime2, should be $mtime1"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39i "write, rename, stat =============================="
4948
4949 test_39j() {
4950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4951
4952         start_full_debug_logging
4953         touch $DIR1/$tfile
4954         sleep 1
4955
4956         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4957         lctl set_param fail_loc=0x80000412
4958         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4959                 error "multiop failed"
4960         local multipid=$!
4961         local mtime1=`stat -c %Y $DIR1/$tfile`
4962
4963         mv $DIR1/$tfile $DIR1/$tfile-1
4964
4965         kill -USR1 $multipid
4966         wait $multipid || error "multiop close failed"
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4970                 [ "$mtime1" = "$mtime2" ] ||
4971                         error "mtime is lost on close: $mtime2, " \
4972                               "should be $mtime1"
4973
4974                 cancel_lru_locks
4975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4976         done
4977         lctl set_param fail_loc=0
4978         stop_full_debug_logging
4979 }
4980 run_test 39j "write, rename, close, stat ======================="
4981
4982 test_39k() {
4983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4984
4985         touch $DIR1/$tfile
4986         sleep 1
4987
4988         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4989         local multipid=$!
4990         local mtime1=`stat -c %Y $DIR1/$tfile`
4991
4992         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4993
4994         kill -USR1 $multipid
4995         wait $multipid || error "multiop close failed"
4996
4997         for (( i=0; i < 2; i++ )) ; do
4998                 local mtime2=`stat -c %Y $DIR1/$tfile`
4999
5000                 [ "$mtime2" = $TEST_39_MTIME ] || \
5001                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5002
5003                 cancel_lru_locks
5004                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5005         done
5006 }
5007 run_test 39k "write, utime, close, stat ========================"
5008
5009 # this should be set to future
5010 TEST_39_ATIME=`date -d "1 year" +%s`
5011
5012 test_39l() {
5013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5014         remote_mds_nodsh && skip "remote MDS with nodsh"
5015
5016         local atime_diff=$(do_facet $SINGLEMDS \
5017                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5018         rm -rf $DIR/$tdir
5019         mkdir_on_mdt0 $DIR/$tdir
5020
5021         # test setting directory atime to future
5022         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5023         local atime=$(stat -c %X $DIR/$tdir)
5024         [ "$atime" = $TEST_39_ATIME ] ||
5025                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5026
5027         # test setting directory atime from future to now
5028         local now=$(date +%s)
5029         touch -a -d @$now $DIR/$tdir
5030
5031         atime=$(stat -c %X $DIR/$tdir)
5032         [ "$atime" -eq "$now"  ] ||
5033                 error "atime is not updated from future: $atime, $now"
5034
5035         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5036         sleep 3
5037
5038         # test setting directory atime when now > dir atime + atime_diff
5039         local d1=$(date +%s)
5040         ls $DIR/$tdir
5041         local d2=$(date +%s)
5042         cancel_lru_locks mdc
5043         atime=$(stat -c %X $DIR/$tdir)
5044         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5045                 error "atime is not updated  : $atime, should be $d2"
5046
5047         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5048         sleep 3
5049
5050         # test not setting directory atime when now < dir atime + atime_diff
5051         ls $DIR/$tdir
5052         cancel_lru_locks mdc
5053         atime=$(stat -c %X $DIR/$tdir)
5054         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5055                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5056
5057         do_facet $SINGLEMDS \
5058                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5059 }
5060 run_test 39l "directory atime update ==========================="
5061
5062 test_39m() {
5063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5064
5065         touch $DIR1/$tfile
5066         sleep 2
5067         local far_past_mtime=$(date -d "May 29 1953" +%s)
5068         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5069
5070         touch -m -d @$far_past_mtime $DIR1/$tfile
5071         touch -a -d @$far_past_atime $DIR1/$tfile
5072
5073         for (( i=0; i < 2; i++ )) ; do
5074                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5075                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5076                         error "atime or mtime set incorrectly"
5077
5078                 cancel_lru_locks $OSC
5079                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5080         done
5081 }
5082 run_test 39m "test atime and mtime before 1970"
5083
5084 test_39n() { # LU-3832
5085         remote_mds_nodsh && skip "remote MDS with nodsh"
5086
5087         local atime_diff=$(do_facet $SINGLEMDS \
5088                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5089         local atime0
5090         local atime1
5091         local atime2
5092
5093         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5094
5095         rm -rf $DIR/$tfile
5096         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5097         atime0=$(stat -c %X $DIR/$tfile)
5098
5099         sleep 5
5100         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5101         atime1=$(stat -c %X $DIR/$tfile)
5102
5103         sleep 5
5104         cancel_lru_locks mdc
5105         cancel_lru_locks osc
5106         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5107         atime2=$(stat -c %X $DIR/$tfile)
5108
5109         do_facet $SINGLEMDS \
5110                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5111
5112         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5113         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5114 }
5115 run_test 39n "check that O_NOATIME is honored"
5116
5117 test_39o() {
5118         TESTDIR=$DIR/$tdir/$tfile
5119         [ -e $TESTDIR ] && rm -rf $TESTDIR
5120         mkdir -p $TESTDIR
5121         cd $TESTDIR
5122         links1=2
5123         ls
5124         mkdir a b
5125         ls
5126         links2=$(stat -c %h .)
5127         [ $(($links1 + 2)) != $links2 ] &&
5128                 error "wrong links count $(($links1 + 2)) != $links2"
5129         rmdir b
5130         links3=$(stat -c %h .)
5131         [ $(($links1 + 1)) != $links3 ] &&
5132                 error "wrong links count $links1 != $links3"
5133         return 0
5134 }
5135 run_test 39o "directory cached attributes updated after create"
5136
5137 test_39p() {
5138         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5139
5140         local MDTIDX=1
5141         TESTDIR=$DIR/$tdir/$tdir
5142         [ -e $TESTDIR ] && rm -rf $TESTDIR
5143         test_mkdir -p $TESTDIR
5144         cd $TESTDIR
5145         links1=2
5146         ls
5147         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5148         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5149         ls
5150         links2=$(stat -c %h .)
5151         [ $(($links1 + 2)) != $links2 ] &&
5152                 error "wrong links count $(($links1 + 2)) != $links2"
5153         rmdir remote_dir2
5154         links3=$(stat -c %h .)
5155         [ $(($links1 + 1)) != $links3 ] &&
5156                 error "wrong links count $links1 != $links3"
5157         return 0
5158 }
5159 run_test 39p "remote directory cached attributes updated after create ========"
5160
5161 test_39r() {
5162         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5163                 skip "no atime update on old OST"
5164         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5165                 skip_env "ldiskfs only test"
5166         fi
5167
5168         local saved_adiff
5169         saved_adiff=$(do_facet ost1 \
5170                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5171         stack_trap "do_facet ost1 \
5172                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5173
5174         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5175
5176         $LFS setstripe -i 0 $DIR/$tfile
5177         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5178                 error "can't write initial file"
5179         cancel_lru_locks osc
5180
5181         # exceed atime_diff and access file
5182         sleep 10
5183         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5184                 error "can't udpate atime"
5185
5186         local atime_cli=$(stat -c %X $DIR/$tfile)
5187         echo "client atime: $atime_cli"
5188         # allow atime update to be written to device
5189         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5190         sleep 5
5191
5192         local ostdev=$(ostdevname 1)
5193         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5194         local seq=${fid[3]#0x}
5195         local oid=${fid[1]}
5196         local oid_hex
5197
5198         if [ $seq == 0 ]; then
5199                 oid_hex=${fid[1]}
5200         else
5201                 oid_hex=${fid[2]#0x}
5202         fi
5203         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5204         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5205
5206         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5207         local atime_ost=$(do_facet ost1 "$cmd" |&
5208                           awk -F'[: ]' '/atime:/ { print $4 }')
5209         (( atime_cli == atime_ost )) ||
5210                 error "atime on client $atime_cli != ost $atime_ost"
5211 }
5212 run_test 39r "lazy atime update on OST"
5213
5214 test_39q() { # LU-8041
5215         local testdir=$DIR/$tdir
5216         mkdir -p $testdir
5217         multiop_bg_pause $testdir D_c || error "multiop failed"
5218         local multipid=$!
5219         cancel_lru_locks mdc
5220         kill -USR1 $multipid
5221         local atime=$(stat -c %X $testdir)
5222         [ "$atime" -ne 0 ] || error "atime is zero"
5223 }
5224 run_test 39q "close won't zero out atime"
5225
5226 test_39s() {
5227         local atime0
5228         local atime1
5229         local atime2
5230         local atime3
5231         local atime4
5232
5233         umount_client $MOUNT
5234         mount_client $MOUNT relatime
5235
5236         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5237         atime0=$(stat -c %X $DIR/$tfile)
5238
5239         # First read updates atime
5240         sleep 1
5241         cat $DIR/$tfile >/dev/null
5242         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5243
5244         # Next reads do not update atime
5245         sleep 1
5246         cat $DIR/$tfile >/dev/null
5247         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5248
5249         # If mtime is greater than atime, atime is updated
5250         sleep 1
5251         touch -m $DIR/$tfile # (mtime = now)
5252         sleep 1
5253         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5254         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5255
5256         # Next reads do not update atime
5257         sleep 1
5258         cat $DIR/$tfile >/dev/null
5259         atime4=$(stat -c %X $DIR/$tfile)
5260
5261         # Remount the client to clear 'relatime' option
5262         remount_client $MOUNT
5263
5264         if (( MDS1_VERSION >= $(version_code 2.15.50) )); then
5265                 # The full test lasted less than default atime_diff
5266                 # Client was remounted to clear 'relatime' option for next tests
5267                 # and to confirm atime was written to disk
5268                 local atime5=$(stat -c %X $DIR/$tfile)
5269                 (( atime3 == atime5 )) ||
5270                         error "atime3 $atime3 != atime5 $atime5"
5271         fi
5272
5273         (( atime0 < atime1 )) ||
5274                 error "atime $atime0 should be smaller than $atime1"
5275         (( atime1 == atime2 )) ||
5276                 error "atime $atime1 was updated to $atime2"
5277         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5278         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5279 }
5280 run_test 39s "relatime is supported"
5281
5282 test_40() {
5283         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5284         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5285                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5286         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5287                 error "$tfile is not 4096 bytes in size"
5288 }
5289 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5290
5291 test_41() {
5292         # bug 1553
5293         small_write $DIR/f41 18
5294 }
5295 run_test 41 "test small file write + fstat ====================="
5296
5297 count_ost_writes() {
5298         lctl get_param -n ${OSC}.*.stats |
5299                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5300                         END { printf("%0.0f", writes) }'
5301 }
5302
5303 # decent default
5304 WRITEBACK_SAVE=500
5305 DIRTY_RATIO_SAVE=40
5306 MAX_DIRTY_RATIO=50
5307 BG_DIRTY_RATIO_SAVE=10
5308 MAX_BG_DIRTY_RATIO=25
5309
5310 start_writeback() {
5311         trap 0
5312         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5313         # dirty_ratio, dirty_background_ratio
5314         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5315                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5316                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5317                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5318         else
5319                 # if file not here, we are a 2.4 kernel
5320                 kill -CONT `pidof kupdated`
5321         fi
5322 }
5323
5324 stop_writeback() {
5325         # setup the trap first, so someone cannot exit the test at the
5326         # exact wrong time and mess up a machine
5327         trap start_writeback EXIT
5328         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5329         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5330                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5331                 sysctl -w vm.dirty_writeback_centisecs=0
5332                 sysctl -w vm.dirty_writeback_centisecs=0
5333                 # save and increase /proc/sys/vm/dirty_ratio
5334                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5335                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5336                 # save and increase /proc/sys/vm/dirty_background_ratio
5337                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5338                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5339         else
5340                 # if file not here, we are a 2.4 kernel
5341                 kill -STOP `pidof kupdated`
5342         fi
5343 }
5344
5345 # ensure that all stripes have some grant before we test client-side cache
5346 setup_test42() {
5347         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5348                 dd if=/dev/zero of=$i bs=4k count=1
5349                 rm $i
5350         done
5351 }
5352
5353 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5354 # file truncation, and file removal.
5355 test_42a() {
5356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5357
5358         setup_test42
5359         cancel_lru_locks $OSC
5360         stop_writeback
5361         sync; sleep 1; sync # just to be safe
5362         BEFOREWRITES=`count_ost_writes`
5363         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5364         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5365         AFTERWRITES=`count_ost_writes`
5366         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5367                 error "$BEFOREWRITES < $AFTERWRITES"
5368         start_writeback
5369 }
5370 run_test 42a "ensure that we don't flush on close"
5371
5372 test_42b() {
5373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5374
5375         setup_test42
5376         cancel_lru_locks $OSC
5377         stop_writeback
5378         sync
5379         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5380         BEFOREWRITES=$(count_ost_writes)
5381         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5382         AFTERWRITES=$(count_ost_writes)
5383         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5384                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5385         fi
5386         BEFOREWRITES=$(count_ost_writes)
5387         sync || error "sync: $?"
5388         AFTERWRITES=$(count_ost_writes)
5389         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5390                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5391         fi
5392         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5393         start_writeback
5394         return 0
5395 }
5396 run_test 42b "test destroy of file with cached dirty data ======"
5397
5398 # if these tests just want to test the effect of truncation,
5399 # they have to be very careful.  consider:
5400 # - the first open gets a {0,EOF}PR lock
5401 # - the first write conflicts and gets a {0, count-1}PW
5402 # - the rest of the writes are under {count,EOF}PW
5403 # - the open for truncate tries to match a {0,EOF}PR
5404 #   for the filesize and cancels the PWs.
5405 # any number of fixes (don't get {0,EOF} on open, match
5406 # composite locks, do smarter file size management) fix
5407 # this, but for now we want these tests to verify that
5408 # the cancellation with truncate intent works, so we
5409 # start the file with a full-file pw lock to match against
5410 # until the truncate.
5411 trunc_test() {
5412         test=$1
5413         file=$DIR/$test
5414         offset=$2
5415         cancel_lru_locks $OSC
5416         stop_writeback
5417         # prime the file with 0,EOF PW to match
5418         touch $file
5419         $TRUNCATE $file 0
5420         sync; sync
5421         # now the real test..
5422         dd if=/dev/zero of=$file bs=1024 count=100
5423         BEFOREWRITES=`count_ost_writes`
5424         $TRUNCATE $file $offset
5425         cancel_lru_locks $OSC
5426         AFTERWRITES=`count_ost_writes`
5427         start_writeback
5428 }
5429
5430 test_42c() {
5431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5432
5433         trunc_test 42c 1024
5434         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5435                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5436         rm $file
5437 }
5438 run_test 42c "test partial truncate of file with cached dirty data"
5439
5440 test_42d() {
5441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5442
5443         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5444         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5445         $LCTL set_param debug=+cache
5446
5447         trunc_test 42d 0
5448         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5449                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5450         rm $file
5451 }
5452 run_test 42d "test complete truncate of file with cached dirty data"
5453
5454 test_42e() { # bug22074
5455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5456
5457         local TDIR=$DIR/${tdir}e
5458         local pages=16 # hardcoded 16 pages, don't change it.
5459         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5460         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5461         local max_dirty_mb
5462         local warmup_files
5463
5464         test_mkdir $DIR/${tdir}e
5465         $LFS setstripe -c 1 $TDIR
5466         createmany -o $TDIR/f $files
5467
5468         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5469
5470         # we assume that with $OSTCOUNT files, at least one of them will
5471         # be allocated on OST0.
5472         warmup_files=$((OSTCOUNT * max_dirty_mb))
5473         createmany -o $TDIR/w $warmup_files
5474
5475         # write a large amount of data into one file and sync, to get good
5476         # avail_grant number from OST.
5477         for ((i=0; i<$warmup_files; i++)); do
5478                 idx=$($LFS getstripe -i $TDIR/w$i)
5479                 [ $idx -ne 0 ] && continue
5480                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5481                 break
5482         done
5483         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5484         sync
5485         $LCTL get_param $proc_osc0/cur_dirty_bytes
5486         $LCTL get_param $proc_osc0/cur_grant_bytes
5487
5488         # create as much dirty pages as we can while not to trigger the actual
5489         # RPCs directly. but depends on the env, VFS may trigger flush during this
5490         # period, hopefully we are good.
5491         for ((i=0; i<$warmup_files; i++)); do
5492                 idx=$($LFS getstripe -i $TDIR/w$i)
5493                 [ $idx -ne 0 ] && continue
5494                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5495         done
5496         $LCTL get_param $proc_osc0/cur_dirty_bytes
5497         $LCTL get_param $proc_osc0/cur_grant_bytes
5498
5499         # perform the real test
5500         $LCTL set_param $proc_osc0/rpc_stats 0
5501         for ((;i<$files; i++)); do
5502                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5503                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5504         done
5505         sync
5506         $LCTL get_param $proc_osc0/rpc_stats
5507
5508         local percent=0
5509         local have_ppr=false
5510         $LCTL get_param $proc_osc0/rpc_stats |
5511                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5512                         # skip lines until we are at the RPC histogram data
5513                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5514                         $have_ppr || continue
5515
5516                         # we only want the percent stat for < 16 pages
5517                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5518
5519                         percent=$((percent + WPCT))
5520                         if [[ $percent -gt 15 ]]; then
5521                                 error "less than 16-pages write RPCs" \
5522                                       "$percent% > 15%"
5523                                 break
5524                         fi
5525                 done
5526         rm -rf $TDIR
5527 }
5528 run_test 42e "verify sub-RPC writes are not done synchronously"
5529
5530 test_43A() { # was test_43
5531         test_mkdir $DIR/$tdir
5532         cp -p /bin/ls $DIR/$tdir/$tfile
5533         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5534         pid=$!
5535         # give multiop a chance to open
5536         sleep 1
5537
5538         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5539         kill -USR1 $pid
5540         # Wait for multiop to exit
5541         wait $pid
5542 }
5543 run_test 43A "execution of file opened for write should return -ETXTBSY"
5544
5545 test_43a() {
5546         test_mkdir $DIR/$tdir
5547         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5548         $DIR/$tdir/sleep 60 &
5549         SLEEP_PID=$!
5550         # Make sure exec of $tdir/sleep wins race with truncate
5551         sleep 1
5552         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5553         kill $SLEEP_PID
5554 }
5555 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5556
5557 test_43b() {
5558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5559
5560         test_mkdir $DIR/$tdir
5561         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5562         $DIR/$tdir/sleep 60 &
5563         SLEEP_PID=$!
5564         # Make sure exec of $tdir/sleep wins race with truncate
5565         sleep 1
5566         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5567         kill $SLEEP_PID
5568 }
5569 run_test 43b "truncate of file being executed should return -ETXTBSY"
5570
5571 test_43c() {
5572         local testdir="$DIR/$tdir"
5573         test_mkdir $testdir
5574         cp $SHELL $testdir/
5575         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5576                 ( cd $testdir && md5sum -c )
5577 }
5578 run_test 43c "md5sum of copy into lustre"
5579
5580 test_44A() { # was test_44
5581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5582
5583         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5584         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5585 }
5586 run_test 44A "zero length read from a sparse stripe"
5587
5588 test_44a() {
5589         local nstripe=$($LFS getstripe -c -d $DIR)
5590         [ -z "$nstripe" ] && skip "can't get stripe info"
5591         [[ $nstripe -gt $OSTCOUNT ]] &&
5592                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5593
5594         local stride=$($LFS getstripe -S -d $DIR)
5595         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5596                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5597         fi
5598
5599         OFFSETS="0 $((stride/2)) $((stride-1))"
5600         for offset in $OFFSETS; do
5601                 for i in $(seq 0 $((nstripe-1))); do
5602                         local GLOBALOFFSETS=""
5603                         # size in Bytes
5604                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5605                         local myfn=$DIR/d44a-$size
5606                         echo "--------writing $myfn at $size"
5607                         ll_sparseness_write $myfn $size ||
5608                                 error "ll_sparseness_write"
5609                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5610                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5611                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5612
5613                         for j in $(seq 0 $((nstripe-1))); do
5614                                 # size in Bytes
5615                                 size=$((((j + $nstripe )*$stride + $offset)))
5616                                 ll_sparseness_write $myfn $size ||
5617                                         error "ll_sparseness_write"
5618                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5619                         done
5620                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5621                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5622                         rm -f $myfn
5623                 done
5624         done
5625 }
5626 run_test 44a "test sparse pwrite ==============================="
5627
5628 dirty_osc_total() {
5629         tot=0
5630         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5631                 tot=$(($tot + $d))
5632         done
5633         echo $tot
5634 }
5635 do_dirty_record() {
5636         before=`dirty_osc_total`
5637         echo executing "\"$*\""
5638         eval $*
5639         after=`dirty_osc_total`
5640         echo before $before, after $after
5641 }
5642 test_45() {
5643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5644
5645         f="$DIR/f45"
5646         # Obtain grants from OST if it supports it
5647         echo blah > ${f}_grant
5648         stop_writeback
5649         sync
5650         do_dirty_record "echo blah > $f"
5651         [[ $before -eq $after ]] && error "write wasn't cached"
5652         do_dirty_record "> $f"
5653         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5654         do_dirty_record "echo blah > $f"
5655         [[ $before -eq $after ]] && error "write wasn't cached"
5656         do_dirty_record "sync"
5657         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5658         do_dirty_record "echo blah > $f"
5659         [[ $before -eq $after ]] && error "write wasn't cached"
5660         do_dirty_record "cancel_lru_locks osc"
5661         [[ $before -gt $after ]] ||
5662                 error "lock cancellation didn't lower dirty count"
5663         start_writeback
5664 }
5665 run_test 45 "osc io page accounting ============================"
5666
5667 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5668 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5669 # objects offset and an assert hit when an rpc was built with 1023's mapped
5670 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5671 test_46() {
5672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5673
5674         f="$DIR/f46"
5675         stop_writeback
5676         sync
5677         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5678         sync
5679         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5680         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5681         sync
5682         start_writeback
5683 }
5684 run_test 46 "dirtying a previously written page ================"
5685
5686 # test_47 is removed "Device nodes check" is moved to test_28
5687
5688 test_48a() { # bug 2399
5689         [ "$mds1_FSTYPE" = "zfs" ] &&
5690         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5691                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5692
5693         test_mkdir $DIR/$tdir
5694         cd $DIR/$tdir
5695         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5696         test_mkdir $DIR/$tdir
5697         touch foo || error "'touch foo' failed after recreating cwd"
5698         test_mkdir bar
5699         touch .foo || error "'touch .foo' failed after recreating cwd"
5700         test_mkdir .bar
5701         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5702         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5703         cd . || error "'cd .' failed after recreating cwd"
5704         mkdir . && error "'mkdir .' worked after recreating cwd"
5705         rmdir . && error "'rmdir .' worked after recreating cwd"
5706         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5707         cd .. || error "'cd ..' failed after recreating cwd"
5708 }
5709 run_test 48a "Access renamed working dir (should return errors)="
5710
5711 test_48b() { # bug 2399
5712         rm -rf $DIR/$tdir
5713         test_mkdir $DIR/$tdir
5714         cd $DIR/$tdir
5715         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5716         touch foo && error "'touch foo' worked after removing cwd"
5717         mkdir foo && error "'mkdir foo' worked after removing cwd"
5718         touch .foo && error "'touch .foo' worked after removing cwd"
5719         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5720         ls . > /dev/null && error "'ls .' worked after removing cwd"
5721         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5722         mkdir . && error "'mkdir .' worked after removing cwd"
5723         rmdir . && error "'rmdir .' worked after removing cwd"
5724         ln -s . foo && error "'ln -s .' worked after removing cwd"
5725         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5726 }
5727 run_test 48b "Access removed working dir (should return errors)="
5728
5729 test_48c() { # bug 2350
5730         #lctl set_param debug=-1
5731         #set -vx
5732         rm -rf $DIR/$tdir
5733         test_mkdir -p $DIR/$tdir/dir
5734         cd $DIR/$tdir/dir
5735         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5736         $TRACE touch foo && error "touch foo worked after removing cwd"
5737         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5738         touch .foo && error "touch .foo worked after removing cwd"
5739         mkdir .foo && error "mkdir .foo worked after removing cwd"
5740         $TRACE ls . && error "'ls .' worked after removing cwd"
5741         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5742         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5743         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5744         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5745         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5746 }
5747 run_test 48c "Access removed working subdir (should return errors)"
5748
5749 test_48d() { # bug 2350
5750         #lctl set_param debug=-1
5751         #set -vx
5752         rm -rf $DIR/$tdir
5753         test_mkdir -p $DIR/$tdir/dir
5754         cd $DIR/$tdir/dir
5755         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5756         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5757         $TRACE touch foo && error "'touch foo' worked after removing parent"
5758         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5759         touch .foo && error "'touch .foo' worked after removing parent"
5760         mkdir .foo && error "mkdir .foo worked after removing parent"
5761         $TRACE ls . && error "'ls .' worked after removing parent"
5762         $TRACE ls .. && error "'ls ..' worked after removing parent"
5763         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5764         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5765         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5766         true
5767 }
5768 run_test 48d "Access removed parent subdir (should return errors)"
5769
5770 test_48e() { # bug 4134
5771         #lctl set_param debug=-1
5772         #set -vx
5773         rm -rf $DIR/$tdir
5774         test_mkdir -p $DIR/$tdir/dir
5775         cd $DIR/$tdir/dir
5776         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5777         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5778         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5779         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5780         # On a buggy kernel addition of "touch foo" after cd .. will
5781         # produce kernel oops in lookup_hash_it
5782         touch ../foo && error "'cd ..' worked after recreate parent"
5783         cd $DIR
5784         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5785 }
5786 run_test 48e "Access to recreated parent subdir (should return errors)"
5787
5788 test_48f() {
5789         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5790                 skip "need MDS >= 2.13.55"
5791         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5792         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5793                 skip "needs different host for mdt1 mdt2"
5794         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5795
5796         $LFS mkdir -i0 $DIR/$tdir
5797         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5798
5799         for d in sub1 sub2 sub3; do
5800                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5801                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5802                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5803         done
5804
5805         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5806 }
5807 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5808
5809 test_49() { # LU-1030
5810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5811         remote_ost_nodsh && skip "remote OST with nodsh"
5812
5813         # get ost1 size - $FSNAME-OST0000
5814         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5815                 awk '{ print $4 }')
5816         # write 800M at maximum
5817         [[ $ost1_size -lt 2 ]] && ost1_size=2
5818         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5819
5820         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5821         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5822         local dd_pid=$!
5823
5824         # change max_pages_per_rpc while writing the file
5825         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5826         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5827         # loop until dd process exits
5828         while ps ax -opid | grep -wq $dd_pid; do
5829                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5830                 sleep $((RANDOM % 5 + 1))
5831         done
5832         # restore original max_pages_per_rpc
5833         $LCTL set_param $osc1_mppc=$orig_mppc
5834         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5835 }
5836 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5837
5838 test_50() {
5839         # bug 1485
5840         test_mkdir $DIR/$tdir
5841         cd $DIR/$tdir
5842         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5843 }
5844 run_test 50 "special situations: /proc symlinks  ==============="
5845
5846 test_51a() {    # was test_51
5847         # bug 1516 - create an empty entry right after ".." then split dir
5848         test_mkdir -c1 $DIR/$tdir
5849         touch $DIR/$tdir/foo
5850         $MCREATE $DIR/$tdir/bar
5851         rm $DIR/$tdir/foo
5852         createmany -m $DIR/$tdir/longfile 201
5853         FNUM=202
5854         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5855                 $MCREATE $DIR/$tdir/longfile$FNUM
5856                 FNUM=$(($FNUM + 1))
5857                 echo -n "+"
5858         done
5859         echo
5860         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5861 }
5862 run_test 51a "special situations: split htree with empty entry =="
5863
5864 cleanup_print_lfs_df () {
5865         trap 0
5866         $LFS df
5867         $LFS df -i
5868 }
5869
5870 test_51b() {
5871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5872
5873         local dir=$DIR/$tdir
5874         local nrdirs=$((65536 + 100))
5875
5876         # cleanup the directory
5877         rm -fr $dir
5878
5879         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5880
5881         $LFS df
5882         $LFS df -i
5883         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5884         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5885         [[ $numfree -lt $nrdirs ]] &&
5886                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5887
5888         # need to check free space for the directories as well
5889         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5890         numfree=$(( blkfree / $(fs_inode_ksize) ))
5891         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5892
5893         trap cleanup_print_lfs_df EXIT
5894
5895         # create files
5896         createmany -d $dir/d $nrdirs || {
5897                 unlinkmany $dir/d $nrdirs
5898                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5899         }
5900
5901         # really created :
5902         nrdirs=$(ls -U $dir | wc -l)
5903
5904         # unlink all but 100 subdirectories, then check it still works
5905         local left=100
5906         local delete=$((nrdirs - left))
5907
5908         $LFS df
5909         $LFS df -i
5910
5911         # for ldiskfs the nlink count should be 1, but this is OSD specific
5912         # and so this is listed for informational purposes only
5913         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5914         unlinkmany -d $dir/d $delete ||
5915                 error "unlink of first $delete subdirs failed"
5916
5917         echo "nlink between: $(stat -c %h $dir)"
5918         local found=$(ls -U $dir | wc -l)
5919         [ $found -ne $left ] &&
5920                 error "can't find subdirs: found only $found, expected $left"
5921
5922         unlinkmany -d $dir/d $delete $left ||
5923                 error "unlink of second $left subdirs failed"
5924         # regardless of whether the backing filesystem tracks nlink accurately
5925         # or not, the nlink count shouldn't be more than "." and ".." here
5926         local after=$(stat -c %h $dir)
5927         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5928                 echo "nlink after: $after"
5929
5930         cleanup_print_lfs_df
5931 }
5932 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5933
5934 test_51d_sub() {
5935         local stripecount=$1
5936         local nfiles=$2
5937
5938         log "create files with stripecount=$stripecount"
5939         $LFS setstripe -C $stripecount $DIR/$tdir
5940         createmany -o $DIR/$tdir/t- $nfiles
5941         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5942         for ((n = 0; n < $OSTCOUNT; n++)); do
5943                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5944                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5945                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5946                             '($1 == '$n') { objs += 1 } \
5947                             END { printf("%0.0f", objs) }')
5948                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5949         done
5950         unlinkmany $DIR/$tdir/t- $nfiles
5951         rm  -f $TMP/$tfile
5952
5953         local nlast
5954         local min=4
5955         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5956
5957         # For some combinations of stripecount and OSTCOUNT current code
5958         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5959         # than others. Rather than skipping this test entirely, check that
5960         # and keep testing to ensure imbalance does not get worse. LU-15282
5961         (( (OSTCOUNT == 6 && stripecount == 4) ||
5962            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5963            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5964         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5965                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5966                         { $LFS df && $LFS df -i &&
5967                         error "stripecount=$stripecount: " \
5968                               "OST $n has fewer objects vs. OST $nlast " \
5969                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5970                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5971                         { $LFS df && $LFS df -i &&
5972                         error "stripecount=$stripecount: " \
5973                               "OST $n has more objects vs. OST $nlast " \
5974                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5975
5976                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5977                         { $LFS df && $LFS df -i &&
5978                         error "stripecount=$stripecount: " \
5979                               "OST $n has fewer #0 objects vs. OST $nlast " \
5980                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5981                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5982                         { $LFS df && $LFS df -i &&
5983                         error "stripecount=$stripecount: " \
5984                               "OST $n has more #0 objects vs. OST $nlast " \
5985                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5986         done
5987 }
5988
5989 test_51d() {
5990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5991         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5992
5993         local stripecount
5994         local per_ost=100
5995         local nfiles=$((per_ost * OSTCOUNT))
5996         local mdts=$(comma_list $(mdts_nodes))
5997         local param="osp.*.create_count"
5998         local qos_old=$(do_facet mds1 \
5999                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6000
6001         do_nodes $mdts \
6002                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6003         stack_trap "do_nodes $mdts \
6004                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6005
6006         test_mkdir $DIR/$tdir
6007         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6008         (( dirstripes > 0 )) || dirstripes=1
6009
6010         # Ensure enough OST objects precreated for tests to pass without
6011         # running out of objects.  This is an LOV r-r OST algorithm test,
6012         # not an OST object precreation test.
6013         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6014         (( old >= nfiles )) ||
6015         {
6016                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6017
6018                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6019                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6020
6021                 # trigger precreation from all MDTs for all OSTs
6022                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6023                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6024                 done
6025         }
6026
6027         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6028                 sleep 8  # allow object precreation to catch up
6029                 test_51d_sub $stripecount $nfiles
6030         done
6031 }
6032 run_test 51d "check LOV round-robin OST object distribution"
6033
6034 test_51e() {
6035         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6036                 skip_env "ldiskfs only test"
6037         fi
6038
6039         test_mkdir -c1 $DIR/$tdir
6040         test_mkdir -c1 $DIR/$tdir/d0
6041
6042         touch $DIR/$tdir/d0/foo
6043         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6044                 error "file exceed 65000 nlink limit!"
6045         unlinkmany $DIR/$tdir/d0/f- 65001
6046         return 0
6047 }
6048 run_test 51e "check file nlink limit"
6049
6050 test_51f() {
6051         test_mkdir $DIR/$tdir
6052
6053         local max=100000
6054         local ulimit_old=$(ulimit -n)
6055         local spare=20 # number of spare fd's for scripts/libraries, etc.
6056         local mdt=$($LFS getstripe -m $DIR/$tdir)
6057         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6058
6059         echo "MDT$mdt numfree=$numfree, max=$max"
6060         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6061         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6062                 while ! ulimit -n $((numfree + spare)); do
6063                         numfree=$((numfree * 3 / 4))
6064                 done
6065                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6066         else
6067                 echo "left ulimit at $ulimit_old"
6068         fi
6069
6070         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6071                 unlinkmany $DIR/$tdir/f $numfree
6072                 error "create+open $numfree files in $DIR/$tdir failed"
6073         }
6074         ulimit -n $ulimit_old
6075
6076         # if createmany exits at 120s there will be fewer than $numfree files
6077         unlinkmany $DIR/$tdir/f $numfree || true
6078 }
6079 run_test 51f "check many open files limit"
6080
6081 test_52a() {
6082         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6083         test_mkdir $DIR/$tdir
6084         touch $DIR/$tdir/foo
6085         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6086         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6087         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6088         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6089         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6090                                         error "link worked"
6091         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6092         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6093         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6094                                                      error "lsattr"
6095         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6096         cp -r $DIR/$tdir $TMP/
6097         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6098 }
6099 run_test 52a "append-only flag test (should return errors)"
6100
6101 test_52b() {
6102         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6103         test_mkdir $DIR/$tdir
6104         touch $DIR/$tdir/foo
6105         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6106         cat test > $DIR/$tdir/foo && error "cat test worked"
6107         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6108         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6109         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6110                                         error "link worked"
6111         echo foo >> $DIR/$tdir/foo && error "echo worked"
6112         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6113         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6114         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6115         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6116                                                         error "lsattr"
6117         chattr -i $DIR/$tdir/foo || error "chattr failed"
6118
6119         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6120 }
6121 run_test 52b "immutable flag test (should return errors) ======="
6122
6123 test_53() {
6124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6125         remote_mds_nodsh && skip "remote MDS with nodsh"
6126         remote_ost_nodsh && skip "remote OST with nodsh"
6127
6128         local param
6129         local param_seq
6130         local ostname
6131         local mds_last
6132         local mds_last_seq
6133         local ost_last
6134         local ost_last_seq
6135         local ost_last_id
6136         local ostnum
6137         local node
6138         local found=false
6139         local support_last_seq=true
6140
6141         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6142                 support_last_seq=false
6143
6144         # only test MDT0000
6145         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6146         local value
6147         for value in $(do_facet $SINGLEMDS \
6148                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6149                 param=$(echo ${value[0]} | cut -d "=" -f1)
6150                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6151
6152                 if $support_last_seq; then
6153                         param_seq=$(echo $param |
6154                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6155                         mds_last_seq=$(do_facet $SINGLEMDS \
6156                                        $LCTL get_param -n $param_seq)
6157                 fi
6158                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6159
6160                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6161                 node=$(facet_active_host ost$((ostnum+1)))
6162                 param="obdfilter.$ostname.last_id"
6163                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6164                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6165                         ost_last_id=$ost_last
6166
6167                         if $support_last_seq; then
6168                                 ost_last_id=$(echo $ost_last |
6169                                               awk -F':' '{print $2}' |
6170                                               sed -e "s/^0x//g")
6171                                 ost_last_seq=$(echo $ost_last |
6172                                                awk -F':' '{print $1}')
6173                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6174                         fi
6175
6176                         if [[ $ost_last_id != $mds_last ]]; then
6177                                 error "$ost_last_id != $mds_last"
6178                         else
6179                                 found=true
6180                                 break
6181                         fi
6182                 done
6183         done
6184         $found || error "can not match last_seq/last_id for $mdtosc"
6185         return 0
6186 }
6187 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6188
6189 test_54a() {
6190         perl -MSocket -e ';' || skip "no Socket perl module installed"
6191
6192         $SOCKETSERVER $DIR/socket ||
6193                 error "$SOCKETSERVER $DIR/socket failed: $?"
6194         $SOCKETCLIENT $DIR/socket ||
6195                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6196         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6197 }
6198 run_test 54a "unix domain socket test =========================="
6199
6200 test_54b() {
6201         f="$DIR/f54b"
6202         mknod $f c 1 3
6203         chmod 0666 $f
6204         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6205 }
6206 run_test 54b "char device works in lustre ======================"
6207
6208 find_loop_dev() {
6209         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6210         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6211         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6212
6213         for i in $(seq 3 7); do
6214                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6215                 LOOPDEV=$LOOPBASE$i
6216                 LOOPNUM=$i
6217                 break
6218         done
6219 }
6220
6221 cleanup_54c() {
6222         local rc=0
6223         loopdev="$DIR/loop54c"
6224
6225         trap 0
6226         $UMOUNT $DIR/$tdir || rc=$?
6227         losetup -d $loopdev || true
6228         losetup -d $LOOPDEV || true
6229         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6230         return $rc
6231 }
6232
6233 test_54c() {
6234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6235
6236         loopdev="$DIR/loop54c"
6237
6238         find_loop_dev
6239         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6240         trap cleanup_54c EXIT
6241         mknod $loopdev b 7 $LOOPNUM
6242         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6243         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6244         losetup $loopdev $DIR/$tfile ||
6245                 error "can't set up $loopdev for $DIR/$tfile"
6246         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6247         test_mkdir $DIR/$tdir
6248         mount -t ext2 $loopdev $DIR/$tdir ||
6249                 error "error mounting $loopdev on $DIR/$tdir"
6250         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6251                 error "dd write"
6252         df $DIR/$tdir
6253         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6254                 error "dd read"
6255         cleanup_54c
6256 }
6257 run_test 54c "block device works in lustre ====================="
6258
6259 test_54d() {
6260         local pipe="$DIR/$tfile.pipe"
6261         local string="aaaaaa"
6262
6263         mknod $pipe p
6264         echo -n "$string" > $pipe &
6265         local result=$(cat $pipe)
6266         [[ "$result" == "$string" ]] || error "$result != $string"
6267 }
6268 run_test 54d "fifo device works in lustre ======================"
6269
6270 test_54e() {
6271         f="$DIR/f54e"
6272         string="aaaaaa"
6273         cp -aL /dev/console $f
6274         echo $string > $f || error "echo $string to $f failed"
6275 }
6276 run_test 54e "console/tty device works in lustre ======================"
6277
6278 test_56a() {
6279         local numfiles=3
6280         local numdirs=2
6281         local dir=$DIR/$tdir
6282
6283         rm -rf $dir
6284         test_mkdir -p $dir/dir
6285         for i in $(seq $numfiles); do
6286                 touch $dir/file$i
6287                 touch $dir/dir/file$i
6288         done
6289
6290         local numcomp=$($LFS getstripe --component-count $dir)
6291
6292         [[ $numcomp == 0 ]] && numcomp=1
6293
6294         # test lfs getstripe with --recursive
6295         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6296
6297         [[ $filenum -eq $((numfiles * 2)) ]] ||
6298                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6299         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6300         [[ $filenum -eq $numfiles ]] ||
6301                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6302         echo "$LFS getstripe showed obdidx or l_ost_idx"
6303
6304         # test lfs getstripe with file instead of dir
6305         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6306         [[ $filenum -eq 1 ]] ||
6307                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6308         echo "$LFS getstripe file1 passed"
6309
6310         #test lfs getstripe with --verbose
6311         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6312         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6313                 error "$LFS getstripe --verbose $dir: "\
6314                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6315         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6316                 error "$LFS getstripe $dir: showed lmm_magic"
6317
6318         #test lfs getstripe with -v prints lmm_fid
6319         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6320         local countfids=$((numdirs + numfiles * numcomp))
6321         [[ $filenum -eq $countfids ]] ||
6322                 error "$LFS getstripe -v $dir: "\
6323                       "got $filenum want $countfids lmm_fid"
6324         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6325                 error "$LFS getstripe $dir: showed lmm_fid by default"
6326         echo "$LFS getstripe --verbose passed"
6327
6328         #check for FID information
6329         local fid1=$($LFS getstripe --fid $dir/file1)
6330         local fid2=$($LFS getstripe --verbose $dir/file1 |
6331                      awk '/lmm_fid: / { print $2; exit; }')
6332         local fid3=$($LFS path2fid $dir/file1)
6333
6334         [ "$fid1" != "$fid2" ] &&
6335                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6336         [ "$fid1" != "$fid3" ] &&
6337                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6338         echo "$LFS getstripe --fid passed"
6339
6340         #test lfs getstripe with --obd
6341         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6342                 error "$LFS getstripe --obd wrong_uuid: should return error"
6343
6344         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6345
6346         local ostidx=1
6347         local obduuid=$(ostuuid_from_index $ostidx)
6348         local found=$($LFS getstripe -r --obd $obduuid $dir |
6349                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6350
6351         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6352         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6353                 ((filenum--))
6354         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6355                 ((filenum--))
6356
6357         [[ $found -eq $filenum ]] ||
6358                 error "$LFS getstripe --obd: found $found expect $filenum"
6359         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6360                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6361                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6362                 error "$LFS getstripe --obd: should not show file on other obd"
6363         echo "$LFS getstripe --obd passed"
6364 }
6365 run_test 56a "check $LFS getstripe"
6366
6367 test_56b() {
6368         local dir=$DIR/$tdir
6369         local numdirs=3
6370
6371         test_mkdir $dir
6372         for i in $(seq $numdirs); do
6373                 test_mkdir $dir/dir$i
6374         done
6375
6376         # test lfs getdirstripe default mode is non-recursion, which is
6377         # different from lfs getstripe
6378         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6379
6380         [[ $dircnt -eq 1 ]] ||
6381                 error "$LFS getdirstripe: found $dircnt, not 1"
6382         dircnt=$($LFS getdirstripe --recursive $dir |
6383                 grep -c lmv_stripe_count)
6384         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6385                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6386 }
6387 run_test 56b "check $LFS getdirstripe"
6388
6389 test_56c() {
6390         remote_ost_nodsh && skip "remote OST with nodsh"
6391
6392         local ost_idx=0
6393         local ost_name=$(ostname_from_index $ost_idx)
6394         local old_status=$(ost_dev_status $ost_idx)
6395         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6396
6397         [[ -z "$old_status" ]] ||
6398                 skip_env "OST $ost_name is in $old_status status"
6399
6400         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6401         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6402                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6403         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6404                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6405                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6406         fi
6407
6408         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6409                 error "$LFS df -v showing inactive devices"
6410         sleep_maxage
6411
6412         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6413
6414         [[ "$new_status" =~ "D" ]] ||
6415                 error "$ost_name status is '$new_status', missing 'D'"
6416         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6417                 [[ "$new_status" =~ "N" ]] ||
6418                         error "$ost_name status is '$new_status', missing 'N'"
6419         fi
6420         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6421                 [[ "$new_status" =~ "f" ]] ||
6422                         error "$ost_name status is '$new_status', missing 'f'"
6423         fi
6424
6425         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6426         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6427                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6428         [[ -z "$p" ]] && restore_lustre_params < $p || true
6429         sleep_maxage
6430
6431         new_status=$(ost_dev_status $ost_idx)
6432         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6433                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6434         # can't check 'f' as devices may actually be on flash
6435 }
6436 run_test 56c "check 'lfs df' showing device status"
6437
6438 test_56d() {
6439         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6440         local osts=$($LFS df -v $MOUNT | grep -c OST)
6441
6442         $LFS df $MOUNT
6443
6444         (( mdts == MDSCOUNT )) ||
6445                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6446         (( osts == OSTCOUNT )) ||
6447                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6448 }
6449 run_test 56d "'lfs df -v' prints only configured devices"
6450
6451 test_56e() {
6452         err_enoent=2 # No such file or directory
6453         err_eopnotsupp=95 # Operation not supported
6454
6455         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6456         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6457
6458         # Check for handling of path not exists
6459         output=$($LFS df $enoent_mnt 2>&1)
6460         ret=$?
6461
6462         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6463         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6464                 error "expect failure $err_enoent, not $ret"
6465
6466         # Check for handling of non-Lustre FS
6467         output=$($LFS df $notsup_mnt)
6468         ret=$?
6469
6470         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6471         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6472                 error "expect success $err_eopnotsupp, not $ret"
6473
6474         # Check for multiple LustreFS argument
6475         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6476         ret=$?
6477
6478         [[ $output -eq 3 && $ret -eq 0 ]] ||
6479                 error "expect success 3, not $output, rc = $ret"
6480
6481         # Check for correct non-Lustre FS handling among multiple
6482         # LustreFS argument
6483         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6484                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6485         ret=$?
6486
6487         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6488                 error "expect success 2, not $output, rc = $ret"
6489 }
6490 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6491
6492 NUMFILES=3
6493 NUMDIRS=3
6494 setup_56() {
6495         local local_tdir="$1"
6496         local local_numfiles="$2"
6497         local local_numdirs="$3"
6498         local dir_params="$4"
6499         local dir_stripe_params="$5"
6500
6501         if [ ! -d "$local_tdir" ] ; then
6502                 test_mkdir -p $dir_stripe_params $local_tdir
6503                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6504                 for i in $(seq $local_numfiles) ; do
6505                         touch $local_tdir/file$i
6506                 done
6507                 for i in $(seq $local_numdirs) ; do
6508                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6509                         for j in $(seq $local_numfiles) ; do
6510                                 touch $local_tdir/dir$i/file$j
6511                         done
6512                 done
6513         fi
6514 }
6515
6516 setup_56_special() {
6517         local local_tdir=$1
6518         local local_numfiles=$2
6519         local local_numdirs=$3
6520
6521         setup_56 $local_tdir $local_numfiles $local_numdirs
6522
6523         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6524                 for i in $(seq $local_numfiles) ; do
6525                         mknod $local_tdir/loop${i}b b 7 $i
6526                         mknod $local_tdir/null${i}c c 1 3
6527                         ln -s $local_tdir/file1 $local_tdir/link${i}
6528                 done
6529                 for i in $(seq $local_numdirs) ; do
6530                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6531                         mknod $local_tdir/dir$i/null${i}c c 1 3
6532                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6533                 done
6534         fi
6535 }
6536
6537 test_56g() {
6538         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6539         local expected=$(($NUMDIRS + 2))
6540
6541         setup_56 $dir $NUMFILES $NUMDIRS
6542
6543         # test lfs find with -name
6544         for i in $(seq $NUMFILES) ; do
6545                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6546
6547                 [ $nums -eq $expected ] ||
6548                         error "lfs find -name '*$i' $dir wrong: "\
6549                               "found $nums, expected $expected"
6550         done
6551 }
6552 run_test 56g "check lfs find -name"
6553
6554 test_56h() {
6555         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6556         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6557
6558         setup_56 $dir $NUMFILES $NUMDIRS
6559
6560         # test lfs find with ! -name
6561         for i in $(seq $NUMFILES) ; do
6562                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6563
6564                 [ $nums -eq $expected ] ||
6565                         error "lfs find ! -name '*$i' $dir wrong: "\
6566                               "found $nums, expected $expected"
6567         done
6568 }
6569 run_test 56h "check lfs find ! -name"
6570
6571 test_56i() {
6572         local dir=$DIR/$tdir
6573
6574         test_mkdir $dir
6575
6576         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6577         local out=$($cmd)
6578
6579         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6580 }
6581 run_test 56i "check 'lfs find -ost UUID' skips directories"
6582
6583 test_56j() {
6584         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6585
6586         setup_56_special $dir $NUMFILES $NUMDIRS
6587
6588         local expected=$((NUMDIRS + 1))
6589         local cmd="$LFS find -type d $dir"
6590         local nums=$($cmd | wc -l)
6591
6592         [ $nums -eq $expected ] ||
6593                 error "'$cmd' wrong: found $nums, expected $expected"
6594 }
6595 run_test 56j "check lfs find -type d"
6596
6597 test_56k() {
6598         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6599
6600         setup_56_special $dir $NUMFILES $NUMDIRS
6601
6602         local expected=$(((NUMDIRS + 1) * NUMFILES))
6603         local cmd="$LFS find -type f $dir"
6604         local nums=$($cmd | wc -l)
6605
6606         [ $nums -eq $expected ] ||
6607                 error "'$cmd' wrong: found $nums, expected $expected"
6608 }
6609 run_test 56k "check lfs find -type f"
6610
6611 test_56l() {
6612         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6613
6614         setup_56_special $dir $NUMFILES $NUMDIRS
6615
6616         local expected=$((NUMDIRS + NUMFILES))
6617         local cmd="$LFS find -type b $dir"
6618         local nums=$($cmd | wc -l)
6619
6620         [ $nums -eq $expected ] ||
6621                 error "'$cmd' wrong: found $nums, expected $expected"
6622 }
6623 run_test 56l "check lfs find -type b"
6624
6625 test_56m() {
6626         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6627
6628         setup_56_special $dir $NUMFILES $NUMDIRS
6629
6630         local expected=$((NUMDIRS + NUMFILES))
6631         local cmd="$LFS find -type c $dir"
6632         local nums=$($cmd | wc -l)
6633         [ $nums -eq $expected ] ||
6634                 error "'$cmd' wrong: found $nums, expected $expected"
6635 }
6636 run_test 56m "check lfs find -type c"
6637
6638 test_56n() {
6639         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6640         setup_56_special $dir $NUMFILES $NUMDIRS
6641
6642         local expected=$((NUMDIRS + NUMFILES))
6643         local cmd="$LFS find -type l $dir"
6644         local nums=$($cmd | wc -l)
6645
6646         [ $nums -eq $expected ] ||
6647                 error "'$cmd' wrong: found $nums, expected $expected"
6648 }
6649 run_test 56n "check lfs find -type l"
6650
6651 test_56o() {
6652         local dir=$DIR/$tdir
6653
6654         setup_56 $dir $NUMFILES $NUMDIRS
6655         utime $dir/file1 > /dev/null || error "utime (1)"
6656         utime $dir/file2 > /dev/null || error "utime (2)"
6657         utime $dir/dir1 > /dev/null || error "utime (3)"
6658         utime $dir/dir2 > /dev/null || error "utime (4)"
6659         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6660         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6661
6662         local expected=4
6663         local nums=$($LFS find -mtime +0 $dir | wc -l)
6664
6665         [ $nums -eq $expected ] ||
6666                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6667
6668         expected=12
6669         cmd="$LFS find -mtime 0 $dir"
6670         nums=$($cmd | wc -l)
6671         [ $nums -eq $expected ] ||
6672                 error "'$cmd' wrong: found $nums, expected $expected"
6673 }
6674 run_test 56o "check lfs find -mtime for old files"
6675
6676 test_56ob() {
6677         local dir=$DIR/$tdir
6678         local expected=1
6679         local count=0
6680
6681         # just to make sure there is something that won't be found
6682         test_mkdir $dir
6683         touch $dir/$tfile.now
6684
6685         for age in year week day hour min; do
6686                 count=$((count + 1))
6687
6688                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6689                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6690                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6691
6692                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6693                 local nums=$($cmd | wc -l)
6694                 [ $nums -eq $expected ] ||
6695                         error "'$cmd' wrong: found $nums, expected $expected"
6696
6697                 cmd="$LFS find $dir -atime $count${age:0:1}"
6698                 nums=$($cmd | wc -l)
6699                 [ $nums -eq $expected ] ||
6700                         error "'$cmd' wrong: found $nums, expected $expected"
6701         done
6702
6703         sleep 2
6704         cmd="$LFS find $dir -ctime +1s -type f"
6705         nums=$($cmd | wc -l)
6706         (( $nums == $count * 2 + 1)) ||
6707                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6708 }
6709 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6710
6711 test_newerXY_base() {
6712         local x=$1
6713         local y=$2
6714         local dir=$DIR/$tdir
6715         local ref
6716         local negref
6717
6718         if [ $y == "t" ]; then
6719                 if [ $x == "b" ]; then
6720                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6721                 else
6722                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6723                 fi
6724         else
6725                 ref=$DIR/$tfile.newer.$x$y
6726                 touch $ref || error "touch $ref failed"
6727         fi
6728
6729         echo "before = $ref"
6730         sleep 2
6731         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6732         sleep 2
6733         if [ $y == "t" ]; then
6734                 if [ $x == "b" ]; then
6735                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6736                 else
6737                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6738                 fi
6739         else
6740                 negref=$DIR/$tfile.negnewer.$x$y
6741                 touch $negref || error "touch $negref failed"
6742         fi
6743
6744         echo "after = $negref"
6745         local cmd="$LFS find $dir -newer$x$y $ref"
6746         local nums=$(eval $cmd | wc -l)
6747         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6748
6749         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6750                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6751
6752         cmd="$LFS find $dir ! -newer$x$y $negref"
6753         nums=$(eval $cmd | wc -l)
6754         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6755                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6756
6757         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6758         nums=$(eval $cmd | wc -l)
6759         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6760                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6761
6762         rm -rf $DIR/*
6763 }
6764
6765 test_56oc() {
6766         test_newerXY_base "a" "a"
6767         test_newerXY_base "a" "m"
6768         test_newerXY_base "a" "c"
6769         test_newerXY_base "m" "a"
6770         test_newerXY_base "m" "m"
6771         test_newerXY_base "m" "c"
6772         test_newerXY_base "c" "a"
6773         test_newerXY_base "c" "m"
6774         test_newerXY_base "c" "c"
6775
6776         test_newerXY_base "a" "t"
6777         test_newerXY_base "m" "t"
6778         test_newerXY_base "c" "t"
6779
6780         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6781            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6782                 ! btime_supported && echo "btime unsupported" && return 0
6783
6784         test_newerXY_base "b" "b"
6785         test_newerXY_base "b" "t"
6786 }
6787 run_test 56oc "check lfs find -newerXY work"
6788
6789 btime_supported() {
6790         local dir=$DIR/$tdir
6791         local rc
6792
6793         mkdir -p $dir
6794         touch $dir/$tfile
6795         $LFS find $dir -btime -1d -type f
6796         rc=$?
6797         rm -rf $dir
6798         return $rc
6799 }
6800
6801 test_56od() {
6802         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6803                 ! btime_supported && skip "btime unsupported on MDS"
6804
6805         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6806                 ! btime_supported && skip "btime unsupported on clients"
6807
6808         local dir=$DIR/$tdir
6809         local ref=$DIR/$tfile.ref
6810         local negref=$DIR/$tfile.negref
6811
6812         mkdir $dir || error "mkdir $dir failed"
6813         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6814         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6815         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6816         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6817         touch $ref || error "touch $ref failed"
6818         # sleep 3 seconds at least
6819         sleep 3
6820
6821         local before=$(do_facet mds1 date +%s)
6822         local skew=$(($(date +%s) - before + 1))
6823
6824         if (( skew < 0 && skew > -5 )); then
6825                 sleep $((0 - skew + 1))
6826                 skew=0
6827         fi
6828
6829         # Set the dir stripe params to limit files all on MDT0,
6830         # otherwise we need to calc the max clock skew between
6831         # the client and MDTs.
6832         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6833         sleep 2
6834         touch $negref || error "touch $negref failed"
6835
6836         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6837         local nums=$($cmd | wc -l)
6838         local expected=$(((NUMFILES + 1) * NUMDIRS))
6839
6840         [ $nums -eq $expected ] ||
6841                 error "'$cmd' wrong: found $nums, expected $expected"
6842
6843         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6844         nums=$($cmd | wc -l)
6845         expected=$((NUMFILES + 1))
6846         [ $nums -eq $expected ] ||
6847                 error "'$cmd' wrong: found $nums, expected $expected"
6848
6849         [ $skew -lt 0 ] && return
6850
6851         local after=$(do_facet mds1 date +%s)
6852         local age=$((after - before + 1 + skew))
6853
6854         cmd="$LFS find $dir -btime -${age}s -type f"
6855         nums=$($cmd | wc -l)
6856         expected=$(((NUMFILES + 1) * NUMDIRS))
6857
6858         echo "Clock skew between client and server: $skew, age:$age"
6859         [ $nums -eq $expected ] ||
6860                 error "'$cmd' wrong: found $nums, expected $expected"
6861
6862         expected=$(($NUMDIRS + 1))
6863         cmd="$LFS find $dir -btime -${age}s -type d"
6864         nums=$($cmd | wc -l)
6865         [ $nums -eq $expected ] ||
6866                 error "'$cmd' wrong: found $nums, expected $expected"
6867         rm -f $ref $negref || error "Failed to remove $ref $negref"
6868 }
6869 run_test 56od "check lfs find -btime with units"
6870
6871 test_56p() {
6872         [ $RUNAS_ID -eq $UID ] &&
6873                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6874
6875         local dir=$DIR/$tdir
6876
6877         setup_56 $dir $NUMFILES $NUMDIRS
6878         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6879
6880         local expected=$NUMFILES
6881         local cmd="$LFS find -uid $RUNAS_ID $dir"
6882         local nums=$($cmd | wc -l)
6883
6884         [ $nums -eq $expected ] ||
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886
6887         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6888         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892 }
6893 run_test 56p "check lfs find -uid and ! -uid"
6894
6895 test_56q() {
6896         [ $RUNAS_ID -eq $UID ] &&
6897                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6898
6899         local dir=$DIR/$tdir
6900
6901         setup_56 $dir $NUMFILES $NUMDIRS
6902         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6903
6904         local expected=$NUMFILES
6905         local cmd="$LFS find -gid $RUNAS_GID $dir"
6906         local nums=$($cmd | wc -l)
6907
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910
6911         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6912         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916 }
6917 run_test 56q "check lfs find -gid and ! -gid"
6918
6919 test_56r() {
6920         local dir=$DIR/$tdir
6921
6922         setup_56 $dir $NUMFILES $NUMDIRS
6923
6924         local expected=12
6925         local cmd="$LFS find -size 0 -type f -lazy $dir"
6926         local nums=$($cmd | wc -l)
6927
6928         [ $nums -eq $expected ] ||
6929                 error "'$cmd' wrong: found $nums, expected $expected"
6930         cmd="$LFS find -size 0 -type f $dir"
6931         nums=$($cmd | wc -l)
6932         [ $nums -eq $expected ] ||
6933                 error "'$cmd' wrong: found $nums, expected $expected"
6934
6935         expected=0
6936         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6937         nums=$($cmd | wc -l)
6938         [ $nums -eq $expected ] ||
6939                 error "'$cmd' wrong: found $nums, expected $expected"
6940         cmd="$LFS find ! -size 0 -type f $dir"
6941         nums=$($cmd | wc -l)
6942         [ $nums -eq $expected ] ||
6943                 error "'$cmd' wrong: found $nums, expected $expected"
6944
6945         echo "test" > $dir/$tfile
6946         echo "test2" > $dir/$tfile.2 && sync
6947         expected=1
6948         cmd="$LFS find -size 5 -type f -lazy $dir"
6949         nums=$($cmd | wc -l)
6950         [ $nums -eq $expected ] ||
6951                 error "'$cmd' wrong: found $nums, expected $expected"
6952         cmd="$LFS find -size 5 -type f $dir"
6953         nums=$($cmd | wc -l)
6954         [ $nums -eq $expected ] ||
6955                 error "'$cmd' wrong: found $nums, expected $expected"
6956
6957         expected=1
6958         cmd="$LFS find -size +5 -type f -lazy $dir"
6959         nums=$($cmd | wc -l)
6960         [ $nums -eq $expected ] ||
6961                 error "'$cmd' wrong: found $nums, expected $expected"
6962         cmd="$LFS find -size +5 -type f $dir"
6963         nums=$($cmd | wc -l)
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         expected=2
6968         cmd="$LFS find -size +0 -type f -lazy $dir"
6969         nums=$($cmd | wc -l)
6970         [ $nums -eq $expected ] ||
6971                 error "'$cmd' wrong: found $nums, expected $expected"
6972         cmd="$LFS find -size +0 -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         expected=2
6978         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6979         nums=$($cmd | wc -l)
6980         [ $nums -eq $expected ] ||
6981                 error "'$cmd' wrong: found $nums, expected $expected"
6982         cmd="$LFS find ! -size -5 -type f $dir"
6983         nums=$($cmd | wc -l)
6984         [ $nums -eq $expected ] ||
6985                 error "'$cmd' wrong: found $nums, expected $expected"
6986
6987         expected=12
6988         cmd="$LFS find -size -5 -type f -lazy $dir"
6989         nums=$($cmd | wc -l)
6990         [ $nums -eq $expected ] ||
6991                 error "'$cmd' wrong: found $nums, expected $expected"
6992         cmd="$LFS find -size -5 -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996 }
6997 run_test 56r "check lfs find -size works"
6998
6999 test_56ra_sub() {
7000         local expected=$1
7001         local glimpses=$2
7002         local cmd="$3"
7003
7004         cancel_lru_locks $OSC
7005
7006         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7007         local nums=$($cmd | wc -l)
7008
7009         [ $nums -eq $expected ] ||
7010                 error "'$cmd' wrong: found $nums, expected $expected"
7011
7012         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7013
7014         if (( rpcs_before + glimpses != rpcs_after )); then
7015                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7016                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7017
7018                 if [[ $glimpses == 0 ]]; then
7019                         error "'$cmd' should not send glimpse RPCs to OST"
7020                 else
7021                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7022                 fi
7023         fi
7024 }
7025
7026 test_56ra() {
7027         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7028                 skip "MDS < 2.12.58 doesn't return LSOM data"
7029         local dir=$DIR/$tdir
7030         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7031
7032         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7033
7034         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7035         $LCTL set_param -n llite.*.statahead_agl=0
7036         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7037
7038         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7039         # open and close all files to ensure LSOM is updated
7040         cancel_lru_locks $OSC
7041         find $dir -type f | xargs cat > /dev/null
7042
7043         #   expect_found  glimpse_rpcs  command_to_run
7044         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7045         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7046         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7047         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7048
7049         echo "test" > $dir/$tfile
7050         echo "test2" > $dir/$tfile.2 && sync
7051         cancel_lru_locks $OSC
7052         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7053
7054         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7055         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7056         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7057         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7058
7059         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7060         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7061         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7062         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7063         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7064         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7065 }
7066 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7067
7068 test_56rb() {
7069         local dir=$DIR/$tdir
7070         local tmp=$TMP/$tfile.log
7071         local mdt_idx;
7072
7073         test_mkdir -p $dir || error "failed to mkdir $dir"
7074         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7075                 error "failed to setstripe $dir/$tfile"
7076         mdt_idx=$($LFS getdirstripe -i $dir)
7077         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7078
7079         stack_trap "rm -f $tmp" EXIT
7080         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7081         ! grep -q obd_uuid $tmp ||
7082                 error "failed to find --size +100K --ost 0 $dir"
7083         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7084         ! grep -q obd_uuid $tmp ||
7085                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7086 }
7087 run_test 56rb "check lfs find --size --ost/--mdt works"
7088
7089 test_56rc() {
7090         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7091         local dir=$DIR/$tdir
7092         local found
7093
7094         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7095         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7096         (( $MDSCOUNT > 2 )) &&
7097                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7098         mkdir $dir/$tdir-{1..10}
7099         touch $dir/$tfile-{1..10}
7100
7101         found=$($LFS find $dir --mdt-count 2 | wc -l)
7102         expect=11
7103         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7104
7105         found=$($LFS find $dir -T +1 | wc -l)
7106         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7107         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7108
7109         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7110         expect=11
7111         (( $found == $expect )) || error "found $found all_char, expect $expect"
7112
7113         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7114         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7115         (( $found == $expect )) || error "found $found all_char, expect $expect"
7116 }
7117 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7118
7119 test_56s() { # LU-611 #LU-9369
7120         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7121
7122         local dir=$DIR/$tdir
7123         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7124
7125         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7126         for i in $(seq $NUMDIRS); do
7127                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7128         done
7129
7130         local expected=$NUMDIRS
7131         local cmd="$LFS find -c $OSTCOUNT $dir"
7132         local nums=$($cmd | wc -l)
7133
7134         [ $nums -eq $expected ] || {
7135                 $LFS getstripe -R $dir
7136                 error "'$cmd' wrong: found $nums, expected $expected"
7137         }
7138
7139         expected=$((NUMDIRS + onestripe))
7140         cmd="$LFS find -stripe-count +0 -type f $dir"
7141         nums=$($cmd | wc -l)
7142         [ $nums -eq $expected ] || {
7143                 $LFS getstripe -R $dir
7144                 error "'$cmd' wrong: found $nums, expected $expected"
7145         }
7146
7147         expected=$onestripe
7148         cmd="$LFS find -stripe-count 1 -type f $dir"
7149         nums=$($cmd | wc -l)
7150         [ $nums -eq $expected ] || {
7151                 $LFS getstripe -R $dir
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153         }
7154
7155         cmd="$LFS find -stripe-count -2 -type f $dir"
7156         nums=$($cmd | wc -l)
7157         [ $nums -eq $expected ] || {
7158                 $LFS getstripe -R $dir
7159                 error "'$cmd' wrong: found $nums, expected $expected"
7160         }
7161
7162         expected=0
7163         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7164         nums=$($cmd | wc -l)
7165         [ $nums -eq $expected ] || {
7166                 $LFS getstripe -R $dir
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168         }
7169 }
7170 run_test 56s "check lfs find -stripe-count works"
7171
7172 test_56t() { # LU-611 #LU-9369
7173         local dir=$DIR/$tdir
7174
7175         setup_56 $dir 0 $NUMDIRS
7176         for i in $(seq $NUMDIRS); do
7177                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7178         done
7179
7180         local expected=$NUMDIRS
7181         local cmd="$LFS find -S 8M $dir"
7182         local nums=$($cmd | wc -l)
7183
7184         [ $nums -eq $expected ] || {
7185                 $LFS getstripe -R $dir
7186                 error "'$cmd' wrong: found $nums, expected $expected"
7187         }
7188         rm -rf $dir
7189
7190         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7191
7192         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7193
7194         expected=$(((NUMDIRS + 1) * NUMFILES))
7195         cmd="$LFS find -stripe-size 512k -type f $dir"
7196         nums=$($cmd | wc -l)
7197         [ $nums -eq $expected ] ||
7198                 error "'$cmd' wrong: found $nums, expected $expected"
7199
7200         cmd="$LFS find -stripe-size +320k -type f $dir"
7201         nums=$($cmd | wc -l)
7202         [ $nums -eq $expected ] ||
7203                 error "'$cmd' wrong: found $nums, expected $expected"
7204
7205         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7206         cmd="$LFS find -stripe-size +200k -type f $dir"
7207         nums=$($cmd | wc -l)
7208         [ $nums -eq $expected ] ||
7209                 error "'$cmd' wrong: found $nums, expected $expected"
7210
7211         cmd="$LFS find -stripe-size -640k -type f $dir"
7212         nums=$($cmd | wc -l)
7213         [ $nums -eq $expected ] ||
7214                 error "'$cmd' wrong: found $nums, expected $expected"
7215
7216         expected=4
7217         cmd="$LFS find -stripe-size 256k -type f $dir"
7218         nums=$($cmd | wc -l)
7219         [ $nums -eq $expected ] ||
7220                 error "'$cmd' wrong: found $nums, expected $expected"
7221
7222         cmd="$LFS find -stripe-size -320k -type f $dir"
7223         nums=$($cmd | wc -l)
7224         [ $nums -eq $expected ] ||
7225                 error "'$cmd' wrong: found $nums, expected $expected"
7226
7227         expected=0
7228         cmd="$LFS find -stripe-size 1024k -type f $dir"
7229         nums=$($cmd | wc -l)
7230         [ $nums -eq $expected ] ||
7231                 error "'$cmd' wrong: found $nums, expected $expected"
7232 }
7233 run_test 56t "check lfs find -stripe-size works"
7234
7235 test_56u() { # LU-611
7236         local dir=$DIR/$tdir
7237
7238         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7239
7240         if [[ $OSTCOUNT -gt 1 ]]; then
7241                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7242                 onestripe=4
7243         else
7244                 onestripe=0
7245         fi
7246
7247         local expected=$(((NUMDIRS + 1) * NUMFILES))
7248         local cmd="$LFS find -stripe-index 0 -type f $dir"
7249         local nums=$($cmd | wc -l)
7250
7251         [ $nums -eq $expected ] ||
7252                 error "'$cmd' wrong: found $nums, expected $expected"
7253
7254         expected=$onestripe
7255         cmd="$LFS find -stripe-index 1 -type f $dir"
7256         nums=$($cmd | wc -l)
7257         [ $nums -eq $expected ] ||
7258                 error "'$cmd' wrong: found $nums, expected $expected"
7259
7260         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7261         nums=$($cmd | wc -l)
7262         [ $nums -eq $expected ] ||
7263                 error "'$cmd' wrong: found $nums, expected $expected"
7264
7265         expected=0
7266         # This should produce an error and not return any files
7267         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7268         nums=$($cmd 2>/dev/null | wc -l)
7269         [ $nums -eq $expected ] ||
7270                 error "'$cmd' wrong: found $nums, expected $expected"
7271
7272         if [[ $OSTCOUNT -gt 1 ]]; then
7273                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7274                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7275                 nums=$($cmd | wc -l)
7276                 [ $nums -eq $expected ] ||
7277                         error "'$cmd' wrong: found $nums, expected $expected"
7278         fi
7279 }
7280 run_test 56u "check lfs find -stripe-index works"
7281
7282 test_56v() {
7283         local mdt_idx=0
7284         local dir=$DIR/$tdir
7285
7286         setup_56 $dir $NUMFILES $NUMDIRS
7287
7288         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7289         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7290
7291         for file in $($LFS find -m $UUID $dir); do
7292                 file_midx=$($LFS getstripe -m $file)
7293                 [ $file_midx -eq $mdt_idx ] ||
7294                         error "lfs find -m $UUID != getstripe -m $file_midx"
7295         done
7296 }
7297 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7298
7299 test_56wa() {
7300         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7302
7303         local dir=$DIR/$tdir
7304
7305         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7306
7307         local stripe_size=$($LFS getstripe -S -d $dir) ||
7308                 error "$LFS getstripe -S -d $dir failed"
7309         stripe_size=${stripe_size%% *}
7310
7311         local file_size=$((stripe_size * OSTCOUNT))
7312         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7313         local required_space=$((file_num * file_size))
7314         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7315                            head -n1)
7316         (( free_space >= required_space / 1024 )) ||
7317                 skip_env "need $required_space, have $free_space kbytes"
7318
7319         local dd_bs=65536
7320         local dd_count=$((file_size / dd_bs))
7321
7322         # write data into the files
7323         local i
7324         local j
7325         local file
7326
7327         for ((i = 1; i <= NUMFILES; i++ )); do
7328                 file=$dir/file$i
7329                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7330                         error "write data into $file failed"
7331         done
7332         for ((i = 1; i <= NUMDIRS; i++ )); do
7333                 for ((j = 1; j <= NUMFILES; j++ )); do
7334                         file=$dir/dir$i/file$j
7335                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7336                                 error "write data into $file failed"
7337                 done
7338         done
7339
7340         # $LFS_MIGRATE will fail if hard link migration is unsupported
7341         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7342                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7343                         error "creating links to $dir/dir1/file1 failed"
7344         fi
7345
7346         local expected=-1
7347
7348         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7349
7350         # lfs_migrate file
7351         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7352
7353         echo "$cmd"
7354         eval $cmd || error "$cmd failed"
7355
7356         check_stripe_count $dir/file1 $expected
7357
7358         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7359                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7360                 # OST 1 if it is on OST 0. This file is small enough to
7361                 # be on only one stripe.
7362                 file=$dir/migr_1_ost
7363                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7364                         error "write data into $file failed"
7365                 local obdidx=$($LFS getstripe -i $file)
7366                 local oldmd5=$(md5sum $file)
7367                 local newobdidx=0
7368
7369                 (( obdidx != 0 )) || newobdidx=1
7370                 cmd="$LFS migrate -i $newobdidx $file"
7371                 echo $cmd
7372                 eval $cmd || error "$cmd failed"
7373
7374                 local realobdix=$($LFS getstripe -i $file)
7375                 local newmd5=$(md5sum $file)
7376
7377                 (( $newobdidx == $realobdix )) ||
7378                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7379                 [[ "$oldmd5" == "$newmd5" ]] ||
7380                         error "md5sum differ: $oldmd5, $newmd5"
7381         fi
7382
7383         # lfs_migrate dir
7384         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7385         echo "$cmd"
7386         eval $cmd || error "$cmd failed"
7387
7388         for (( j = 1; j <= NUMFILES; j++ )); do
7389                 check_stripe_count $dir/dir1/file$j $expected
7390         done
7391
7392         # lfs_migrate works with lfs find
7393         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7394              $LFS_MIGRATE -y -c $expected"
7395         echo "$cmd"
7396         eval $cmd || error "$cmd failed"
7397
7398         for (( i = 2; i <= NUMFILES; i++ )); do
7399                 check_stripe_count $dir/file$i $expected
7400         done
7401         for (( i = 2; i <= NUMDIRS; i++ )); do
7402                 for (( j = 1; j <= NUMFILES; j++ )); do
7403                         check_stripe_count $dir/dir$i/file$j $expected
7404                 done
7405         done
7406 }
7407 run_test 56wa "check lfs_migrate -c stripe_count works"
7408
7409 test_56wb() {
7410         local file1=$DIR/$tdir/file1
7411         local create_pool=false
7412         local initial_pool=$($LFS getstripe -p $DIR)
7413         local pool_list=()
7414         local pool=""
7415
7416         echo -n "Creating test dir..."
7417         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7418         echo "done."
7419
7420         echo -n "Creating test file..."
7421         touch $file1 || error "cannot create file"
7422         echo "done."
7423
7424         echo -n "Detecting existing pools..."
7425         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7426
7427         if [ ${#pool_list[@]} -gt 0 ]; then
7428                 echo "${pool_list[@]}"
7429                 for thispool in "${pool_list[@]}"; do
7430                         if [[ -z "$initial_pool" ||
7431                               "$initial_pool" != "$thispool" ]]; then
7432                                 pool="$thispool"
7433                                 echo "Using existing pool '$pool'"
7434                                 break
7435                         fi
7436                 done
7437         else
7438                 echo "none detected."
7439         fi
7440         if [ -z "$pool" ]; then
7441                 pool=${POOL:-testpool}
7442                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7443                 echo -n "Creating pool '$pool'..."
7444                 create_pool=true
7445                 pool_add $pool &> /dev/null ||
7446                         error "pool_add failed"
7447                 echo "done."
7448
7449                 echo -n "Adding target to pool..."
7450                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7451                         error "pool_add_targets failed"
7452                 echo "done."
7453         fi
7454
7455         echo -n "Setting pool using -p option..."
7456         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7457                 error "migrate failed rc = $?"
7458         echo "done."
7459
7460         echo -n "Verifying test file is in pool after migrating..."
7461         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7462                 error "file was not migrated to pool $pool"
7463         echo "done."
7464
7465         echo -n "Removing test file from pool '$pool'..."
7466         # "lfs migrate $file" won't remove the file from the pool
7467         # until some striping information is changed.
7468         $LFS migrate -c 1 $file1 &> /dev/null ||
7469                 error "cannot remove from pool"
7470         [ "$($LFS getstripe -p $file1)" ] &&
7471                 error "pool still set"
7472         echo "done."
7473
7474         echo -n "Setting pool using --pool option..."
7475         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7476                 error "migrate failed rc = $?"
7477         echo "done."
7478
7479         # Clean up
7480         rm -f $file1
7481         if $create_pool; then
7482                 destroy_test_pools 2> /dev/null ||
7483                         error "destroy test pools failed"
7484         fi
7485 }
7486 run_test 56wb "check lfs_migrate pool support"
7487
7488 test_56wc() {
7489         local file1="$DIR/$tdir/$tfile"
7490         local md5
7491         local parent_ssize
7492         local parent_scount
7493         local cur_ssize
7494         local cur_scount
7495         local orig_ssize
7496         local new_scount
7497         local cur_comp
7498
7499         echo -n "Creating test dir..."
7500         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7501         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7502                 error "cannot set stripe by '-S 1M -c 1'"
7503         echo "done"
7504
7505         echo -n "Setting initial stripe for test file..."
7506         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7507                 error "cannot set stripe"
7508         cur_ssize=$($LFS getstripe -S "$file1")
7509         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7510         echo "done."
7511
7512         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7513         stack_trap "rm -f $file1"
7514         md5="$(md5sum $file1)"
7515
7516         # File currently set to -S 512K -c 1
7517
7518         # Ensure -c and -S options are rejected when -R is set
7519         echo -n "Verifying incompatible options are detected..."
7520         $LFS_MIGRATE -R -c 1 "$file1" &&
7521                 error "incompatible -R and -c options not detected"
7522         $LFS_MIGRATE -R -S 1M "$file1" &&
7523                 error "incompatible -R and -S options not detected"
7524         $LFS_MIGRATE -R -p pool "$file1" &&
7525                 error "incompatible -R and -p options not detected"
7526         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7527                 error "incompatible -R and -E options not detected"
7528         $LFS_MIGRATE -R -A "$file1" &&
7529                 error "incompatible -R and -A options not detected"
7530         $LFS_MIGRATE -A -c 1 "$file1" &&
7531                 error "incompatible -A and -c options not detected"
7532         $LFS_MIGRATE -A -S 1M "$file1" &&
7533                 error "incompatible -A and -S options not detected"
7534         $LFS_MIGRATE -A -p pool "$file1" &&
7535                 error "incompatible -A and -p options not detected"
7536         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7537                 error "incompatible -A and -E options not detected"
7538         echo "done."
7539
7540         # Ensure unrecognized options are passed through to 'lfs migrate'
7541         echo -n "Verifying -S option is passed through to lfs migrate..."
7542         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7543         cur_ssize=$($LFS getstripe -S "$file1")
7544         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7545         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7546         echo "done."
7547
7548         # File currently set to -S 1M -c 1
7549
7550         # Ensure long options are supported
7551         echo -n "Verifying long options supported..."
7552         $LFS_MIGRATE --non-block "$file1" ||
7553                 error "long option without argument not supported"
7554         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7555                 error "long option with argument not supported"
7556         cur_ssize=$($LFS getstripe -S "$file1")
7557         (( cur_ssize == 524288 )) ||
7558                 error "migrate --stripe-size $cur_ssize != 524288"
7559         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7560         echo "done."
7561
7562         # File currently set to -S 512K -c 1
7563
7564         if (( OSTCOUNT > 1 )); then
7565                 echo -n "Verifying explicit stripe count can be set..."
7566                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7567                 cur_scount=$($LFS getstripe -c "$file1")
7568                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7569                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7570                         error "file data has changed (3)"
7571                 echo "done."
7572         fi
7573
7574         # File currently set to -S 512K -c 1 or -S 512K -c 2
7575
7576         # Ensure parent striping is used if -R is set, and no stripe
7577         # count or size is specified
7578         echo -n "Setting stripe for parent directory..."
7579         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7580                 error "cannot set stripe '-S 2M -c 1'"
7581         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7582         echo "done."
7583
7584         echo -n "Verifying restripe option uses parent stripe settings..."
7585         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7586         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7587         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7588         cur_ssize=$($LFS getstripe -S "$file1")
7589         (( cur_ssize == parent_ssize )) ||
7590                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7591         cur_scount=$($LFS getstripe -c "$file1")
7592         (( cur_scount == parent_scount )) ||
7593                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7594         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7595         echo "done."
7596
7597         # File currently set to -S 1M -c 1
7598
7599         # Ensure striping is preserved if -R is not set, and no stripe
7600         # count or size is specified
7601         echo -n "Verifying striping size preserved when not specified..."
7602         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7603         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7604                 error "cannot set stripe on parent directory"
7605         $LFS_MIGRATE "$file1" || error "migrate failed"
7606         cur_ssize=$($LFS getstripe -S "$file1")
7607         (( cur_ssize == orig_ssize )) ||
7608                 error "migrate by default $cur_ssize != $orig_ssize"
7609         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7610         echo "done."
7611
7612         # Ensure file name properly detected when final option has no argument
7613         echo -n "Verifying file name properly detected..."
7614         $LFS_MIGRATE "$file1" ||
7615                 error "file name interpreted as option argument"
7616         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7617         echo "done."
7618
7619         # Ensure PFL arguments are passed through properly
7620         echo -n "Verifying PFL options passed through..."
7621         new_scount=$(((OSTCOUNT + 1) / 2))
7622         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7623                 error "migrate PFL arguments failed"
7624         cur_comp=$($LFS getstripe --comp-count $file1)
7625         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7626         cur_scount=$($LFS getstripe --stripe-count $file1)
7627         (( cur_scount == new_scount)) ||
7628                 error "PFL stripe count $cur_scount != $new_scount"
7629         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7630         echo "done."
7631 }
7632 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7633
7634 test_56wd() {
7635         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7636
7637         local file1=$DIR/$tdir/$tfile
7638
7639         echo -n "Creating test dir..."
7640         test_mkdir $DIR/$tdir || error "cannot create dir"
7641         echo "done."
7642
7643         echo -n "Creating test file..."
7644         echo "$tfile" > $file1
7645         echo "done."
7646
7647         # Ensure 'lfs migrate' will fail by using a non-existent option,
7648         # and make sure rsync is not called to recover
7649         echo -n "Make sure --no-rsync option works..."
7650         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7651                 grep -q 'refusing to fall back to rsync' ||
7652                 error "rsync was called with --no-rsync set"
7653         echo "done."
7654
7655         # Ensure rsync is called without trying 'lfs migrate' first
7656         echo -n "Make sure --rsync option works..."
7657         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7658                 grep -q 'falling back to rsync' &&
7659                 error "lfs migrate was called with --rsync set"
7660         echo "done."
7661 }
7662 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7663
7664 test_56we() {
7665         local td=$DIR/$tdir
7666         local tf=$td/$tfile
7667
7668         test_mkdir $td || error "cannot create $td"
7669         touch $tf || error "cannot touch $tf"
7670
7671         echo -n "Make sure --non-direct|-D works..."
7672         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7673                 grep -q "lfs migrate --non-direct" ||
7674                 error "--non-direct option cannot work correctly"
7675         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7676                 grep -q "lfs migrate -D" ||
7677                 error "-D option cannot work correctly"
7678         echo "done."
7679 }
7680 run_test 56we "check lfs_migrate --non-direct|-D support"
7681
7682 test_56x() {
7683         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7684         check_swap_layouts_support
7685
7686         local dir=$DIR/$tdir
7687         local ref1=/etc/passwd
7688         local file1=$dir/file1
7689
7690         test_mkdir $dir || error "creating dir $dir"
7691         $LFS setstripe -c 2 $file1
7692         cp $ref1 $file1
7693         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7694         stripe=$($LFS getstripe -c $file1)
7695         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7696         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7697
7698         # clean up
7699         rm -f $file1
7700 }
7701 run_test 56x "lfs migration support"
7702
7703 test_56xa() {
7704         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7705         check_swap_layouts_support
7706
7707         local dir=$DIR/$tdir/$testnum
7708
7709         test_mkdir -p $dir
7710
7711         local ref1=/etc/passwd
7712         local file1=$dir/file1
7713
7714         $LFS setstripe -c 2 $file1
7715         cp $ref1 $file1
7716         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7717
7718         local stripe=$($LFS getstripe -c $file1)
7719
7720         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7721         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7722
7723         # clean up
7724         rm -f $file1
7725 }
7726 run_test 56xa "lfs migration --block support"
7727
7728 check_migrate_links() {
7729         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7730         local dir="$1"
7731         local file1="$dir/file1"
7732         local begin="$2"
7733         local count="$3"
7734         local runas="$4"
7735         local total_count=$(($begin + $count - 1))
7736         local symlink_count=10
7737         local uniq_count=10
7738
7739         if [ ! -f "$file1" ]; then
7740                 echo -n "creating initial file..."
7741                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7742                         error "cannot setstripe initial file"
7743                 echo "done"
7744
7745                 echo -n "creating symlinks..."
7746                 for s in $(seq 1 $symlink_count); do
7747                         ln -s "$file1" "$dir/slink$s" ||
7748                                 error "cannot create symlinks"
7749                 done
7750                 echo "done"
7751
7752                 echo -n "creating nonlinked files..."
7753                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7754                         error "cannot create nonlinked files"
7755                 echo "done"
7756         fi
7757
7758         # create hard links
7759         if [ ! -f "$dir/file$total_count" ]; then
7760                 echo -n "creating hard links $begin:$total_count..."
7761                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7762                         /dev/null || error "cannot create hard links"
7763                 echo "done"
7764         fi
7765
7766         echo -n "checking number of hard links listed in xattrs..."
7767         local fid=$($LFS getstripe -F "$file1")
7768         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7769
7770         echo "${#paths[*]}"
7771         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7772                         skip "hard link list has unexpected size, skipping test"
7773         fi
7774         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7775                         error "link names should exceed xattrs size"
7776         fi
7777
7778         echo -n "migrating files..."
7779         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7780         local rc=$?
7781         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7782         echo "done"
7783
7784         # make sure all links have been properly migrated
7785         echo -n "verifying files..."
7786         fid=$($LFS getstripe -F "$file1") ||
7787                 error "cannot get fid for file $file1"
7788         for i in $(seq 2 $total_count); do
7789                 local fid2=$($LFS getstripe -F $dir/file$i)
7790
7791                 [ "$fid2" == "$fid" ] ||
7792                         error "migrated hard link has mismatched FID"
7793         done
7794
7795         # make sure hard links were properly detected, and migration was
7796         # performed only once for the entire link set; nonlinked files should
7797         # also be migrated
7798         local actual=$(grep -c 'done' <<< "$migrate_out")
7799         local expected=$(($uniq_count + 1))
7800
7801         [ "$actual" -eq  "$expected" ] ||
7802                 error "hard links individually migrated ($actual != $expected)"
7803
7804         # make sure the correct number of hard links are present
7805         local hardlinks=$(stat -c '%h' "$file1")
7806
7807         [ $hardlinks -eq $total_count ] ||
7808                 error "num hard links $hardlinks != $total_count"
7809         echo "done"
7810
7811         return 0
7812 }
7813
7814 test_56xb() {
7815         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7816                 skip "Need MDS version at least 2.10.55"
7817
7818         local dir="$DIR/$tdir"
7819
7820         test_mkdir "$dir" || error "cannot create dir $dir"
7821
7822         echo "testing lfs migrate mode when all links fit within xattrs"
7823         check_migrate_links "$dir" 2 99
7824
7825         echo "testing rsync mode when all links fit within xattrs"
7826         check_migrate_links --rsync "$dir" 2 99
7827
7828         echo "testing lfs migrate mode when all links do not fit within xattrs"
7829         check_migrate_links "$dir" 101 100
7830
7831         echo "testing rsync mode when all links do not fit within xattrs"
7832         check_migrate_links --rsync "$dir" 101 100
7833
7834         chown -R $RUNAS_ID $dir
7835         echo "testing non-root lfs migrate mode when not all links are in xattr"
7836         check_migrate_links "$dir" 101 100 "$RUNAS"
7837
7838         # clean up
7839         rm -rf $dir
7840 }
7841 run_test 56xb "lfs migration hard link support"
7842
7843 test_56xc() {
7844         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7845
7846         local dir="$DIR/$tdir"
7847
7848         test_mkdir "$dir" || error "cannot create dir $dir"
7849
7850         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7851         echo -n "Setting initial stripe for 20MB test file..."
7852         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7853                 error "cannot setstripe 20MB file"
7854         echo "done"
7855         echo -n "Sizing 20MB test file..."
7856         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7857         echo "done"
7858         echo -n "Verifying small file autostripe count is 1..."
7859         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7860                 error "cannot migrate 20MB file"
7861         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7862                 error "cannot get stripe for $dir/20mb"
7863         [ $stripe_count -eq 1 ] ||
7864                 error "unexpected stripe count $stripe_count for 20MB file"
7865         rm -f "$dir/20mb"
7866         echo "done"
7867
7868         # Test 2: File is small enough to fit within the available space on
7869         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7870         # have at least an additional 1KB for each desired stripe for test 3
7871         echo -n "Setting stripe for 1GB test file..."
7872         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7873         echo "done"
7874         echo -n "Sizing 1GB test file..."
7875         # File size is 1GB + 3KB
7876         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7877         echo "done"
7878
7879         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7880         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7881         if (( avail > 524288 * OSTCOUNT )); then
7882                 echo -n "Migrating 1GB file..."
7883                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7884                         error "cannot migrate 1GB file"
7885                 echo "done"
7886                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7887                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7888                         error "cannot getstripe for 1GB file"
7889                 [ $stripe_count -eq 2 ] ||
7890                         error "unexpected stripe count $stripe_count != 2"
7891                 echo "done"
7892         fi
7893
7894         # Test 3: File is too large to fit within the available space on
7895         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7896         if [ $OSTCOUNT -ge 3 ]; then
7897                 # The required available space is calculated as
7898                 # file size (1GB + 3KB) / OST count (3).
7899                 local kb_per_ost=349526
7900
7901                 echo -n "Migrating 1GB file with limit..."
7902                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7903                         error "cannot migrate 1GB file with limit"
7904                 echo "done"
7905
7906                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7907                 echo -n "Verifying 1GB autostripe count with limited space..."
7908                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7909                         error "unexpected stripe count $stripe_count (min 3)"
7910                 echo "done"
7911         fi
7912
7913         # clean up
7914         rm -rf $dir
7915 }
7916 run_test 56xc "lfs migration autostripe"
7917
7918 test_56xd() {
7919         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7920
7921         local dir=$DIR/$tdir
7922         local f_mgrt=$dir/$tfile.mgrt
7923         local f_yaml=$dir/$tfile.yaml
7924         local f_copy=$dir/$tfile.copy
7925         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7926         local layout_copy="-c 2 -S 2M -i 1"
7927         local yamlfile=$dir/yamlfile
7928         local layout_before;
7929         local layout_after;
7930
7931         test_mkdir "$dir" || error "cannot create dir $dir"
7932         $LFS setstripe $layout_yaml $f_yaml ||
7933                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7934         $LFS getstripe --yaml $f_yaml > $yamlfile
7935         $LFS setstripe $layout_copy $f_copy ||
7936                 error "cannot setstripe $f_copy with layout $layout_copy"
7937         touch $f_mgrt
7938         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7939
7940         # 1. test option --yaml
7941         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7942                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7943         layout_before=$(get_layout_param $f_yaml)
7944         layout_after=$(get_layout_param $f_mgrt)
7945         [ "$layout_after" == "$layout_before" ] ||
7946                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7947
7948         # 2. test option --copy
7949         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7950                 error "cannot migrate $f_mgrt with --copy $f_copy"
7951         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
7952         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
7953         [ "$layout_after" == "$layout_before" ] ||
7954                 error "lfs_migrate --copy: $layout_after != $layout_before"
7955 }
7956 run_test 56xd "check lfs_migrate --yaml and --copy support"
7957
7958 test_56xe() {
7959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7960
7961         local dir=$DIR/$tdir
7962         local f_comp=$dir/$tfile
7963         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7964         local layout_before=""
7965         local layout_after=""
7966
7967         test_mkdir "$dir" || error "cannot create dir $dir"
7968         $LFS setstripe $layout $f_comp ||
7969                 error "cannot setstripe $f_comp with layout $layout"
7970         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
7971         dd if=/dev/zero of=$f_comp bs=1M count=4
7972
7973         # 1. migrate a comp layout file by lfs_migrate
7974         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7975         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
7976         [ "$layout_before" == "$layout_after" ] ||
7977                 error "lfs_migrate: $layout_before != $layout_after"
7978
7979         # 2. migrate a comp layout file by lfs migrate
7980         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7981         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
7982         [ "$layout_before" == "$layout_after" ] ||
7983                 error "lfs migrate: $layout_before != $layout_after"
7984 }
7985 run_test 56xe "migrate a composite layout file"
7986
7987 test_56xf() {
7988         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7989
7990         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7991                 skip "Need server version at least 2.13.53"
7992
7993         local dir=$DIR/$tdir
7994         local f_comp=$dir/$tfile
7995         local layout="-E 1M -c1 -E -1 -c2"
7996         local fid_before=""
7997         local fid_after=""
7998
7999         test_mkdir "$dir" || error "cannot create dir $dir"
8000         $LFS setstripe $layout $f_comp ||
8001                 error "cannot setstripe $f_comp with layout $layout"
8002         fid_before=$($LFS getstripe --fid $f_comp)
8003         dd if=/dev/zero of=$f_comp bs=1M count=4
8004
8005         # 1. migrate a comp layout file to a comp layout
8006         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8007         fid_after=$($LFS getstripe --fid $f_comp)
8008         [ "$fid_before" == "$fid_after" ] ||
8009                 error "comp-to-comp migrate: $fid_before != $fid_after"
8010
8011         # 2. migrate a comp layout file to a plain layout
8012         $LFS migrate -c2 $f_comp ||
8013                 error "cannot migrate $f_comp by lfs migrate"
8014         fid_after=$($LFS getstripe --fid $f_comp)
8015         [ "$fid_before" == "$fid_after" ] ||
8016                 error "comp-to-plain migrate: $fid_before != $fid_after"
8017
8018         # 3. migrate a plain layout file to a comp layout
8019         $LFS migrate $layout $f_comp ||
8020                 error "cannot migrate $f_comp by lfs migrate"
8021         fid_after=$($LFS getstripe --fid $f_comp)
8022         [ "$fid_before" == "$fid_after" ] ||
8023                 error "plain-to-comp migrate: $fid_before != $fid_after"
8024 }
8025 run_test 56xf "FID is not lost during migration of a composite layout file"
8026
8027 check_file_ost_range() {
8028         local file="$1"
8029         shift
8030         local range="$*"
8031         local -a file_range
8032         local idx
8033
8034         file_range=($($LFS getstripe -y "$file" |
8035                 awk '/l_ost_idx:/ { print $NF }'))
8036
8037         if [[ "${#file_range[@]}" = 0 ]]; then
8038                 echo "No osts found for $file"
8039                 return 1
8040         fi
8041
8042         for idx in "${file_range[@]}"; do
8043                 [[ " $range " =~ " $idx " ]] ||
8044                         return 1
8045         done
8046
8047         return 0
8048 }
8049
8050 sub_test_56xg() {
8051         local stripe_opt="$1"
8052         local pool="$2"
8053         shift 2
8054         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8055
8056         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8057                 error "Fail to migrate $tfile on $pool"
8058         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8059                 error "$tfile is not in pool $pool"
8060         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8061                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8062 }
8063
8064 test_56xg() {
8065         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8066         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8067         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8068                 skip "Need MDS version newer than 2.14.52"
8069
8070         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8071         local -a pool_ranges=("0 0" "1 1" "0 1")
8072
8073         # init pools
8074         for i in "${!pool_names[@]}"; do
8075                 pool_add ${pool_names[$i]} ||
8076                         error "pool_add failed (pool: ${pool_names[$i]})"
8077                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8078                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8079         done
8080
8081         # init the file to migrate
8082         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8083                 error "Unable to create $tfile on OST1"
8084         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8085                 error "Unable to write on $tfile"
8086
8087         echo "1. migrate $tfile on pool ${pool_names[0]}"
8088         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8089
8090         echo "2. migrate $tfile on pool ${pool_names[2]}"
8091         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8092
8093         echo "3. migrate $tfile on pool ${pool_names[1]}"
8094         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8095
8096         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8097         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8098         echo
8099
8100         # Clean pools
8101         destroy_test_pools ||
8102                 error "pool_destroy failed"
8103 }
8104 run_test 56xg "lfs migrate pool support"
8105
8106 test_56xh() {
8107         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8108
8109         local size_mb=25
8110         local file1=$DIR/$tfile
8111         local tmp1=$TMP/$tfile.tmp
8112
8113         $LFS setstripe -c 2 $file1
8114
8115         stack_trap "rm -f $file1 $tmp1"
8116         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8117                         error "error creating $tmp1"
8118         ls -lsh $tmp1
8119         cp $tmp1 $file1
8120
8121         local start=$SECONDS
8122
8123         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8124                 error "migrate failed rc = $?"
8125
8126         local elapsed=$((SECONDS - start))
8127
8128         # with 1MB/s, elapsed should equal size_mb
8129         (( elapsed >= size_mb * 95 / 100 )) ||
8130                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8131
8132         (( elapsed <= size_mb * 120 / 100 )) ||
8133                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8134
8135         (( elapsed <= size_mb * 150 / 100 )) ||
8136                 error "'lfs migrate -W' too slow in VM ($elapsed > 2 * $size_mb 2)"
8137
8138         stripe=$($LFS getstripe -c $file1)
8139         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8140         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8141
8142         # Clean up file (since it is multiple MB)
8143         rm -f $file1 $tmp1
8144 }
8145 run_test 56xh "lfs migrate bandwidth limitation support"
8146
8147 test_56xi() {
8148         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8149         verify_yaml_available || skip_env "YAML verification not installed"
8150
8151         local size_mb=5
8152         local file1=$DIR/$tfile.1
8153         local file2=$DIR/$tfile.2
8154         local file3=$DIR/$tfile.3
8155         local output_file=$DIR/$tfile.out
8156         local tmp1=$TMP/$tfile.tmp
8157
8158         $LFS setstripe -c 2 $file1
8159         $LFS setstripe -c 2 $file2
8160         $LFS setstripe -c 2 $file3
8161
8162         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8163         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8164                         error "error creating $tmp1"
8165         ls -lsh $tmp1
8166         cp $tmp1 $file1
8167         cp $tmp1 $file2
8168         cp $tmp1 $file3
8169
8170         $LFS migrate --stats --stats-interval=1 \
8171                 -c 1 $file1 $file2 $file3 1> $output_file ||
8172                 error "migrate failed rc = $?"
8173
8174         cat $output_file
8175         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8176
8177         # Clean up file (since it is multiple MB)
8178         rm -f $file1 $file2 $file3 $tmp1 $output_file
8179 }
8180 run_test 56xi "lfs migrate stats support"
8181
8182 test_56y() {
8183         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8184                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8185
8186         local res=""
8187         local dir=$DIR/$tdir
8188         local f1=$dir/file1
8189         local f2=$dir/file2
8190
8191         test_mkdir -p $dir || error "creating dir $dir"
8192         touch $f1 || error "creating std file $f1"
8193         $MULTIOP $f2 H2c || error "creating released file $f2"
8194
8195         # a directory can be raid0, so ask only for files
8196         res=$($LFS find $dir -L raid0 -type f | wc -l)
8197         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8198
8199         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8200         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8201
8202         # only files can be released, so no need to force file search
8203         res=$($LFS find $dir -L released)
8204         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8205
8206         res=$($LFS find $dir -type f \! -L released)
8207         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8208 }
8209 run_test 56y "lfs find -L raid0|released"
8210
8211 test_56z() { # LU-4824
8212         # This checks to make sure 'lfs find' continues after errors
8213         # There are two classes of errors that should be caught:
8214         # - If multiple paths are provided, all should be searched even if one
8215         #   errors out
8216         # - If errors are encountered during the search, it should not terminate
8217         #   early
8218         local dir=$DIR/$tdir
8219         local i
8220
8221         test_mkdir $dir
8222         for i in d{0..9}; do
8223                 test_mkdir $dir/$i
8224                 touch $dir/$i/$tfile
8225         done
8226         $LFS find $DIR/non_existent_dir $dir &&
8227                 error "$LFS find did not return an error"
8228         # Make a directory unsearchable. This should NOT be the last entry in
8229         # directory order.  Arbitrarily pick the 6th entry
8230         chmod 700 $($LFS find $dir -type d | sed '6!d')
8231
8232         $RUNAS $LFS find $DIR/non_existent $dir
8233         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8234
8235         # The user should be able to see 10 directories and 9 files
8236         (( count == 19 )) ||
8237                 error "$LFS find found $count != 19 entries after error"
8238 }
8239 run_test 56z "lfs find should continue after an error"
8240
8241 test_56aa() { # LU-5937
8242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8243
8244         local dir=$DIR/$tdir
8245
8246         mkdir $dir
8247         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8248
8249         createmany -o $dir/striped_dir/${tfile}- 1024
8250         local dirs=$($LFS find --size +8k $dir/)
8251
8252         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8253 }
8254 run_test 56aa "lfs find --size under striped dir"
8255
8256 test_56ab() { # LU-10705
8257         test_mkdir $DIR/$tdir
8258         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8259         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8260         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8261         # Flush writes to ensure valid blocks.  Need to be more thorough for
8262         # ZFS, since blocks are not allocated/returned to client immediately.
8263         sync_all_data
8264         wait_zfs_commit ost1 2
8265         cancel_lru_locks osc
8266         ls -ls $DIR/$tdir
8267
8268         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8269
8270         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8271
8272         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8273         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8274
8275         rm -f $DIR/$tdir/$tfile.[123]
8276 }
8277 run_test 56ab "lfs find --blocks"
8278
8279 # LU-11188
8280 test_56aca() {
8281         local dir="$DIR/$tdir"
8282         local perms=(001 002 003 004 005 006 007
8283                      010 020 030 040 050 060 070
8284                      100 200 300 400 500 600 700
8285                      111 222 333 444 555 666 777)
8286         local perm_minus=(8 8 4 8 4 4 2
8287                           8 8 4 8 4 4 2
8288                           8 8 4 8 4 4 2
8289                           4 4 2 4 2 2 1)
8290         local perm_slash=(8  8 12  8 12 12 14
8291                           8  8 12  8 12 12 14
8292                           8  8 12  8 12 12 14
8293                          16 16 24 16 24 24 28)
8294
8295         test_mkdir "$dir"
8296         for perm in ${perms[*]}; do
8297                 touch "$dir/$tfile.$perm"
8298                 chmod $perm "$dir/$tfile.$perm"
8299         done
8300
8301         for ((i = 0; i < ${#perms[*]}; i++)); do
8302                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8303                 (( $num == 1 )) ||
8304                         error "lfs find -perm ${perms[i]}:"\
8305                               "$num != 1"
8306
8307                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8308                 (( $num == ${perm_minus[i]} )) ||
8309                         error "lfs find -perm -${perms[i]}:"\
8310                               "$num != ${perm_minus[i]}"
8311
8312                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8313                 (( $num == ${perm_slash[i]} )) ||
8314                         error "lfs find -perm /${perms[i]}:"\
8315                               "$num != ${perm_slash[i]}"
8316         done
8317 }
8318 run_test 56aca "check lfs find -perm with octal representation"
8319
8320 test_56acb() {
8321         local dir=$DIR/$tdir
8322         # p is the permission of write and execute for user, group and other
8323         # without the umask. It is used to test +wx.
8324         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8325         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8326         local symbolic=(+t  a+t u+t g+t o+t
8327                         g+s u+s o+s +s o+sr
8328                         o=r,ug+o,u+w
8329                         u+ g+ o+ a+ ugo+
8330                         u- g- o- a- ugo-
8331                         u= g= o= a= ugo=
8332                         o=r,ug+o,u+w u=r,a+u,u+w
8333                         g=r,ugo=g,u+w u+x,+X +X
8334                         u+x,u+X u+X u+x,g+X o+r,+X
8335                         u+x,go+X +wx +rwx)
8336
8337         test_mkdir $dir
8338         for perm in ${perms[*]}; do
8339                 touch "$dir/$tfile.$perm"
8340                 chmod $perm "$dir/$tfile.$perm"
8341         done
8342
8343         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8344                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8345
8346                 (( $num == 1 )) ||
8347                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8348         done
8349 }
8350 run_test 56acb "check lfs find -perm with symbolic representation"
8351
8352 test_56acc() {
8353         local dir=$DIR/$tdir
8354         local tests="17777 787 789 abcd
8355                 ug=uu ug=a ug=gu uo=ou urw
8356                 u+xg+x a=r,u+x,"
8357
8358         test_mkdir $dir
8359         for err in $tests; do
8360                 if $LFS find $dir -perm $err 2>/dev/null; then
8361                         error "lfs find -perm $err: parsing should have failed"
8362                 fi
8363         done
8364 }
8365 run_test 56acc "check parsing error for lfs find -perm"
8366
8367 test_56ba() {
8368         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8369                 skip "Need MDS version at least 2.10.50"
8370
8371         # Create composite files with one component
8372         local dir=$DIR/$tdir
8373
8374         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8375         # Create composite files with three components
8376         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8377         # Create non-composite files
8378         createmany -o $dir/${tfile}- 10
8379
8380         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8381
8382         [[ $nfiles == 10 ]] ||
8383                 error "lfs find -E 1M found $nfiles != 10 files"
8384
8385         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8386         [[ $nfiles == 25 ]] ||
8387                 error "lfs find ! -E 1M found $nfiles != 25 files"
8388
8389         # All files have a component that starts at 0
8390         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8391         [[ $nfiles == 35 ]] ||
8392                 error "lfs find --component-start 0 - $nfiles != 35 files"
8393
8394         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8395         [[ $nfiles == 15 ]] ||
8396                 error "lfs find --component-start 2M - $nfiles != 15 files"
8397
8398         # All files created here have a componenet that does not starts at 2M
8399         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8400         [[ $nfiles == 35 ]] ||
8401                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8402
8403         # Find files with a specified number of components
8404         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8405         [[ $nfiles == 15 ]] ||
8406                 error "lfs find --component-count 3 - $nfiles != 15 files"
8407
8408         # Remember non-composite files have a component count of zero
8409         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8410         [[ $nfiles == 10 ]] ||
8411                 error "lfs find --component-count 0 - $nfiles != 10 files"
8412
8413         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8414         [[ $nfiles == 20 ]] ||
8415                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8416
8417         # All files have a flag called "init"
8418         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8419         [[ $nfiles == 35 ]] ||
8420                 error "lfs find --component-flags init - $nfiles != 35 files"
8421
8422         # Multi-component files will have a component not initialized
8423         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8424         [[ $nfiles == 15 ]] ||
8425                 error "lfs find !--component-flags init - $nfiles != 15 files"
8426
8427         rm -rf $dir
8428
8429 }
8430 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8431
8432 test_56ca() {
8433         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8434                 skip "Need MDS version at least 2.10.57"
8435
8436         local td=$DIR/$tdir
8437         local tf=$td/$tfile
8438         local dir
8439         local nfiles
8440         local cmd
8441         local i
8442         local j
8443
8444         # create mirrored directories and mirrored files
8445         mkdir $td || error "mkdir $td failed"
8446         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8447         createmany -o $tf- 10 || error "create $tf- failed"
8448
8449         for i in $(seq 2); do
8450                 dir=$td/dir$i
8451                 mkdir $dir || error "mkdir $dir failed"
8452                 $LFS mirror create -N$((3 + i)) $dir ||
8453                         error "create mirrored dir $dir failed"
8454                 createmany -o $dir/$tfile- 10 ||
8455                         error "create $dir/$tfile- failed"
8456         done
8457
8458         # change the states of some mirrored files
8459         echo foo > $tf-6
8460         for i in $(seq 2); do
8461                 dir=$td/dir$i
8462                 for j in $(seq 4 9); do
8463                         echo foo > $dir/$tfile-$j
8464                 done
8465         done
8466
8467         # find mirrored files with specific mirror count
8468         cmd="$LFS find --mirror-count 3 --type f $td"
8469         nfiles=$($cmd | wc -l)
8470         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8471
8472         cmd="$LFS find ! --mirror-count 3 --type f $td"
8473         nfiles=$($cmd | wc -l)
8474         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8475
8476         cmd="$LFS find --mirror-count +2 --type f $td"
8477         nfiles=$($cmd | wc -l)
8478         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8479
8480         cmd="$LFS find --mirror-count -6 --type f $td"
8481         nfiles=$($cmd | wc -l)
8482         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8483
8484         # find mirrored files with specific file state
8485         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8486         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8487
8488         cmd="$LFS find --mirror-state=ro --type f $td"
8489         nfiles=$($cmd | wc -l)
8490         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8491
8492         cmd="$LFS find ! --mirror-state=ro --type f $td"
8493         nfiles=$($cmd | wc -l)
8494         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8495
8496         cmd="$LFS find --mirror-state=wp --type f $td"
8497         nfiles=$($cmd | wc -l)
8498         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8499
8500         cmd="$LFS find ! --mirror-state=sp --type f $td"
8501         nfiles=$($cmd | wc -l)
8502         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8503 }
8504 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8505
8506 test_56da() { # LU-14179
8507         local path=$DIR/$tdir
8508
8509         test_mkdir $path
8510         cd $path
8511
8512         local longdir=$(str_repeat 'a' 255)
8513
8514         for i in {1..15}; do
8515                 path=$path/$longdir
8516                 test_mkdir $longdir
8517                 cd $longdir
8518         done
8519
8520         local len=${#path}
8521         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8522
8523         test_mkdir $lastdir
8524         cd $lastdir
8525         # PATH_MAX-1
8526         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8527
8528         # NAME_MAX
8529         touch $(str_repeat 'f' 255)
8530
8531         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8532                 error "lfs find reported an error"
8533
8534         rm -rf $DIR/$tdir
8535 }
8536 run_test 56da "test lfs find with long paths"
8537
8538 test_56ea() { #LU-10378
8539         local path=$DIR/$tdir
8540         local pool=$TESTNAME
8541
8542         # Create ost pool
8543         pool_add $pool || error "pool_add $pool failed"
8544         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8545                 error "adding targets to $pool failed"
8546
8547         # Set default pool on directory before creating file
8548         mkdir $path || error "mkdir $path failed"
8549         $LFS setstripe -p $pool $path ||
8550                 error "set OST pool on $pool failed"
8551         touch $path/$tfile || error "touch $path/$tfile failed"
8552
8553         # Compare basic file attributes from -printf and stat
8554         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8555         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8556
8557         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8558                 error "Attrs from lfs find and stat don't match"
8559
8560         # Compare Lustre attributes from lfs find and lfs getstripe
8561         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8562         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8563         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8564         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8565         local fpool=$($LFS getstripe --pool $path/$tfile)
8566         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8567
8568         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8569                 error "Attrs from lfs find and lfs getstripe don't match"
8570
8571         # Verify behavior for unknown escape/format sequences
8572         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8573
8574         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8575                 error "Escape/format codes don't match"
8576 }
8577 run_test 56ea "test lfs find -printf option"
8578
8579 test_56eb() {
8580         local dir=$DIR/$tdir
8581         local subdir_1=$dir/subdir_1
8582
8583         test_mkdir -p $subdir_1
8584         ln -s subdir_1 $dir/link_1
8585
8586         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8587                 error "symlink is not followed"
8588
8589         $LFS getstripe --no-follow $dir |
8590                 grep "^$dir/link_1 has no stripe info$" ||
8591                 error "symlink should not have stripe info"
8592
8593         touch $dir/testfile
8594         ln -s testfile $dir/file_link_2
8595
8596         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8597                 error "symlink is not followed"
8598
8599         $LFS getstripe --no-follow $dir |
8600                 grep "^$dir/file_link_2 has no stripe info$" ||
8601                 error "symlink should not have stripe info"
8602 }
8603 run_test 56eb "check lfs getstripe on symlink"
8604
8605 test_57a() {
8606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8607         # note test will not do anything if MDS is not local
8608         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8609                 skip_env "ldiskfs only test"
8610         fi
8611         remote_mds_nodsh && skip "remote MDS with nodsh"
8612
8613         local MNTDEV="osd*.*MDT*.mntdev"
8614         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8615         [ -z "$DEV" ] && error "can't access $MNTDEV"
8616         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8617                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8618                         error "can't access $DEV"
8619                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8620                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8621                 rm $TMP/t57a.dump
8622         done
8623 }
8624 run_test 57a "verify MDS filesystem created with large inodes =="
8625
8626 test_57b() {
8627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8628         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8629                 skip_env "ldiskfs only test"
8630         fi
8631         remote_mds_nodsh && skip "remote MDS with nodsh"
8632
8633         local dir=$DIR/$tdir
8634         local filecount=100
8635         local file1=$dir/f1
8636         local fileN=$dir/f$filecount
8637
8638         rm -rf $dir || error "removing $dir"
8639         test_mkdir -c1 $dir
8640         local mdtidx=$($LFS getstripe -m $dir)
8641         local mdtname=MDT$(printf %04x $mdtidx)
8642         local facet=mds$((mdtidx + 1))
8643
8644         echo "mcreating $filecount files"
8645         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8646
8647         # verify that files do not have EAs yet
8648         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8649                 error "$file1 has an EA"
8650         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8651                 error "$fileN has an EA"
8652
8653         sync
8654         sleep 1
8655         df $dir  #make sure we get new statfs data
8656         local mdsfree=$(do_facet $facet \
8657                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8658         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8659         local file
8660
8661         echo "opening files to create objects/EAs"
8662         for file in $(seq -f $dir/f%g 1 $filecount); do
8663                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8664                         error "opening $file"
8665         done
8666
8667         # verify that files have EAs now
8668         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8669         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8670
8671         sleep 1  #make sure we get new statfs data
8672         df $dir
8673         local mdsfree2=$(do_facet $facet \
8674                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8675         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8676
8677         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8678                 if [ "$mdsfree" != "$mdsfree2" ]; then
8679                         error "MDC before $mdcfree != after $mdcfree2"
8680                 else
8681                         echo "MDC before $mdcfree != after $mdcfree2"
8682                         echo "unable to confirm if MDS has large inodes"
8683                 fi
8684         fi
8685         rm -rf $dir
8686 }
8687 run_test 57b "default LOV EAs are stored inside large inodes ==="
8688
8689 test_58() {
8690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8691         [ -z "$(which wiretest 2>/dev/null)" ] &&
8692                         skip_env "could not find wiretest"
8693
8694         wiretest
8695 }
8696 run_test 58 "verify cross-platform wire constants =============="
8697
8698 test_59() {
8699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8700
8701         echo "touch 130 files"
8702         createmany -o $DIR/f59- 130
8703         echo "rm 130 files"
8704         unlinkmany $DIR/f59- 130
8705         sync
8706         # wait for commitment of removal
8707         wait_delete_completed
8708 }
8709 run_test 59 "verify cancellation of llog records async ========="
8710
8711 TEST60_HEAD="test_60 run $RANDOM"
8712 test_60a() {
8713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8714         remote_mgs_nodsh && skip "remote MGS with nodsh"
8715         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8716                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8717                         skip_env "missing subtest run-llog.sh"
8718
8719         log "$TEST60_HEAD - from kernel mode"
8720         do_facet mgs "$LCTL dk > /dev/null"
8721         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8722         do_facet mgs $LCTL dk > $TMP/$tfile
8723
8724         # LU-6388: test llog_reader
8725         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8726         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8727         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8728                         skip_env "missing llog_reader"
8729         local fstype=$(facet_fstype mgs)
8730         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8731                 skip_env "Only for ldiskfs or zfs type mgs"
8732
8733         local mntpt=$(facet_mntpt mgs)
8734         local mgsdev=$(mgsdevname 1)
8735         local fid_list
8736         local fid
8737         local rec_list
8738         local rec
8739         local rec_type
8740         local obj_file
8741         local path
8742         local seq
8743         local oid
8744         local pass=true
8745
8746         #get fid and record list
8747         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8748                 tail -n 4))
8749         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8750                 tail -n 4))
8751         #remount mgs as ldiskfs or zfs type
8752         stop mgs || error "stop mgs failed"
8753         mount_fstype mgs || error "remount mgs failed"
8754         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8755                 fid=${fid_list[i]}
8756                 rec=${rec_list[i]}
8757                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8758                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8759                 oid=$((16#$oid))
8760
8761                 case $fstype in
8762                         ldiskfs )
8763                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8764                         zfs )
8765                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8766                 esac
8767                 echo "obj_file is $obj_file"
8768                 do_facet mgs $llog_reader $obj_file
8769
8770                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8771                         awk '{ print $3 }' | sed -e "s/^type=//g")
8772                 if [ $rec_type != $rec ]; then
8773                         echo "FAILED test_60a wrong record type $rec_type," \
8774                               "should be $rec"
8775                         pass=false
8776                         break
8777                 fi
8778
8779                 #check obj path if record type is LLOG_LOGID_MAGIC
8780                 if [ "$rec" == "1064553b" ]; then
8781                         path=$(do_facet mgs $llog_reader $obj_file |
8782                                 grep "path=" | awk '{ print $NF }' |
8783                                 sed -e "s/^path=//g")
8784                         if [ $obj_file != $mntpt/$path ]; then
8785                                 echo "FAILED test_60a wrong obj path" \
8786                                       "$montpt/$path, should be $obj_file"
8787                                 pass=false
8788                                 break
8789                         fi
8790                 fi
8791         done
8792         rm -f $TMP/$tfile
8793         #restart mgs before "error", otherwise it will block the next test
8794         stop mgs || error "stop mgs failed"
8795         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8796         $pass || error "test failed, see FAILED test_60a messages for specifics"
8797 }
8798 run_test 60a "llog_test run from kernel module and test llog_reader"
8799
8800 test_60b() { # bug 6411
8801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8802
8803         dmesg > $DIR/$tfile
8804         LLOG_COUNT=$(do_facet mgs dmesg |
8805                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8806                           /llog_[a-z]*.c:[0-9]/ {
8807                                 if (marker)
8808                                         from_marker++
8809                                 from_begin++
8810                           }
8811                           END {
8812                                 if (marker)
8813                                         print from_marker
8814                                 else
8815                                         print from_begin
8816                           }")
8817
8818         [[ $LLOG_COUNT -gt 120 ]] &&
8819                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8820 }
8821 run_test 60b "limit repeated messages from CERROR/CWARN"
8822
8823 test_60c() {
8824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8825
8826         echo "create 5000 files"
8827         createmany -o $DIR/f60c- 5000
8828 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8829         lctl set_param fail_loc=0x80000137
8830         unlinkmany $DIR/f60c- 5000
8831         lctl set_param fail_loc=0
8832 }
8833 run_test 60c "unlink file when mds full"
8834
8835 test_60d() {
8836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8837
8838         SAVEPRINTK=$(lctl get_param -n printk)
8839         # verify "lctl mark" is even working"
8840         MESSAGE="test message ID $RANDOM $$"
8841         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8842         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8843
8844         lctl set_param printk=0 || error "set lnet.printk failed"
8845         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8846         MESSAGE="new test message ID $RANDOM $$"
8847         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8848         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8849         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8850
8851         lctl set_param -n printk="$SAVEPRINTK"
8852 }
8853 run_test 60d "test printk console message masking"
8854
8855 test_60e() {
8856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8857         remote_mds_nodsh && skip "remote MDS with nodsh"
8858
8859         touch $DIR/$tfile
8860 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8861         do_facet mds1 lctl set_param fail_loc=0x15b
8862         rm $DIR/$tfile
8863 }
8864 run_test 60e "no space while new llog is being created"
8865
8866 test_60f() {
8867         local old_path=$($LCTL get_param -n debug_path)
8868
8869         stack_trap "$LCTL set_param debug_path=$old_path"
8870         stack_trap "rm -f $TMP/$tfile*"
8871         rm -f $TMP/$tfile* 2> /dev/null
8872         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8873         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8874         test_mkdir $DIR/$tdir
8875         # retry in case the open is cached and not released
8876         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8877                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8878                 sleep 0.1
8879         done
8880         ls $TMP/$tfile*
8881         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8882 }
8883 run_test 60f "change debug_path works"
8884
8885 test_60g() {
8886         local pid
8887         local i
8888
8889         test_mkdir -c $MDSCOUNT $DIR/$tdir
8890
8891         (
8892                 local index=0
8893                 while true; do
8894                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8895                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8896                                 2>/dev/null
8897                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8898                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8899                         index=$((index + 1))
8900                 done
8901         ) &
8902
8903         pid=$!
8904
8905         for i in {0..100}; do
8906                 # define OBD_FAIL_OSD_TXN_START    0x19a
8907                 local index=$((i % MDSCOUNT + 1))
8908
8909                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8910                         > /dev/null
8911                 sleep 0.01
8912         done
8913
8914         kill -9 $pid
8915
8916         for i in $(seq $MDSCOUNT); do
8917                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8918         done
8919
8920         mkdir $DIR/$tdir/new || error "mkdir failed"
8921         rmdir $DIR/$tdir/new || error "rmdir failed"
8922
8923         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8924                 -t namespace
8925         for i in $(seq $MDSCOUNT); do
8926                 wait_update_facet mds$i "$LCTL get_param -n \
8927                         mdd.$(facet_svc mds$i).lfsck_namespace |
8928                         awk '/^status/ { print \\\$2 }'" "completed"
8929         done
8930
8931         ls -R $DIR/$tdir
8932         rm -rf $DIR/$tdir || error "rmdir failed"
8933 }
8934 run_test 60g "transaction abort won't cause MDT hung"
8935
8936 test_60h() {
8937         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8938                 skip "Need MDS version at least 2.12.52"
8939         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8940
8941         local f
8942
8943         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8944         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8945         for fail_loc in 0x80000188 0x80000189; do
8946                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8947                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8948                         error "mkdir $dir-$fail_loc failed"
8949                 for i in {0..10}; do
8950                         # create may fail on missing stripe
8951                         echo $i > $DIR/$tdir-$fail_loc/$i
8952                 done
8953                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8954                         error "getdirstripe $tdir-$fail_loc failed"
8955                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8956                         error "migrate $tdir-$fail_loc failed"
8957                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8958                         error "getdirstripe $tdir-$fail_loc failed"
8959                 pushd $DIR/$tdir-$fail_loc
8960                 for f in *; do
8961                         echo $f | cmp $f - || error "$f data mismatch"
8962                 done
8963                 popd
8964                 rm -rf $DIR/$tdir-$fail_loc
8965         done
8966 }
8967 run_test 60h "striped directory with missing stripes can be accessed"
8968
8969 function t60i_load() {
8970         mkdir $DIR/$tdir
8971         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8972         $LCTL set_param fail_loc=0x131c fail_val=1
8973         for ((i=0; i<5000; i++)); do
8974                 touch $DIR/$tdir/f$i
8975         done
8976 }
8977
8978 test_60i() {
8979         changelog_register || error "changelog_register failed"
8980         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8981         changelog_users $SINGLEMDS | grep -q $cl_user ||
8982                 error "User $cl_user not found in changelog_users"
8983         changelog_chmask "ALL"
8984         t60i_load &
8985         local PID=$!
8986         for((i=0; i<100; i++)); do
8987                 changelog_dump >/dev/null ||
8988                         error "can't read changelog"
8989         done
8990         kill $PID
8991         wait $PID
8992         changelog_deregister || error "changelog_deregister failed"
8993         $LCTL set_param fail_loc=0
8994 }
8995 run_test 60i "llog: new record vs reader race"
8996
8997 test_60j() {
8998         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8999                 skip "need MDS version at least 2.15.50"
9000         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9001         remote_mds_nodsh && skip "remote MDS with nodsh"
9002         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9003
9004         changelog_users $SINGLEMDS | grep "^cl" &&
9005                 skip "active changelog user"
9006
9007         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9008
9009         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9010                 skip_env "missing llog_reader"
9011
9012         mkdir_on_mdt0 $DIR/$tdir
9013
9014         local f=$DIR/$tdir/$tfile
9015         local mdt_dev
9016         local tmpfile
9017         local plain
9018
9019         changelog_register || error "cannot register changelog user"
9020
9021         # set changelog_mask to ALL
9022         changelog_chmask "ALL"
9023         changelog_clear
9024
9025         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9026         unlinkmany ${f}- 100 || error "unlinkmany failed"
9027
9028         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9029         mdt_dev=$(facet_device $SINGLEMDS)
9030
9031         do_facet $SINGLEMDS sync
9032         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9033                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9034                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9035
9036         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9037
9038         # if $tmpfile is not on EXT3 filesystem for some reason
9039         [[ ${plain:0:1} == 'O' ]] ||
9040                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9041
9042         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9043                 $mdt_dev; stat -c %s $tmpfile")
9044         echo "Truncate llog from $size to $((size - size % 8192))"
9045         size=$((size - size % 8192))
9046         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9047         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9048                 grep -c 'in bitmap only')
9049         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9050
9051         size=$((size - 9000))
9052         echo "Corrupt llog in the middle at $size"
9053         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9054                 count=333 conv=notrunc
9055         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9056                 grep -c 'next chunk')
9057         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9058 }
9059 run_test 60j "llog_reader reports corruptions"
9060
9061 test_61a() {
9062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9063
9064         f="$DIR/f61"
9065         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9066         cancel_lru_locks osc
9067         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9068         sync
9069 }
9070 run_test 61a "mmap() writes don't make sync hang ================"
9071
9072 test_61b() {
9073         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9074 }
9075 run_test 61b "mmap() of unstriped file is successful"
9076
9077 # bug 2330 - insufficient obd_match error checking causes LBUG
9078 test_62() {
9079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9080
9081         f="$DIR/f62"
9082         echo foo > $f
9083         cancel_lru_locks osc
9084         lctl set_param fail_loc=0x405
9085         cat $f && error "cat succeeded, expect -EIO"
9086         lctl set_param fail_loc=0
9087 }
9088 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9089 # match every page all of the time.
9090 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9091
9092 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9093 # Though this test is irrelevant anymore, it helped to reveal some
9094 # other grant bugs (LU-4482), let's keep it.
9095 test_63a() {   # was test_63
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097
9098         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9099
9100         for i in `seq 10` ; do
9101                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9102                 sleep 5
9103                 kill $!
9104                 sleep 1
9105         done
9106
9107         rm -f $DIR/f63 || true
9108 }
9109 run_test 63a "Verify oig_wait interruption does not crash ======="
9110
9111 # bug 2248 - async write errors didn't return to application on sync
9112 # bug 3677 - async write errors left page locked
9113 test_63b() {
9114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9115
9116         debugsave
9117         lctl set_param debug=-1
9118
9119         # ensure we have a grant to do async writes
9120         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9121         rm $DIR/$tfile
9122
9123         sync    # sync lest earlier test intercept the fail_loc
9124
9125         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9126         lctl set_param fail_loc=0x80000406
9127         $MULTIOP $DIR/$tfile Owy && \
9128                 error "sync didn't return ENOMEM"
9129         sync; sleep 2; sync     # do a real sync this time to flush page
9130         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9131                 error "locked page left in cache after async error" || true
9132         debugrestore
9133 }
9134 run_test 63b "async write errors should be returned to fsync ==="
9135
9136 test_64a () {
9137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9138
9139         lfs df $DIR
9140         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9141 }
9142 run_test 64a "verify filter grant calculations (in kernel) ====="
9143
9144 test_64b () {
9145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9146
9147         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9148 }
9149 run_test 64b "check out-of-space detection on client"
9150
9151 test_64c() {
9152         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9153 }
9154 run_test 64c "verify grant shrink"
9155
9156 import_param() {
9157         local tgt=$1
9158         local param=$2
9159
9160         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9161 }
9162
9163 # this does exactly what osc_request.c:osc_announce_cached() does in
9164 # order to calculate max amount of grants to ask from server
9165 want_grant() {
9166         local tgt=$1
9167
9168         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9169         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9170
9171         ((rpc_in_flight++));
9172         nrpages=$((nrpages * rpc_in_flight))
9173
9174         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9175
9176         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9177
9178         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9179         local undirty=$((nrpages * PAGE_SIZE))
9180
9181         local max_extent_pages
9182         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9183         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9184         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9185         local grant_extent_tax
9186         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9187
9188         undirty=$((undirty + nrextents * grant_extent_tax))
9189
9190         echo $undirty
9191 }
9192
9193 # this is size of unit for grant allocation. It should be equal to
9194 # what tgt_grant.c:tgt_grant_chunk() calculates
9195 grant_chunk() {
9196         local tgt=$1
9197         local max_brw_size
9198         local grant_extent_tax
9199
9200         max_brw_size=$(import_param $tgt max_brw_size)
9201
9202         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9203
9204         echo $(((max_brw_size + grant_extent_tax) * 2))
9205 }
9206
9207 test_64d() {
9208         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9209                 skip "OST < 2.10.55 doesn't limit grants enough"
9210
9211         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9212
9213         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9214                 skip "no grant_param connect flag"
9215
9216         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9217
9218         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9219         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9220
9221
9222         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9223         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9224
9225         $LFS setstripe $DIR/$tfile -i 0 -c 1
9226         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9227         ddpid=$!
9228
9229         while kill -0 $ddpid; do
9230                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9231
9232                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9233                         kill $ddpid
9234                         error "cur_grant $cur_grant > $max_cur_granted"
9235                 fi
9236
9237                 sleep 1
9238         done
9239 }
9240 run_test 64d "check grant limit exceed"
9241
9242 check_grants() {
9243         local tgt=$1
9244         local expected=$2
9245         local msg=$3
9246         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9247
9248         ((cur_grants == expected)) ||
9249                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9250 }
9251
9252 round_up_p2() {
9253         echo $((($1 + $2 - 1) & ~($2 - 1)))
9254 }
9255
9256 test_64e() {
9257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9258         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9259                 skip "Need OSS version at least 2.11.56"
9260
9261         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9262         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9263         $LCTL set_param debug=+cache
9264
9265         # Remount client to reset grant
9266         remount_client $MOUNT || error "failed to remount client"
9267         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9268
9269         local init_grants=$(import_param $osc_tgt initial_grant)
9270
9271         check_grants $osc_tgt $init_grants "init grants"
9272
9273         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9274         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9275         local gbs=$(import_param $osc_tgt grant_block_size)
9276
9277         # write random number of bytes from max_brw_size / 4 to max_brw_size
9278         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9279         # align for direct io
9280         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9281         # round to grant consumption unit
9282         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9283
9284         local grants=$((wb_round_up + extent_tax))
9285
9286         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9287
9288         # define OBD_FAIL_TGT_NO_GRANT 0x725
9289         # make the server not grant more back
9290         do_facet ost1 $LCTL set_param fail_loc=0x725
9291         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9292
9293         do_facet ost1 $LCTL set_param fail_loc=0
9294
9295         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9296
9297         rm -f $DIR/$tfile || error "rm failed"
9298
9299         # Remount client to reset grant
9300         remount_client $MOUNT || error "failed to remount client"
9301         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9302
9303         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9304
9305         # define OBD_FAIL_TGT_NO_GRANT 0x725
9306         # make the server not grant more back
9307         do_facet ost1 $LCTL set_param fail_loc=0x725
9308         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9309         do_facet ost1 $LCTL set_param fail_loc=0
9310
9311         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9312 }
9313 run_test 64e "check grant consumption (no grant allocation)"
9314
9315 test_64f() {
9316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9317
9318         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9319         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9320         $LCTL set_param debug=+cache
9321
9322         # Remount client to reset grant
9323         remount_client $MOUNT || error "failed to remount client"
9324         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9325
9326         local init_grants=$(import_param $osc_tgt initial_grant)
9327         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9328         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9329         local gbs=$(import_param $osc_tgt grant_block_size)
9330         local chunk=$(grant_chunk $osc_tgt)
9331
9332         # write random number of bytes from max_brw_size / 4 to max_brw_size
9333         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9334         # align for direct io
9335         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9336         # round to grant consumption unit
9337         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9338
9339         local grants=$((wb_round_up + extent_tax))
9340
9341         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9342         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9343                 error "error writing to $DIR/$tfile"
9344
9345         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9346                 "direct io with grant allocation"
9347
9348         rm -f $DIR/$tfile || error "rm failed"
9349
9350         # Remount client to reset grant
9351         remount_client $MOUNT || error "failed to remount client"
9352         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9353
9354         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9355
9356         local cmd="oO_WRONLY:w${write_bytes}_yc"
9357
9358         $MULTIOP $DIR/$tfile $cmd &
9359         MULTIPID=$!
9360         sleep 1
9361
9362         check_grants $osc_tgt $((init_grants - grants)) \
9363                 "buffered io, not write rpc"
9364
9365         kill -USR1 $MULTIPID
9366         wait
9367
9368         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9369                 "buffered io, one RPC"
9370 }
9371 run_test 64f "check grant consumption (with grant allocation)"
9372
9373 test_64g() {
9374         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9375                 skip "Need MDS version at least 2.14.56"
9376
9377         local mdts=$(comma_list $(mdts_nodes))
9378
9379         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9380                         tr '\n' ' ')
9381         stack_trap "$LCTL set_param $old"
9382
9383         # generate dirty pages and increase dirty granted on MDT
9384         stack_trap "rm -f $DIR/$tfile-*"
9385         for (( i = 0; i < 10; i++)); do
9386                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9387                         error "can't set stripe"
9388                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9389                         error "can't dd"
9390                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9391                         $LFS getstripe $DIR/$tfile-$i
9392                         error "not DoM file"
9393                 }
9394         done
9395
9396         # flush dirty pages
9397         sync
9398
9399         # wait until grant shrink reset grant dirty on MDTs
9400         for ((i = 0; i < 120; i++)); do
9401                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9402                         awk '{sum=sum+$1} END {print sum}')
9403                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9404                 echo "$grant_dirty grants, $vm_dirty pages"
9405                 (( grant_dirty + vm_dirty == 0 )) && break
9406                 (( i == 3 )) && sync &&
9407                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9408                 sleep 1
9409         done
9410
9411         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9412                 awk '{sum=sum+$1} END {print sum}')
9413         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9414 }
9415 run_test 64g "grant shrink on MDT"
9416
9417 test_64h() {
9418         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9419                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9420
9421         local instance=$($LFS getname -i $DIR)
9422         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9423         local num_exps=$(do_facet ost1 \
9424             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9425         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9426         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9427         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9428
9429         # 10MiB is for file to be written, max_brw_size * 16 *
9430         # num_exps is space reserve so that tgt_grant_shrink() decided
9431         # to not shrink
9432         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9433         (( avail * 1024 < expect )) &&
9434                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9435
9436         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9437         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9438         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9439         $LCTL set_param osc.*OST0000*.grant_shrink=1
9440         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9441
9442         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9443         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9444
9445         # drop cache so that coming read would do rpc
9446         cancel_lru_locks osc
9447
9448         # shrink interval is set to 10, pause for 7 seconds so that
9449         # grant thread did not wake up yet but coming read entered
9450         # shrink mode for rpc (osc_should_shrink_grant())
9451         sleep 7
9452
9453         declare -a cur_grant_bytes
9454         declare -a tot_granted
9455         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9456         tot_granted[0]=$(do_facet ost1 \
9457             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9458
9459         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9460
9461         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9462         tot_granted[1]=$(do_facet ost1 \
9463             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9464
9465         # grant change should be equal on both sides
9466         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9467                 tot_granted[0] - tot_granted[1])) ||
9468                 error "grant change mismatch, "                                \
9469                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9470                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9471 }
9472 run_test 64h "grant shrink on read"
9473
9474 test_64i() {
9475         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9476                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9477
9478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9479         remote_ost_nodsh && skip "remote OSTs with nodsh"
9480
9481         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9482
9483         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9484
9485         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9486         local instance=$($LFS getname -i $DIR)
9487
9488         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9489         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9490
9491         # shrink grants and simulate rpc loss
9492         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9493         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9494         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9495
9496         fail ost1
9497
9498         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9499
9500         local testid=$(echo $TESTNAME | tr '_' ' ')
9501
9502         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9503                 grep "GRANT, real grant" &&
9504                 error "client has more grants then it owns" || true
9505 }
9506 run_test 64i "shrink on reconnect"
9507
9508 # bug 1414 - set/get directories' stripe info
9509 test_65a() {
9510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9511
9512         test_mkdir $DIR/$tdir
9513         touch $DIR/$tdir/f1
9514         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9515 }
9516 run_test 65a "directory with no stripe info"
9517
9518 test_65b() {
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520
9521         test_mkdir $DIR/$tdir
9522         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9523
9524         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9525                                                 error "setstripe"
9526         touch $DIR/$tdir/f2
9527         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9528 }
9529 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9530
9531 test_65c() {
9532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9533         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9534
9535         test_mkdir $DIR/$tdir
9536         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9537
9538         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9539                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9540         touch $DIR/$tdir/f3
9541         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9542 }
9543 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9544
9545 test_65d() {
9546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9547
9548         test_mkdir $DIR/$tdir
9549         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9550         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9551
9552         if [[ $STRIPECOUNT -le 0 ]]; then
9553                 sc=1
9554         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9555                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9556                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9557         else
9558                 sc=$(($STRIPECOUNT - 1))
9559         fi
9560         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9561         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9562         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9563                 error "lverify failed"
9564 }
9565 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9566
9567 test_65e() {
9568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9569
9570         test_mkdir $DIR/$tdir
9571
9572         $LFS setstripe $DIR/$tdir || error "setstripe"
9573         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9574                                         error "no stripe info failed"
9575         touch $DIR/$tdir/f6
9576         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9577 }
9578 run_test 65e "directory setstripe defaults"
9579
9580 test_65f() {
9581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9582
9583         test_mkdir $DIR/${tdir}f
9584         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9585                 error "setstripe succeeded" || true
9586 }
9587 run_test 65f "dir setstripe permission (should return error) ==="
9588
9589 test_65g() {
9590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9591
9592         test_mkdir $DIR/$tdir
9593         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9594
9595         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9596                 error "setstripe -S failed"
9597         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9598         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9599                 error "delete default stripe failed"
9600 }
9601 run_test 65g "directory setstripe -d"
9602
9603 test_65h() {
9604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9605
9606         test_mkdir $DIR/$tdir
9607         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9608
9609         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9610                 error "setstripe -S failed"
9611         test_mkdir $DIR/$tdir/dd1
9612         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9613                 error "stripe info inherit failed"
9614 }
9615 run_test 65h "directory stripe info inherit ===================="
9616
9617 test_65i() {
9618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9619
9620         save_layout_restore_at_exit $MOUNT
9621
9622         # bug6367: set non-default striping on root directory
9623         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9624
9625         # bug12836: getstripe on -1 default directory striping
9626         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9627
9628         # bug12836: getstripe -v on -1 default directory striping
9629         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9630
9631         # bug12836: new find on -1 default directory striping
9632         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9633 }
9634 run_test 65i "various tests to set root directory striping"
9635
9636 test_65j() { # bug6367
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638
9639         sync; sleep 1
9640
9641         # if we aren't already remounting for each test, do so for this test
9642         if [ "$I_MOUNTED" = "yes" ]; then
9643                 cleanup || error "failed to unmount"
9644                 setup
9645         fi
9646
9647         save_layout_restore_at_exit $MOUNT
9648
9649         $LFS setstripe -d $MOUNT || error "setstripe failed"
9650 }
9651 run_test 65j "set default striping on root directory (bug 6367)="
9652
9653 cleanup_65k() {
9654         rm -rf $DIR/$tdir
9655         wait_delete_completed
9656         do_facet $SINGLEMDS "lctl set_param -n \
9657                 osp.$ost*MDT0000.max_create_count=$max_count"
9658         do_facet $SINGLEMDS "lctl set_param -n \
9659                 osp.$ost*MDT0000.create_count=$count"
9660         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9661         echo $INACTIVE_OSC "is Activate"
9662
9663         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9664 }
9665
9666 test_65k() { # bug11679
9667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9668         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9669         remote_mds_nodsh && skip "remote MDS with nodsh"
9670
9671         local disable_precreate=true
9672         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9673                 disable_precreate=false
9674
9675         echo "Check OST status: "
9676         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9677                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9678
9679         for OSC in $MDS_OSCS; do
9680                 echo $OSC "is active"
9681                 do_facet $SINGLEMDS lctl --device %$OSC activate
9682         done
9683
9684         for INACTIVE_OSC in $MDS_OSCS; do
9685                 local ost=$(osc_to_ost $INACTIVE_OSC)
9686                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9687                                lov.*md*.target_obd |
9688                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9689
9690                 mkdir -p $DIR/$tdir
9691                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9692                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9693
9694                 echo "Deactivate: " $INACTIVE_OSC
9695                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9696
9697                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9698                               osp.$ost*MDT0000.create_count")
9699                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9700                                   osp.$ost*MDT0000.max_create_count")
9701                 $disable_precreate &&
9702                         do_facet $SINGLEMDS "lctl set_param -n \
9703                                 osp.$ost*MDT0000.max_create_count=0"
9704
9705                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9706                         [ -f $DIR/$tdir/$idx ] && continue
9707                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9708                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9709                                 { cleanup_65k;
9710                                   error "setstripe $idx should succeed"; }
9711                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9712                 done
9713                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9714                 rmdir $DIR/$tdir
9715
9716                 do_facet $SINGLEMDS "lctl set_param -n \
9717                         osp.$ost*MDT0000.max_create_count=$max_count"
9718                 do_facet $SINGLEMDS "lctl set_param -n \
9719                         osp.$ost*MDT0000.create_count=$count"
9720                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9721                 echo $INACTIVE_OSC "is Activate"
9722
9723                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9724         done
9725 }
9726 run_test 65k "validate manual striping works properly with deactivated OSCs"
9727
9728 test_65l() { # bug 12836
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730
9731         test_mkdir -p $DIR/$tdir/test_dir
9732         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9733         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9734 }
9735 run_test 65l "lfs find on -1 stripe dir ========================"
9736
9737 test_65m() {
9738         local layout=$(save_layout $MOUNT)
9739         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9740                 restore_layout $MOUNT $layout
9741                 error "setstripe should fail by non-root users"
9742         }
9743         true
9744 }
9745 run_test 65m "normal user can't set filesystem default stripe"
9746
9747 test_65n() {
9748         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9749         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9750                 skip "Need MDS version at least 2.12.50"
9751         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9752
9753         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9754         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9755         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9756
9757         save_layout_restore_at_exit $MOUNT
9758
9759         # new subdirectory under root directory should not inherit
9760         # the default layout from root
9761         local dir1=$MOUNT/$tdir-1
9762         mkdir $dir1 || error "mkdir $dir1 failed"
9763         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9764                 error "$dir1 shouldn't have LOV EA"
9765
9766         # delete the default layout on root directory
9767         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9768
9769         local dir2=$MOUNT/$tdir-2
9770         mkdir $dir2 || error "mkdir $dir2 failed"
9771         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9772                 error "$dir2 shouldn't have LOV EA"
9773
9774         # set a new striping pattern on root directory
9775         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9776         local new_def_stripe_size=$((def_stripe_size * 2))
9777         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9778                 error "set stripe size on $MOUNT failed"
9779
9780         # new file created in $dir2 should inherit the new stripe size from
9781         # the filesystem default
9782         local file2=$dir2/$tfile-2
9783         touch $file2 || error "touch $file2 failed"
9784
9785         local file2_stripe_size=$($LFS getstripe -S $file2)
9786         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9787         {
9788                 echo "file2_stripe_size: '$file2_stripe_size'"
9789                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9790                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9791         }
9792
9793         local dir3=$MOUNT/$tdir-3
9794         mkdir $dir3 || error "mkdir $dir3 failed"
9795         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9796         # the root layout, which is the actual default layout that will be used
9797         # when new files are created in $dir3.
9798         local dir3_layout=$(get_layout_param $dir3)
9799         local root_dir_layout=$(get_layout_param $MOUNT)
9800         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9801         {
9802                 echo "dir3_layout: '$dir3_layout'"
9803                 echo "root_dir_layout: '$root_dir_layout'"
9804                 error "$dir3 should show the default layout from $MOUNT"
9805         }
9806
9807         # set OST pool on root directory
9808         local pool=$TESTNAME
9809         pool_add $pool || error "add $pool failed"
9810         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9811                 error "add targets to $pool failed"
9812
9813         $LFS setstripe -p $pool $MOUNT ||
9814                 error "set OST pool on $MOUNT failed"
9815
9816         # new file created in $dir3 should inherit the pool from
9817         # the filesystem default
9818         local file3=$dir3/$tfile-3
9819         touch $file3 || error "touch $file3 failed"
9820
9821         local file3_pool=$($LFS getstripe -p $file3)
9822         [[ "$file3_pool" = "$pool" ]] ||
9823                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9824
9825         local dir4=$MOUNT/$tdir-4
9826         mkdir $dir4 || error "mkdir $dir4 failed"
9827         local dir4_layout=$(get_layout_param $dir4)
9828         root_dir_layout=$(get_layout_param $MOUNT)
9829         echo "$LFS getstripe -d $dir4"
9830         $LFS getstripe -d $dir4
9831         echo "$LFS getstripe -d $MOUNT"
9832         $LFS getstripe -d $MOUNT
9833         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9834         {
9835                 echo "dir4_layout: '$dir4_layout'"
9836                 echo "root_dir_layout: '$root_dir_layout'"
9837                 error "$dir4 should show the default layout from $MOUNT"
9838         }
9839
9840         # new file created in $dir4 should inherit the pool from
9841         # the filesystem default
9842         local file4=$dir4/$tfile-4
9843         touch $file4 || error "touch $file4 failed"
9844
9845         local file4_pool=$($LFS getstripe -p $file4)
9846         [[ "$file4_pool" = "$pool" ]] ||
9847                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9848
9849         # new subdirectory under non-root directory should inherit
9850         # the default layout from its parent directory
9851         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9852                 error "set directory layout on $dir4 failed"
9853
9854         local dir5=$dir4/$tdir-5
9855         mkdir $dir5 || error "mkdir $dir5 failed"
9856
9857         dir4_layout=$(get_layout_param $dir4)
9858         local dir5_layout=$(get_layout_param $dir5)
9859         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9860         {
9861                 echo "dir4_layout: '$dir4_layout'"
9862                 echo "dir5_layout: '$dir5_layout'"
9863                 error "$dir5 should inherit the default layout from $dir4"
9864         }
9865
9866         # though subdir under ROOT doesn't inherit default layout, but
9867         # its sub dir/file should be created with default layout.
9868         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9869         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9870                 skip "Need MDS version at least 2.12.59"
9871
9872         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9873         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9874         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9875
9876         if [ $default_lmv_hash == "none" ]; then
9877                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9878         else
9879                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9880                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9881         fi
9882
9883         $LFS setdirstripe -D -c 2 $MOUNT ||
9884                 error "setdirstripe -D -c 2 failed"
9885         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9886         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9887         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9888
9889         # $dir4 layout includes pool
9890         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9891         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9892                 error "pool lost on setstripe"
9893         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9894         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9895                 error "pool lost on compound layout setstripe"
9896 }
9897 run_test 65n "don't inherit default layout from root for new subdirectories"
9898
9899 test_65o() {
9900         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9901                 skip "need MDS version at least 2.14.57"
9902
9903         # set OST pool on root directory
9904         local pool=$TESTNAME
9905
9906         pool_add $pool || error "add $pool failed"
9907         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9908                 error "add targets to $pool failed"
9909
9910         local dir1=$MOUNT/$tdir
9911
9912         mkdir $dir1 || error "mkdir $dir1 failed"
9913
9914         # set a new striping pattern on root directory
9915         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9916
9917         $LFS setstripe -p $pool $dir1 ||
9918                 error "set directory layout on $dir1 failed"
9919
9920         # $dir1 layout includes pool
9921         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9922         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9923                 error "pool lost on setstripe"
9924         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9925         $LFS getstripe $dir1
9926         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9927                 error "pool lost on compound layout setstripe"
9928
9929         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9930                 error "setdirstripe failed on sub-dir with inherited pool"
9931         $LFS getstripe $dir1/dir2
9932         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9933                 error "pool lost on compound layout setdirstripe"
9934
9935         $LFS setstripe -E -1 -c 1 $dir1
9936         $LFS getstripe -d $dir1
9937         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9938                 error "pool lost on setstripe"
9939 }
9940 run_test 65o "pool inheritance for mdt component"
9941
9942 test_65p () { # LU-16152
9943         local src_dir=$DIR/$tdir/src_dir
9944         local dst_dir=$DIR/$tdir/dst_dir
9945         local yaml_file=$DIR/$tdir/layout.yaml
9946         local border
9947
9948         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9949                 skip "Need at least version 2.15.51"
9950
9951         test_mkdir -p $src_dir
9952         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9953                 error "failed to setstripe"
9954         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9955                 error "failed to getstripe"
9956
9957         test_mkdir -p $dst_dir
9958         $LFS setstripe --yaml $yaml_file $dst_dir ||
9959                 error "failed to setstripe with yaml file"
9960         border=$($LFS getstripe -d $dst_dir |
9961                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9962                 error "failed to getstripe"
9963
9964         # 2048M is 0x80000000, or 2147483648
9965         (( $border == 2147483648 )) ||
9966                 error "failed to handle huge number in yaml layout"
9967 }
9968 run_test 65p "setstripe with yaml file and huge number"
9969
9970 # bug 2543 - update blocks count on client
9971 test_66() {
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973
9974         local COUNT=${COUNT:-8}
9975         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9976         sync; sync_all_data; sync; sync_all_data
9977         cancel_lru_locks osc
9978         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9979         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9980 }
9981 run_test 66 "update inode blocks count on client ==============="
9982
9983 meminfo() {
9984         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9985 }
9986
9987 swap_used() {
9988         swapon -s | awk '($1 == "'$1'") { print $4 }'
9989 }
9990
9991 # bug5265, obdfilter oa2dentry return -ENOENT
9992 # #define OBD_FAIL_SRV_ENOENT 0x217
9993 test_69() {
9994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9995         remote_ost_nodsh && skip "remote OST with nodsh"
9996
9997         f="$DIR/$tfile"
9998         $LFS setstripe -c 1 -i 0 $f
9999
10000         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10001
10002         do_facet ost1 lctl set_param fail_loc=0x217
10003         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10004         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10005
10006         do_facet ost1 lctl set_param fail_loc=0
10007         $DIRECTIO write $f 0 2 || error "write error"
10008
10009         cancel_lru_locks osc
10010         $DIRECTIO read $f 0 1 || error "read error"
10011
10012         do_facet ost1 lctl set_param fail_loc=0x217
10013         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10014
10015         do_facet ost1 lctl set_param fail_loc=0
10016         rm -f $f
10017 }
10018 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10019
10020 test_71() {
10021         test_mkdir $DIR/$tdir
10022         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10023         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10024 }
10025 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10026
10027 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10029         [ "$RUNAS_ID" = "$UID" ] &&
10030                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10031         # Check that testing environment is properly set up. Skip if not
10032         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10033                 skip_env "User $RUNAS_ID does not exist - skipping"
10034
10035         touch $DIR/$tfile
10036         chmod 777 $DIR/$tfile
10037         chmod ug+s $DIR/$tfile
10038         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10039                 error "$RUNAS dd $DIR/$tfile failed"
10040         # See if we are still setuid/sgid
10041         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10042                 error "S/gid is not dropped on write"
10043         # Now test that MDS is updated too
10044         cancel_lru_locks mdc
10045         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10046                 error "S/gid is not dropped on MDS"
10047         rm -f $DIR/$tfile
10048 }
10049 run_test 72a "Test that remove suid works properly (bug5695) ===="
10050
10051 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10052         local perm
10053
10054         [ "$RUNAS_ID" = "$UID" ] &&
10055                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10056         [ "$RUNAS_ID" -eq 0 ] &&
10057                 skip_env "RUNAS_ID = 0 -- skipping"
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059         # Check that testing environment is properly set up. Skip if not
10060         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10061                 skip_env "User $RUNAS_ID does not exist - skipping"
10062
10063         touch $DIR/${tfile}-f{g,u}
10064         test_mkdir $DIR/${tfile}-dg
10065         test_mkdir $DIR/${tfile}-du
10066         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10067         chmod g+s $DIR/${tfile}-{f,d}g
10068         chmod u+s $DIR/${tfile}-{f,d}u
10069         for perm in 777 2777 4777; do
10070                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10071                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10072                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10073                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10074         done
10075         true
10076 }
10077 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10078
10079 # bug 3462 - multiple simultaneous MDC requests
10080 test_73() {
10081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10082
10083         test_mkdir $DIR/d73-1
10084         test_mkdir $DIR/d73-2
10085         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10086         pid1=$!
10087
10088         lctl set_param fail_loc=0x80000129
10089         $MULTIOP $DIR/d73-1/f73-2 Oc &
10090         sleep 1
10091         lctl set_param fail_loc=0
10092
10093         $MULTIOP $DIR/d73-2/f73-3 Oc &
10094         pid3=$!
10095
10096         kill -USR1 $pid1
10097         wait $pid1 || return 1
10098
10099         sleep 25
10100
10101         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10102         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10103         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10104
10105         rm -rf $DIR/d73-*
10106 }
10107 run_test 73 "multiple MDC requests (should not deadlock)"
10108
10109 test_74a() { # bug 6149, 6184
10110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10111
10112         touch $DIR/f74a
10113         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10114         #
10115         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10116         # will spin in a tight reconnection loop
10117         $LCTL set_param fail_loc=0x8000030e
10118         # get any lock that won't be difficult - lookup works.
10119         ls $DIR/f74a
10120         $LCTL set_param fail_loc=0
10121         rm -f $DIR/f74a
10122         true
10123 }
10124 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10125
10126 test_74b() { # bug 13310
10127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10128
10129         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10130         #
10131         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10132         # will spin in a tight reconnection loop
10133         $LCTL set_param fail_loc=0x8000030e
10134         # get a "difficult" lock
10135         touch $DIR/f74b
10136         $LCTL set_param fail_loc=0
10137         rm -f $DIR/f74b
10138         true
10139 }
10140 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10141
10142 test_74c() {
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144
10145         #define OBD_FAIL_LDLM_NEW_LOCK
10146         $LCTL set_param fail_loc=0x319
10147         touch $DIR/$tfile && error "touch successful"
10148         $LCTL set_param fail_loc=0
10149         true
10150 }
10151 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10152
10153 slab_lic=/sys/kernel/slab/lustre_inode_cache
10154 num_objects() {
10155         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10156         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10157                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10158 }
10159
10160 test_76a() { # Now for b=20433, added originally in b=1443
10161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10162
10163         cancel_lru_locks osc
10164         # there may be some slab objects cached per core
10165         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10166         local before=$(num_objects)
10167         local count=$((512 * cpus))
10168         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10169         local margin=$((count / 10))
10170         if [[ -f $slab_lic/aliases ]]; then
10171                 local aliases=$(cat $slab_lic/aliases)
10172                 (( aliases > 0 )) && margin=$((margin * aliases))
10173         fi
10174
10175         echo "before slab objects: $before"
10176         for i in $(seq $count); do
10177                 touch $DIR/$tfile
10178                 rm -f $DIR/$tfile
10179         done
10180         cancel_lru_locks osc
10181         local after=$(num_objects)
10182         echo "created: $count, after slab objects: $after"
10183         # shared slab counts are not very accurate, allow significant margin
10184         # the main goal is that the cache growth is not permanently > $count
10185         while (( after > before + margin )); do
10186                 sleep 1
10187                 after=$(num_objects)
10188                 wait=$((wait + 1))
10189                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10190                 if (( wait > 60 )); then
10191                         error "inode slab grew from $before+$margin to $after"
10192                 fi
10193         done
10194 }
10195 run_test 76a "confirm clients recycle inodes properly ===="
10196
10197 test_76b() {
10198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10199         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10200
10201         local count=512
10202         local before=$(num_objects)
10203
10204         for i in $(seq $count); do
10205                 mkdir $DIR/$tdir
10206                 rmdir $DIR/$tdir
10207         done
10208
10209         local after=$(num_objects)
10210         local wait=0
10211
10212         while (( after > before )); do
10213                 sleep 1
10214                 after=$(num_objects)
10215                 wait=$((wait + 1))
10216                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10217                 if (( wait > 60 )); then
10218                         error "inode slab grew from $before to $after"
10219                 fi
10220         done
10221
10222         echo "slab objects before: $before, after: $after"
10223 }
10224 run_test 76b "confirm clients recycle directory inodes properly ===="
10225
10226 export ORIG_CSUM=""
10227 set_checksums()
10228 {
10229         # Note: in sptlrpc modes which enable its own bulk checksum, the
10230         # original crc32_le bulk checksum will be automatically disabled,
10231         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10232         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10233         # In this case set_checksums() will not be no-op, because sptlrpc
10234         # bulk checksum will be enabled all through the test.
10235
10236         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10237         lctl set_param -n osc.*.checksums $1
10238         return 0
10239 }
10240
10241 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10242                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10243 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10244                              tr -d [] | head -n1)}
10245 set_checksum_type()
10246 {
10247         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10248         rc=$?
10249         log "set checksum type to $1, rc = $rc"
10250         return $rc
10251 }
10252
10253 get_osc_checksum_type()
10254 {
10255         # arugment 1: OST name, like OST0000
10256         ost=$1
10257         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10258                         sed 's/.*\[\(.*\)\].*/\1/g')
10259         rc=$?
10260         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10261         echo $checksum_type
10262 }
10263
10264 F77_TMP=$TMP/f77-temp
10265 F77SZ=8
10266 setup_f77() {
10267         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10268                 error "error writing to $F77_TMP"
10269 }
10270
10271 test_77a() { # bug 10889
10272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10273         $GSS && skip_env "could not run with gss"
10274
10275         [ ! -f $F77_TMP ] && setup_f77
10276         set_checksums 1
10277         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10278         set_checksums 0
10279         rm -f $DIR/$tfile
10280 }
10281 run_test 77a "normal checksum read/write operation"
10282
10283 test_77b() { # bug 10889
10284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10285         $GSS && skip_env "could not run with gss"
10286
10287         [ ! -f $F77_TMP ] && setup_f77
10288         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10289         $LCTL set_param fail_loc=0x80000409
10290         set_checksums 1
10291
10292         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10293                 error "dd error: $?"
10294         $LCTL set_param fail_loc=0
10295
10296         for algo in $CKSUM_TYPES; do
10297                 cancel_lru_locks osc
10298                 set_checksum_type $algo
10299                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10300                 $LCTL set_param fail_loc=0x80000408
10301                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10302                 $LCTL set_param fail_loc=0
10303         done
10304         set_checksums 0
10305         set_checksum_type $ORIG_CSUM_TYPE
10306         rm -f $DIR/$tfile
10307 }
10308 run_test 77b "checksum error on client write, read"
10309
10310 cleanup_77c() {
10311         trap 0
10312         set_checksums 0
10313         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10314         $check_ost &&
10315                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10316         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10317         $check_ost && [ -n "$ost_file_prefix" ] &&
10318                 do_facet ost1 rm -f ${ost_file_prefix}\*
10319 }
10320
10321 test_77c() {
10322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10323         $GSS && skip_env "could not run with gss"
10324         remote_ost_nodsh && skip "remote OST with nodsh"
10325
10326         local bad1
10327         local osc_file_prefix
10328         local osc_file
10329         local check_ost=false
10330         local ost_file_prefix
10331         local ost_file
10332         local orig_cksum
10333         local dump_cksum
10334         local fid
10335
10336         # ensure corruption will occur on first OSS/OST
10337         $LFS setstripe -i 0 $DIR/$tfile
10338
10339         [ ! -f $F77_TMP ] && setup_f77
10340         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10341                 error "dd write error: $?"
10342         fid=$($LFS path2fid $DIR/$tfile)
10343
10344         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10345         then
10346                 check_ost=true
10347                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10348                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10349         else
10350                 echo "OSS do not support bulk pages dump upon error"
10351         fi
10352
10353         osc_file_prefix=$($LCTL get_param -n debug_path)
10354         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10355
10356         trap cleanup_77c EXIT
10357
10358         set_checksums 1
10359         # enable bulk pages dump upon error on Client
10360         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10361         # enable bulk pages dump upon error on OSS
10362         $check_ost &&
10363                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10364
10365         # flush Client cache to allow next read to reach OSS
10366         cancel_lru_locks osc
10367
10368         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10369         $LCTL set_param fail_loc=0x80000408
10370         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10371         $LCTL set_param fail_loc=0
10372
10373         rm -f $DIR/$tfile
10374
10375         # check cksum dump on Client
10376         osc_file=$(ls ${osc_file_prefix}*)
10377         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10378         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10379         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10380         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10381         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10382                      cksum)
10383         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10384         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10385                 error "dump content does not match on Client"
10386
10387         $check_ost || skip "No need to check cksum dump on OSS"
10388
10389         # check cksum dump on OSS
10390         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10391         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10392         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10393         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10394         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10395                 error "dump content does not match on OSS"
10396
10397         cleanup_77c
10398 }
10399 run_test 77c "checksum error on client read with debug"
10400
10401 test_77d() { # bug 10889
10402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10403         $GSS && skip_env "could not run with gss"
10404
10405         stack_trap "rm -f $DIR/$tfile"
10406         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10407         $LCTL set_param fail_loc=0x80000409
10408         set_checksums 1
10409         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10410                 error "direct write: rc=$?"
10411         $LCTL set_param fail_loc=0
10412         set_checksums 0
10413
10414         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10415         $LCTL set_param fail_loc=0x80000408
10416         set_checksums 1
10417         cancel_lru_locks osc
10418         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10419                 error "direct read: rc=$?"
10420         $LCTL set_param fail_loc=0
10421         set_checksums 0
10422 }
10423 run_test 77d "checksum error on OST direct write, read"
10424
10425 test_77f() { # bug 10889
10426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10427         $GSS && skip_env "could not run with gss"
10428
10429         set_checksums 1
10430         stack_trap "rm -f $DIR/$tfile"
10431         for algo in $CKSUM_TYPES; do
10432                 cancel_lru_locks osc
10433                 set_checksum_type $algo
10434                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10435                 $LCTL set_param fail_loc=0x409
10436                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10437                         error "direct write succeeded"
10438                 $LCTL set_param fail_loc=0
10439         done
10440         set_checksum_type $ORIG_CSUM_TYPE
10441         set_checksums 0
10442 }
10443 run_test 77f "repeat checksum error on write (expect error)"
10444
10445 test_77g() { # bug 10889
10446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10447         $GSS && skip_env "could not run with gss"
10448         remote_ost_nodsh && skip "remote OST with nodsh"
10449
10450         [ ! -f $F77_TMP ] && setup_f77
10451
10452         local file=$DIR/$tfile
10453         stack_trap "rm -f $file" EXIT
10454
10455         $LFS setstripe -c 1 -i 0 $file
10456         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10457         do_facet ost1 lctl set_param fail_loc=0x8000021a
10458         set_checksums 1
10459         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10460                 error "write error: rc=$?"
10461         do_facet ost1 lctl set_param fail_loc=0
10462         set_checksums 0
10463
10464         cancel_lru_locks osc
10465         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10466         do_facet ost1 lctl set_param fail_loc=0x8000021b
10467         set_checksums 1
10468         cmp $F77_TMP $file || error "file compare failed"
10469         do_facet ost1 lctl set_param fail_loc=0
10470         set_checksums 0
10471 }
10472 run_test 77g "checksum error on OST write, read"
10473
10474 test_77k() { # LU-10906
10475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10476         $GSS && skip_env "could not run with gss"
10477
10478         local cksum_param="osc.$FSNAME*.checksums"
10479         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10480         local checksum
10481         local i
10482
10483         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10484         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10485         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10486
10487         for i in 0 1; do
10488                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10489                         error "failed to set checksum=$i on MGS"
10490                 wait_update $HOSTNAME "$get_checksum" $i
10491                 #remount
10492                 echo "remount client, checksum should be $i"
10493                 remount_client $MOUNT || error "failed to remount client"
10494                 checksum=$(eval $get_checksum)
10495                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10496         done
10497         # remove persistent param to avoid races with checksum mountopt below
10498         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10499                 error "failed to delete checksum on MGS"
10500
10501         for opt in "checksum" "nochecksum"; do
10502                 #remount with mount option
10503                 echo "remount client with option $opt, checksum should be $i"
10504                 umount_client $MOUNT || error "failed to umount client"
10505                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10506                         error "failed to mount client with option '$opt'"
10507                 checksum=$(eval $get_checksum)
10508                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10509                 i=$((i - 1))
10510         done
10511
10512         remount_client $MOUNT || error "failed to remount client"
10513 }
10514 run_test 77k "enable/disable checksum correctly"
10515
10516 test_77l() {
10517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10518         $GSS && skip_env "could not run with gss"
10519
10520         set_checksums 1
10521         stack_trap "set_checksums $ORIG_CSUM" EXIT
10522         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10523
10524         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10525
10526         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10527         for algo in $CKSUM_TYPES; do
10528                 set_checksum_type $algo || error "fail to set checksum type $algo"
10529                 osc_algo=$(get_osc_checksum_type OST0000)
10530                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10531
10532                 # no locks, no reqs to let the connection idle
10533                 cancel_lru_locks osc
10534                 lru_resize_disable osc
10535                 wait_osc_import_state client ost1 IDLE
10536
10537                 # ensure ost1 is connected
10538                 stat $DIR/$tfile >/dev/null || error "can't stat"
10539                 wait_osc_import_state client ost1 FULL
10540
10541                 osc_algo=$(get_osc_checksum_type OST0000)
10542                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10543         done
10544         return 0
10545 }
10546 run_test 77l "preferred checksum type is remembered after reconnected"
10547
10548 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10549 rm -f $F77_TMP
10550 unset F77_TMP
10551
10552 test_77m() {
10553         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10554                 skip "Need at least version 2.14.52"
10555         local param=checksum_speed
10556
10557         $LCTL get_param $param || error "reading $param failed"
10558
10559         csum_speeds=$($LCTL get_param -n $param)
10560
10561         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10562                 error "known checksum types are missing"
10563 }
10564 run_test 77m "Verify checksum_speed is correctly read"
10565
10566 check_filefrag_77n() {
10567         local nr_ext=0
10568         local starts=()
10569         local ends=()
10570
10571         while read extidx a b start end rest; do
10572                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10573                         nr_ext=$(( $nr_ext + 1 ))
10574                         starts+=( ${start%..} )
10575                         ends+=( ${end%:} )
10576                 fi
10577         done < <( filefrag -sv $1 )
10578
10579         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10580         return 1
10581 }
10582
10583 test_77n() {
10584         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10585
10586         touch $DIR/$tfile
10587         $TRUNCATE $DIR/$tfile 0
10588         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10589         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10590         check_filefrag_77n $DIR/$tfile ||
10591                 skip "$tfile blocks not contiguous around hole"
10592
10593         set_checksums 1
10594         stack_trap "set_checksums $ORIG_CSUM" EXIT
10595         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10596         stack_trap "rm -f $DIR/$tfile"
10597
10598         for algo in $CKSUM_TYPES; do
10599                 if [[ "$algo" =~ ^t10 ]]; then
10600                         set_checksum_type $algo ||
10601                                 error "fail to set checksum type $algo"
10602                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10603                                 error "fail to read $tfile with $algo"
10604                 fi
10605         done
10606         rm -f $DIR/$tfile
10607         return 0
10608 }
10609 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10610
10611 test_77o() {
10612         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10613                 skip "Need MDS version at least 2.14.55"
10614         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10615                 skip "Need OST version at least 2.14.55"
10616         local ofd=obdfilter
10617         local mdt=mdt
10618
10619         # print OST checksum_type
10620         echo "$ofd.$FSNAME-*.checksum_type:"
10621         do_nodes $(comma_list $(osts_nodes)) \
10622                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10623
10624         # print MDT checksum_type
10625         echo "$mdt.$FSNAME-*.checksum_type:"
10626         do_nodes $(comma_list $(mdts_nodes)) \
10627                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10628
10629         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10630                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10631
10632         (( $o_count == $OSTCOUNT )) ||
10633                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10634
10635         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10636                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10637
10638         (( $m_count == $MDSCOUNT )) ||
10639                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10640 }
10641 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10642
10643 cleanup_test_78() {
10644         trap 0
10645         rm -f $DIR/$tfile
10646 }
10647
10648 test_78() { # bug 10901
10649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10650         remote_ost || skip_env "local OST"
10651
10652         NSEQ=5
10653         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10654         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10655         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10656         echo "MemTotal: $MEMTOTAL"
10657
10658         # reserve 256MB of memory for the kernel and other running processes,
10659         # and then take 1/2 of the remaining memory for the read/write buffers.
10660         if [ $MEMTOTAL -gt 512 ] ;then
10661                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10662         else
10663                 # for those poor memory-starved high-end clusters...
10664                 MEMTOTAL=$((MEMTOTAL / 2))
10665         fi
10666         echo "Mem to use for directio: $MEMTOTAL"
10667
10668         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10669         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10670         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10671         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10672                 head -n1)
10673         echo "Smallest OST: $SMALLESTOST"
10674         [[ $SMALLESTOST -lt 10240 ]] &&
10675                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10676
10677         trap cleanup_test_78 EXIT
10678
10679         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10680                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10681
10682         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10683         echo "File size: $F78SIZE"
10684         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10685         for i in $(seq 1 $NSEQ); do
10686                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10687                 echo directIO rdwr round $i of $NSEQ
10688                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10689         done
10690
10691         cleanup_test_78
10692 }
10693 run_test 78 "handle large O_DIRECT writes correctly ============"
10694
10695 test_79() { # bug 12743
10696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10697
10698         wait_delete_completed
10699
10700         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10701         BKFREE=$(calc_osc_kbytes kbytesfree)
10702         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10703
10704         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10705         DFTOTAL=`echo $STRING | cut -d, -f1`
10706         DFUSED=`echo $STRING  | cut -d, -f2`
10707         DFAVAIL=`echo $STRING | cut -d, -f3`
10708         DFFREE=$(($DFTOTAL - $DFUSED))
10709
10710         ALLOWANCE=$((64 * $OSTCOUNT))
10711
10712         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10713            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10714                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10715         fi
10716         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10717            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10718                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10719         fi
10720         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10721            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10722                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10723         fi
10724 }
10725 run_test 79 "df report consistency check ======================="
10726
10727 test_80() { # bug 10718
10728         remote_ost_nodsh && skip "remote OST with nodsh"
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730
10731         # relax strong synchronous semantics for slow backends like ZFS
10732         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10733                 local soc="obdfilter.*.sync_lock_cancel"
10734                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10735
10736                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10737                 if [ -z "$save" ]; then
10738                         soc="obdfilter.*.sync_on_lock_cancel"
10739                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10740                 fi
10741
10742                 if [ "$save" != "never" ]; then
10743                         local hosts=$(comma_list $(osts_nodes))
10744
10745                         do_nodes $hosts $LCTL set_param $soc=never
10746                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10747                 fi
10748         fi
10749
10750         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10751         sync; sleep 1; sync
10752         local before=$(date +%s)
10753         cancel_lru_locks osc
10754         local after=$(date +%s)
10755         local diff=$((after - before))
10756         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10757
10758         rm -f $DIR/$tfile
10759 }
10760 run_test 80 "Page eviction is equally fast at high offsets too"
10761
10762 test_81a() { # LU-456
10763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10764         remote_ost_nodsh && skip "remote OST with nodsh"
10765
10766         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10767         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10768         do_facet ost1 lctl set_param fail_loc=0x80000228
10769
10770         # write should trigger a retry and success
10771         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10772         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10773         RC=$?
10774         if [ $RC -ne 0 ] ; then
10775                 error "write should success, but failed for $RC"
10776         fi
10777 }
10778 run_test 81a "OST should retry write when get -ENOSPC ==============="
10779
10780 test_81b() { # LU-456
10781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10782         remote_ost_nodsh && skip "remote OST with nodsh"
10783
10784         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10785         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10786         do_facet ost1 lctl set_param fail_loc=0x228
10787
10788         # write should retry several times and return -ENOSPC finally
10789         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10790         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10791         RC=$?
10792         ENOSPC=28
10793         if [ $RC -ne $ENOSPC ] ; then
10794                 error "dd should fail for -ENOSPC, but succeed."
10795         fi
10796 }
10797 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10798
10799 test_99() {
10800         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10801
10802         test_mkdir $DIR/$tdir.cvsroot
10803         chown $RUNAS_ID $DIR/$tdir.cvsroot
10804
10805         cd $TMP
10806         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10807
10808         cd /etc/init.d
10809         # some versions of cvs import exit(1) when asked to import links or
10810         # files they can't read.  ignore those files.
10811         local toignore=$(find . -type l -printf '-I %f\n' -o \
10812                          ! -perm /4 -printf '-I %f\n')
10813         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10814                 $tdir.reposname vtag rtag
10815
10816         cd $DIR
10817         test_mkdir $DIR/$tdir.reposname
10818         chown $RUNAS_ID $DIR/$tdir.reposname
10819         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10820
10821         cd $DIR/$tdir.reposname
10822         $RUNAS touch foo99
10823         $RUNAS cvs add -m 'addmsg' foo99
10824         $RUNAS cvs update
10825         $RUNAS cvs commit -m 'nomsg' foo99
10826         rm -fr $DIR/$tdir.cvsroot
10827 }
10828 run_test 99 "cvs strange file/directory operations"
10829
10830 test_100() {
10831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10832         [[ "$NETTYPE" =~ tcp ]] ||
10833                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10834         remote_ost_nodsh && skip "remote OST with nodsh"
10835         remote_mds_nodsh && skip "remote MDS with nodsh"
10836         remote_servers ||
10837                 skip "useless for local single node setup"
10838
10839         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10840                 [ "$PROT" != "tcp" ] && continue
10841                 RPORT=$(echo $REMOTE | cut -d: -f2)
10842                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10843
10844                 rc=0
10845                 LPORT=`echo $LOCAL | cut -d: -f2`
10846                 if [ $LPORT -ge 1024 ]; then
10847                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10848                         netstat -tna
10849                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10850                 fi
10851         done
10852         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10853 }
10854 run_test 100 "check local port using privileged port ==========="
10855
10856 function get_named_value()
10857 {
10858     local tag=$1
10859
10860     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10861 }
10862
10863 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10864                    awk '/^max_cached_mb/ { print $2 }')
10865
10866 cleanup_101a() {
10867         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10868         trap 0
10869 }
10870
10871 test_101a() {
10872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10873
10874         local s
10875         local discard
10876         local nreads=10000
10877         local cache_limit=32
10878
10879         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10880         trap cleanup_101a EXIT
10881         $LCTL set_param -n llite.*.read_ahead_stats=0
10882         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10883
10884         #
10885         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10886         #
10887         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10888         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10889
10890         discard=0
10891         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10892                    get_named_value 'read.but.discarded'); do
10893                         discard=$(($discard + $s))
10894         done
10895         cleanup_101a
10896
10897         $LCTL get_param osc.*-osc*.rpc_stats
10898         $LCTL get_param llite.*.read_ahead_stats
10899
10900         # Discard is generally zero, but sometimes a few random reads line up
10901         # and trigger larger readahead, which is wasted & leads to discards.
10902         if [[ $(($discard)) -gt $nreads ]]; then
10903                 error "too many ($discard) discarded pages"
10904         fi
10905         rm -f $DIR/$tfile || true
10906 }
10907 run_test 101a "check read-ahead for random reads"
10908
10909 setup_test101bc() {
10910         test_mkdir $DIR/$tdir
10911         local ssize=$1
10912         local FILE_LENGTH=$2
10913         STRIPE_OFFSET=0
10914
10915         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10916
10917         local list=$(comma_list $(osts_nodes))
10918         set_osd_param $list '' read_cache_enable 0
10919         set_osd_param $list '' writethrough_cache_enable 0
10920
10921         trap cleanup_test101bc EXIT
10922         # prepare the read-ahead file
10923         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10924
10925         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10926                                 count=$FILE_SIZE_MB 2> /dev/null
10927
10928 }
10929
10930 cleanup_test101bc() {
10931         trap 0
10932         rm -rf $DIR/$tdir
10933         rm -f $DIR/$tfile
10934
10935         local list=$(comma_list $(osts_nodes))
10936         set_osd_param $list '' read_cache_enable 1
10937         set_osd_param $list '' writethrough_cache_enable 1
10938 }
10939
10940 calc_total() {
10941         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10942 }
10943
10944 ra_check_101() {
10945         local read_size=$1
10946         local stripe_size=$2
10947         local stride_length=$((stripe_size / read_size))
10948         local stride_width=$((stride_length * OSTCOUNT))
10949         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10950                                 (stride_width - stride_length) ))
10951         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10952                   get_named_value 'read.but.discarded' | calc_total)
10953
10954         if [[ $discard -gt $discard_limit ]]; then
10955                 $LCTL get_param llite.*.read_ahead_stats
10956                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10957         else
10958                 echo "Read-ahead success for size ${read_size}"
10959         fi
10960 }
10961
10962 test_101b() {
10963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10965
10966         local STRIPE_SIZE=1048576
10967         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10968
10969         if [ $SLOW == "yes" ]; then
10970                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10971         else
10972                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10973         fi
10974
10975         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10976
10977         # prepare the read-ahead file
10978         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10979         cancel_lru_locks osc
10980         for BIDX in 2 4 8 16 32 64 128 256
10981         do
10982                 local BSIZE=$((BIDX*4096))
10983                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10984                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10985                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10986                 $LCTL set_param -n llite.*.read_ahead_stats=0
10987                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10988                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10989                 cancel_lru_locks osc
10990                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10991         done
10992         cleanup_test101bc
10993         true
10994 }
10995 run_test 101b "check stride-io mode read-ahead ================="
10996
10997 test_101c() {
10998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10999
11000         local STRIPE_SIZE=1048576
11001         local FILE_LENGTH=$((STRIPE_SIZE*100))
11002         local nreads=10000
11003         local rsize=65536
11004         local osc_rpc_stats
11005
11006         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11007
11008         cancel_lru_locks osc
11009         $LCTL set_param osc.*.rpc_stats=0
11010         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11011         $LCTL get_param osc.*.rpc_stats
11012         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11013                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11014                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11015                 local size
11016
11017                 if [ $lines -le 20 ]; then
11018                         echo "continue debug"
11019                         continue
11020                 fi
11021                 for size in 1 2 4 8; do
11022                         local rpc=$(echo "$stats" |
11023                                     awk '($1 == "'$size':") {print $2; exit; }')
11024                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11025                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11026                 done
11027                 echo "$osc_rpc_stats check passed!"
11028         done
11029         cleanup_test101bc
11030         true
11031 }
11032 run_test 101c "check stripe_size aligned read-ahead"
11033
11034 test_101d() {
11035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11036
11037         local file=$DIR/$tfile
11038         local sz_MB=${FILESIZE_101d:-80}
11039         local ra_MB=${READAHEAD_MB:-40}
11040
11041         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11042         [ $free_MB -lt $sz_MB ] &&
11043                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11044
11045         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11046         $LFS setstripe -c -1 $file || error "setstripe failed"
11047
11048         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11049         echo Cancel LRU locks on lustre client to flush the client cache
11050         cancel_lru_locks osc
11051
11052         echo Disable read-ahead
11053         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11054         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11055         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11056         $LCTL get_param -n llite.*.max_read_ahead_mb
11057
11058         echo "Reading the test file $file with read-ahead disabled"
11059         local sz_KB=$((sz_MB * 1024 / 4))
11060         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11061         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11062         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11063                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11064
11065         echo "Cancel LRU locks on lustre client to flush the client cache"
11066         cancel_lru_locks osc
11067         echo Enable read-ahead with ${ra_MB}MB
11068         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11069
11070         echo "Reading the test file $file with read-ahead enabled"
11071         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11072                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11073
11074         echo "read-ahead disabled time read $raOFF"
11075         echo "read-ahead enabled time read $raON"
11076
11077         rm -f $file
11078         wait_delete_completed
11079
11080         # use awk for this check instead of bash because it handles decimals
11081         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11082                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11083 }
11084 run_test 101d "file read with and without read-ahead enabled"
11085
11086 test_101e() {
11087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11088
11089         local file=$DIR/$tfile
11090         local size_KB=500  #KB
11091         local count=100
11092         local bsize=1024
11093
11094         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11095         local need_KB=$((count * size_KB))
11096         [[ $free_KB -le $need_KB ]] &&
11097                 skip_env "Need free space $need_KB, have $free_KB"
11098
11099         echo "Creating $count ${size_KB}K test files"
11100         for ((i = 0; i < $count; i++)); do
11101                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11102         done
11103
11104         echo "Cancel LRU locks on lustre client to flush the client cache"
11105         cancel_lru_locks $OSC
11106
11107         echo "Reset readahead stats"
11108         $LCTL set_param -n llite.*.read_ahead_stats=0
11109
11110         for ((i = 0; i < $count; i++)); do
11111                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11112         done
11113
11114         $LCTL get_param llite.*.max_cached_mb
11115         $LCTL get_param llite.*.read_ahead_stats
11116         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11117                      get_named_value 'misses' | calc_total)
11118
11119         for ((i = 0; i < $count; i++)); do
11120                 rm -rf $file.$i 2>/dev/null
11121         done
11122
11123         #10000 means 20% reads are missing in readahead
11124         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11125 }
11126 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11127
11128 test_101f() {
11129         which iozone || skip_env "no iozone installed"
11130
11131         local old_debug=$($LCTL get_param debug)
11132         old_debug=${old_debug#*=}
11133         $LCTL set_param debug="reada mmap"
11134
11135         # create a test file
11136         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11137
11138         echo Cancel LRU locks on lustre client to flush the client cache
11139         cancel_lru_locks osc
11140
11141         echo Reset readahead stats
11142         $LCTL set_param -n llite.*.read_ahead_stats=0
11143
11144         echo mmap read the file with small block size
11145         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11146                 > /dev/null 2>&1
11147
11148         echo checking missing pages
11149         $LCTL get_param llite.*.read_ahead_stats
11150         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11151                         get_named_value 'misses' | calc_total)
11152
11153         $LCTL set_param debug="$old_debug"
11154         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11155         rm -f $DIR/$tfile
11156 }
11157 run_test 101f "check mmap read performance"
11158
11159 test_101g_brw_size_test() {
11160         local mb=$1
11161         local pages=$((mb * 1048576 / PAGE_SIZE))
11162         local file=$DIR/$tfile
11163
11164         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11165                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11166         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11167                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11168                         return 2
11169         done
11170
11171         stack_trap "rm -f $file" EXIT
11172         $LCTL set_param -n osc.*.rpc_stats=0
11173
11174         # 10 RPCs should be enough for the test
11175         local count=10
11176         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11177                 { error "dd write ${mb} MB blocks failed"; return 3; }
11178         cancel_lru_locks osc
11179         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11180                 { error "dd write ${mb} MB blocks failed"; return 4; }
11181
11182         # calculate number of full-sized read and write RPCs
11183         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11184                 sed -n '/pages per rpc/,/^$/p' |
11185                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11186                 END { print reads,writes }'))
11187         # allow one extra full-sized read RPC for async readahead
11188         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11189                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11190         [[ ${rpcs[1]} == $count ]] ||
11191                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11192 }
11193
11194 test_101g() {
11195         remote_ost_nodsh && skip "remote OST with nodsh"
11196
11197         local rpcs
11198         local osts=$(get_facets OST)
11199         local list=$(comma_list $(osts_nodes))
11200         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11201         local brw_size="obdfilter.*.brw_size"
11202
11203         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11204
11205         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11206
11207         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11208                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11209                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11210            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11211                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11212                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11213
11214                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11215                         suffix="M"
11216
11217                 if [[ $orig_mb -lt 16 ]]; then
11218                         save_lustre_params $osts "$brw_size" > $p
11219                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11220                                 error "set 16MB RPC size failed"
11221
11222                         echo "remount client to enable new RPC size"
11223                         remount_client $MOUNT || error "remount_client failed"
11224                 fi
11225
11226                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11227                 # should be able to set brw_size=12, but no rpc_stats for that
11228                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11229         fi
11230
11231         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11232
11233         if [[ $orig_mb -lt 16 ]]; then
11234                 restore_lustre_params < $p
11235                 remount_client $MOUNT || error "remount_client restore failed"
11236         fi
11237
11238         rm -f $p $DIR/$tfile
11239 }
11240 run_test 101g "Big bulk(4/16 MiB) readahead"
11241
11242 test_101h() {
11243         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11244
11245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11246                 error "dd 70M file failed"
11247         echo Cancel LRU locks on lustre client to flush the client cache
11248         cancel_lru_locks osc
11249
11250         echo "Reset readahead stats"
11251         $LCTL set_param -n llite.*.read_ahead_stats 0
11252
11253         echo "Read 10M of data but cross 64M bundary"
11254         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11255         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11256                      get_named_value 'misses' | calc_total)
11257         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11258         rm -f $p $DIR/$tfile
11259 }
11260 run_test 101h "Readahead should cover current read window"
11261
11262 test_101i() {
11263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11264                 error "dd 10M file failed"
11265
11266         local max_per_file_mb=$($LCTL get_param -n \
11267                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11268         cancel_lru_locks osc
11269         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11270         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11271                 error "set max_read_ahead_per_file_mb to 1 failed"
11272
11273         echo "Reset readahead stats"
11274         $LCTL set_param llite.*.read_ahead_stats=0
11275
11276         dd if=$DIR/$tfile of=/dev/null bs=2M
11277
11278         $LCTL get_param llite.*.read_ahead_stats
11279         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11280                      awk '/misses/ { print $2 }')
11281         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11282         rm -f $DIR/$tfile
11283 }
11284 run_test 101i "allow current readahead to exceed reservation"
11285
11286 test_101j() {
11287         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11288                 error "setstripe $DIR/$tfile failed"
11289         local file_size=$((1048576 * 16))
11290         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11291         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11292
11293         echo Disable read-ahead
11294         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11295
11296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11297         for blk in $PAGE_SIZE 1048576 $file_size; do
11298                 cancel_lru_locks osc
11299                 echo "Reset readahead stats"
11300                 $LCTL set_param -n llite.*.read_ahead_stats=0
11301                 local count=$(($file_size / $blk))
11302                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11303                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11304                              get_named_value 'failed.to.fast.read' | calc_total)
11305                 $LCTL get_param -n llite.*.read_ahead_stats
11306                 [ $miss -eq $count ] || error "expected $count got $miss"
11307         done
11308
11309         rm -f $p $DIR/$tfile
11310 }
11311 run_test 101j "A complete read block should be submitted when no RA"
11312
11313 test_101k()
11314 {
11315         local file=$DIR/$tfile
11316
11317         check_set_fallocate_or_skip
11318
11319         $LCTL set_param -n llite.*.read_ahead_stats=0
11320         fallocate -l 16K $file || error "failed to fallocate $file"
11321         cancel_lru_locks osc
11322         $MULTIOP $file or1048576c
11323         $LCTL get_param llite.*.read_ahead_stats
11324 }
11325 run_test 101k "read ahead for small file"
11326
11327 setup_test102() {
11328         test_mkdir $DIR/$tdir
11329         chown $RUNAS_ID $DIR/$tdir
11330         STRIPE_SIZE=65536
11331         STRIPE_OFFSET=1
11332         STRIPE_COUNT=$OSTCOUNT
11333         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11334
11335         trap cleanup_test102 EXIT
11336         cd $DIR
11337         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11338         cd $DIR/$tdir
11339         for num in 1 2 3 4; do
11340                 for count in $(seq 1 $STRIPE_COUNT); do
11341                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11342                                 local size=`expr $STRIPE_SIZE \* $num`
11343                                 local file=file"$num-$idx-$count"
11344                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11345                         done
11346                 done
11347         done
11348
11349         cd $DIR
11350         $1 tar cf $TMP/f102.tar $tdir --xattrs
11351 }
11352
11353 cleanup_test102() {
11354         trap 0
11355         rm -f $TMP/f102.tar
11356         rm -rf $DIR/d0.sanity/d102
11357 }
11358
11359 test_102a() {
11360         [ "$UID" != 0 ] && skip "must run as root"
11361         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11362                 skip_env "must have user_xattr"
11363
11364         [ -z "$(which setfattr 2>/dev/null)" ] &&
11365                 skip_env "could not find setfattr"
11366
11367         local testfile=$DIR/$tfile
11368
11369         touch $testfile
11370         echo "set/get xattr..."
11371         setfattr -n trusted.name1 -v value1 $testfile ||
11372                 error "setfattr -n trusted.name1=value1 $testfile failed"
11373         getfattr -n trusted.name1 $testfile 2> /dev/null |
11374           grep "trusted.name1=.value1" ||
11375                 error "$testfile missing trusted.name1=value1"
11376
11377         setfattr -n user.author1 -v author1 $testfile ||
11378                 error "setfattr -n user.author1=author1 $testfile failed"
11379         getfattr -n user.author1 $testfile 2> /dev/null |
11380           grep "user.author1=.author1" ||
11381                 error "$testfile missing trusted.author1=author1"
11382
11383         echo "listxattr..."
11384         setfattr -n trusted.name2 -v value2 $testfile ||
11385                 error "$testfile unable to set trusted.name2"
11386         setfattr -n trusted.name3 -v value3 $testfile ||
11387                 error "$testfile unable to set trusted.name3"
11388         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11389             grep "trusted.name" | wc -l) -eq 3 ] ||
11390                 error "$testfile missing 3 trusted.name xattrs"
11391
11392         setfattr -n user.author2 -v author2 $testfile ||
11393                 error "$testfile unable to set user.author2"
11394         setfattr -n user.author3 -v author3 $testfile ||
11395                 error "$testfile unable to set user.author3"
11396         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11397             grep "user.author" | wc -l) -eq 3 ] ||
11398                 error "$testfile missing 3 user.author xattrs"
11399
11400         echo "remove xattr..."
11401         setfattr -x trusted.name1 $testfile ||
11402                 error "$testfile error deleting trusted.name1"
11403         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11404                 error "$testfile did not delete trusted.name1 xattr"
11405
11406         setfattr -x user.author1 $testfile ||
11407                 error "$testfile error deleting user.author1"
11408         echo "set lustre special xattr ..."
11409         $LFS setstripe -c1 $testfile
11410         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11411                 awk -F "=" '/trusted.lov/ { print $2 }' )
11412         setfattr -n "trusted.lov" -v $lovea $testfile ||
11413                 error "$testfile doesn't ignore setting trusted.lov again"
11414         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11415                 error "$testfile allow setting invalid trusted.lov"
11416         rm -f $testfile
11417 }
11418 run_test 102a "user xattr test =================================="
11419
11420 check_102b_layout() {
11421         local layout="$*"
11422         local testfile=$DIR/$tfile
11423
11424         echo "test layout '$layout'"
11425         $LFS setstripe $layout $testfile || error "setstripe failed"
11426         $LFS getstripe -y $testfile
11427
11428         echo "get/set/list trusted.lov xattr ..." # b=10930
11429         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11430         [[ "$value" =~ "trusted.lov" ]] ||
11431                 error "can't get trusted.lov from $testfile"
11432         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11433                 error "getstripe failed"
11434
11435         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11436
11437         value=$(cut -d= -f2 <<<$value)
11438         # LU-13168: truncated xattr should fail if short lov_user_md header
11439         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11440                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11441         for len in $lens; do
11442                 echo "setfattr $len $testfile.2"
11443                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11444                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11445         done
11446         local stripe_size=$($LFS getstripe -S $testfile.2)
11447         local stripe_count=$($LFS getstripe -c $testfile.2)
11448         [[ $stripe_size -eq 65536 ]] ||
11449                 error "stripe size $stripe_size != 65536"
11450         [[ $stripe_count -eq $stripe_count_orig ]] ||
11451                 error "stripe count $stripe_count != $stripe_count_orig"
11452         rm $testfile $testfile.2
11453 }
11454
11455 test_102b() {
11456         [ -z "$(which setfattr 2>/dev/null)" ] &&
11457                 skip_env "could not find setfattr"
11458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11459
11460         # check plain layout
11461         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11462
11463         # and also check composite layout
11464         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11465
11466 }
11467 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11468
11469 test_102c() {
11470         [ -z "$(which setfattr 2>/dev/null)" ] &&
11471                 skip_env "could not find setfattr"
11472         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11473
11474         # b10930: get/set/list lustre.lov xattr
11475         echo "get/set/list lustre.lov xattr ..."
11476         test_mkdir $DIR/$tdir
11477         chown $RUNAS_ID $DIR/$tdir
11478         local testfile=$DIR/$tdir/$tfile
11479         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11480                 error "setstripe failed"
11481         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11482                 error "getstripe failed"
11483         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11484         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11485
11486         local testfile2=${testfile}2
11487         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11488                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11489
11490         $RUNAS $MCREATE $testfile2
11491         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11492         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11493         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11494         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11495         [ $stripe_count -eq $STRIPECOUNT ] ||
11496                 error "stripe count $stripe_count != $STRIPECOUNT"
11497 }
11498 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11499
11500 compare_stripe_info1() {
11501         local stripe_index_all_zero=true
11502
11503         for num in 1 2 3 4; do
11504                 for count in $(seq 1 $STRIPE_COUNT); do
11505                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11506                                 local size=$((STRIPE_SIZE * num))
11507                                 local file=file"$num-$offset-$count"
11508                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11509                                 [[ $stripe_size -ne $size ]] &&
11510                                     error "$file: size $stripe_size != $size"
11511                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11512                                 # allow fewer stripes to be created, ORI-601
11513                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11514                                     error "$file: count $stripe_count != $count"
11515                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11516                                 [[ $stripe_index -ne 0 ]] &&
11517                                         stripe_index_all_zero=false
11518                         done
11519                 done
11520         done
11521         $stripe_index_all_zero &&
11522                 error "all files are being extracted starting from OST index 0"
11523         return 0
11524 }
11525
11526 have_xattrs_include() {
11527         tar --help | grep -q xattrs-include &&
11528                 echo --xattrs-include="lustre.*"
11529 }
11530
11531 test_102d() {
11532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11533         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11534
11535         XINC=$(have_xattrs_include)
11536         setup_test102
11537         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11538         cd $DIR/$tdir/$tdir
11539         compare_stripe_info1
11540 }
11541 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11542
11543 test_102f() {
11544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11546
11547         XINC=$(have_xattrs_include)
11548         setup_test102
11549         test_mkdir $DIR/$tdir.restore
11550         cd $DIR
11551         tar cf - --xattrs $tdir | tar xf - \
11552                 -C $DIR/$tdir.restore --xattrs $XINC
11553         cd $DIR/$tdir.restore/$tdir
11554         compare_stripe_info1
11555 }
11556 run_test 102f "tar copy files, not keep osts"
11557
11558 grow_xattr() {
11559         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11560                 skip "must have user_xattr"
11561         [ -z "$(which setfattr 2>/dev/null)" ] &&
11562                 skip_env "could not find setfattr"
11563         [ -z "$(which getfattr 2>/dev/null)" ] &&
11564                 skip_env "could not find getfattr"
11565
11566         local xsize=${1:-1024}  # in bytes
11567         local file=$DIR/$tfile
11568         local value="$(generate_string $xsize)"
11569         local xbig=trusted.big
11570         local toobig=$2
11571
11572         touch $file
11573         log "save $xbig on $file"
11574         if [ -z "$toobig" ]
11575         then
11576                 setfattr -n $xbig -v $value $file ||
11577                         error "saving $xbig on $file failed"
11578         else
11579                 setfattr -n $xbig -v $value $file &&
11580                         error "saving $xbig on $file succeeded"
11581                 return 0
11582         fi
11583
11584         local orig=$(get_xattr_value $xbig $file)
11585         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11586
11587         local xsml=trusted.sml
11588         log "save $xsml on $file"
11589         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11590
11591         local new=$(get_xattr_value $xbig $file)
11592         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11593
11594         log "grow $xsml on $file"
11595         setfattr -n $xsml -v "$value" $file ||
11596                 error "growing $xsml on $file failed"
11597
11598         new=$(get_xattr_value $xbig $file)
11599         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11600         log "$xbig still valid after growing $xsml"
11601
11602         rm -f $file
11603 }
11604
11605 test_102h() { # bug 15777
11606         grow_xattr 1024
11607 }
11608 run_test 102h "grow xattr from inside inode to external block"
11609
11610 test_102ha() {
11611         large_xattr_enabled || skip_env "ea_inode feature disabled"
11612
11613         echo "setting xattr of max xattr size: $(max_xattr_size)"
11614         grow_xattr $(max_xattr_size)
11615
11616         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11617         echo "This should fail:"
11618         grow_xattr $(($(max_xattr_size) + 10)) 1
11619 }
11620 run_test 102ha "grow xattr from inside inode to external inode"
11621
11622 test_102i() { # bug 17038
11623         [ -z "$(which getfattr 2>/dev/null)" ] &&
11624                 skip "could not find getfattr"
11625
11626         touch $DIR/$tfile
11627         ln -s $DIR/$tfile $DIR/${tfile}link
11628         getfattr -n trusted.lov $DIR/$tfile ||
11629                 error "lgetxattr on $DIR/$tfile failed"
11630         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11631                 grep -i "no such attr" ||
11632                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11633         rm -f $DIR/$tfile $DIR/${tfile}link
11634 }
11635 run_test 102i "lgetxattr test on symbolic link ============"
11636
11637 test_102j() {
11638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11639         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11640
11641         XINC=$(have_xattrs_include)
11642         setup_test102 "$RUNAS"
11643         chown $RUNAS_ID $DIR/$tdir
11644         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11645         cd $DIR/$tdir/$tdir
11646         compare_stripe_info1 "$RUNAS"
11647 }
11648 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11649
11650 test_102k() {
11651         [ -z "$(which setfattr 2>/dev/null)" ] &&
11652                 skip "could not find setfattr"
11653
11654         touch $DIR/$tfile
11655         # b22187 just check that does not crash for regular file.
11656         setfattr -n trusted.lov $DIR/$tfile
11657         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11658         local test_kdir=$DIR/$tdir
11659         test_mkdir $test_kdir
11660         local default_size=$($LFS getstripe -S $test_kdir)
11661         local default_count=$($LFS getstripe -c $test_kdir)
11662         local default_offset=$($LFS getstripe -i $test_kdir)
11663         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11664                 error 'dir setstripe failed'
11665         setfattr -n trusted.lov $test_kdir
11666         local stripe_size=$($LFS getstripe -S $test_kdir)
11667         local stripe_count=$($LFS getstripe -c $test_kdir)
11668         local stripe_offset=$($LFS getstripe -i $test_kdir)
11669         [ $stripe_size -eq $default_size ] ||
11670                 error "stripe size $stripe_size != $default_size"
11671         [ $stripe_count -eq $default_count ] ||
11672                 error "stripe count $stripe_count != $default_count"
11673         [ $stripe_offset -eq $default_offset ] ||
11674                 error "stripe offset $stripe_offset != $default_offset"
11675         rm -rf $DIR/$tfile $test_kdir
11676 }
11677 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11678
11679 test_102l() {
11680         [ -z "$(which getfattr 2>/dev/null)" ] &&
11681                 skip "could not find getfattr"
11682
11683         # LU-532 trusted. xattr is invisible to non-root
11684         local testfile=$DIR/$tfile
11685
11686         touch $testfile
11687
11688         echo "listxattr as user..."
11689         chown $RUNAS_ID $testfile
11690         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11691             grep -q "trusted" &&
11692                 error "$testfile trusted xattrs are user visible"
11693
11694         return 0;
11695 }
11696 run_test 102l "listxattr size test =================================="
11697
11698 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11699         local path=$DIR/$tfile
11700         touch $path
11701
11702         listxattr_size_check $path || error "listattr_size_check $path failed"
11703 }
11704 run_test 102m "Ensure listxattr fails on small bufffer ========"
11705
11706 cleanup_test102
11707
11708 getxattr() { # getxattr path name
11709         # Return the base64 encoding of the value of xattr name on path.
11710         local path=$1
11711         local name=$2
11712
11713         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11714         # file: $path
11715         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11716         #
11717         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11718
11719         getfattr --absolute-names --encoding=base64 --name=$name $path |
11720                 awk -F= -v name=$name '$1 == name {
11721                         print substr($0, index($0, "=") + 1);
11722         }'
11723 }
11724
11725 test_102n() { # LU-4101 mdt: protect internal xattrs
11726         [ -z "$(which setfattr 2>/dev/null)" ] &&
11727                 skip "could not find setfattr"
11728         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11729         then
11730                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11731         fi
11732
11733         local file0=$DIR/$tfile.0
11734         local file1=$DIR/$tfile.1
11735         local xattr0=$TMP/$tfile.0
11736         local xattr1=$TMP/$tfile.1
11737         local namelist="lov lma lmv link fid version som hsm"
11738         local name
11739         local value
11740
11741         rm -rf $file0 $file1 $xattr0 $xattr1
11742         touch $file0 $file1
11743
11744         # Get 'before' xattrs of $file1.
11745         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11746
11747         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11748                 namelist+=" lfsck_namespace"
11749         for name in $namelist; do
11750                 # Try to copy xattr from $file0 to $file1.
11751                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11752
11753                 setfattr --name=trusted.$name --value="$value" $file1 ||
11754                         error "setxattr 'trusted.$name' failed"
11755
11756                 # Try to set a garbage xattr.
11757                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11758
11759                 if [[ x$name == "xlov" ]]; then
11760                         setfattr --name=trusted.lov --value="$value" $file1 &&
11761                         error "setxattr invalid 'trusted.lov' success"
11762                 else
11763                         setfattr --name=trusted.$name --value="$value" $file1 ||
11764                                 error "setxattr invalid 'trusted.$name' failed"
11765                 fi
11766
11767                 # Try to remove the xattr from $file1. We don't care if this
11768                 # appears to succeed or fail, we just don't want there to be
11769                 # any changes or crashes.
11770                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11771         done
11772
11773         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11774         then
11775                 name="lfsck_ns"
11776                 # Try to copy xattr from $file0 to $file1.
11777                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11778
11779                 setfattr --name=trusted.$name --value="$value" $file1 ||
11780                         error "setxattr 'trusted.$name' failed"
11781
11782                 # Try to set a garbage xattr.
11783                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11784
11785                 setfattr --name=trusted.$name --value="$value" $file1 ||
11786                         error "setxattr 'trusted.$name' failed"
11787
11788                 # Try to remove the xattr from $file1. We don't care if this
11789                 # appears to succeed or fail, we just don't want there to be
11790                 # any changes or crashes.
11791                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11792         fi
11793
11794         # Get 'after' xattrs of file1.
11795         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11796
11797         if ! diff $xattr0 $xattr1; then
11798                 error "before and after xattrs of '$file1' differ"
11799         fi
11800
11801         rm -rf $file0 $file1 $xattr0 $xattr1
11802
11803         return 0
11804 }
11805 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11806
11807 test_102p() { # LU-4703 setxattr did not check ownership
11808         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11809                 skip "MDS needs to be at least 2.5.56"
11810
11811         local testfile=$DIR/$tfile
11812
11813         touch $testfile
11814
11815         echo "setfacl as user..."
11816         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11817         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11818
11819         echo "setfattr as user..."
11820         setfacl -m "u:$RUNAS_ID:---" $testfile
11821         $RUNAS setfattr -x system.posix_acl_access $testfile
11822         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11823 }
11824 run_test 102p "check setxattr(2) correctly fails without permission"
11825
11826 test_102q() {
11827         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11828                 skip "MDS needs to be at least 2.6.92"
11829
11830         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11831 }
11832 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11833
11834 test_102r() {
11835         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11836                 skip "MDS needs to be at least 2.6.93"
11837
11838         touch $DIR/$tfile || error "touch"
11839         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11840         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11841         rm $DIR/$tfile || error "rm"
11842
11843         #normal directory
11844         mkdir -p $DIR/$tdir || error "mkdir"
11845         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11846         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11847         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11848                 error "$testfile error deleting user.author1"
11849         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11850                 grep "user.$(basename $tdir)" &&
11851                 error "$tdir did not delete user.$(basename $tdir)"
11852         rmdir $DIR/$tdir || error "rmdir"
11853
11854         #striped directory
11855         test_mkdir $DIR/$tdir
11856         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11857         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11858         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11859                 error "$testfile error deleting user.author1"
11860         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11861                 grep "user.$(basename $tdir)" &&
11862                 error "$tdir did not delete user.$(basename $tdir)"
11863         rmdir $DIR/$tdir || error "rm striped dir"
11864 }
11865 run_test 102r "set EAs with empty values"
11866
11867 test_102s() {
11868         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11869                 skip "MDS needs to be at least 2.11.52"
11870
11871         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11872
11873         save_lustre_params client "llite.*.xattr_cache" > $save
11874
11875         for cache in 0 1; do
11876                 lctl set_param llite.*.xattr_cache=$cache
11877
11878                 rm -f $DIR/$tfile
11879                 touch $DIR/$tfile || error "touch"
11880                 for prefix in lustre security system trusted user; do
11881                         # Note getxattr() may fail with 'Operation not
11882                         # supported' or 'No such attribute' depending
11883                         # on prefix and cache.
11884                         getfattr -n $prefix.n102s $DIR/$tfile &&
11885                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11886                 done
11887         done
11888
11889         restore_lustre_params < $save
11890 }
11891 run_test 102s "getting nonexistent xattrs should fail"
11892
11893 test_102t() {
11894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11895                 skip "MDS needs to be at least 2.11.52"
11896
11897         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11898
11899         save_lustre_params client "llite.*.xattr_cache" > $save
11900
11901         for cache in 0 1; do
11902                 lctl set_param llite.*.xattr_cache=$cache
11903
11904                 for buf_size in 0 256; do
11905                         rm -f $DIR/$tfile
11906                         touch $DIR/$tfile || error "touch"
11907                         setfattr -n user.multiop $DIR/$tfile
11908                         $MULTIOP $DIR/$tfile oa$buf_size ||
11909                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11910                 done
11911         done
11912
11913         restore_lustre_params < $save
11914 }
11915 run_test 102t "zero length xattr values handled correctly"
11916
11917 run_acl_subtest()
11918 {
11919         local test=$LUSTRE/tests/acl/$1.test
11920         local tmp=$(mktemp -t $1-XXXXXX).test
11921         local bin=$2
11922         local dmn=$3
11923         local grp=$4
11924         local nbd=$5
11925         export LANG=C
11926
11927
11928         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11929         local sedgroups="-e s/:users/:$grp/g"
11930         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11931
11932         sed $sedusers $sedgroups < $test > $tmp
11933         stack_trap "rm -f $tmp"
11934         [[ -s $tmp ]] || error "sed failed to create test script"
11935
11936         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11937         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11938 }
11939
11940 test_103a() {
11941         [ "$UID" != 0 ] && skip "must run as root"
11942         $GSS && skip_env "could not run under gss"
11943         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11944                 skip_env "must have acl enabled"
11945         which setfacl || skip_env "could not find setfacl"
11946         remote_mds_nodsh && skip "remote MDS with nodsh"
11947
11948         ACLBIN=${ACLBIN:-"bin"}
11949         ACLDMN=${ACLDMN:-"daemon"}
11950         ACLGRP=${ACLGRP:-"users"}
11951         ACLNBD=${ACLNBD:-"nobody"}
11952
11953         if ! id $ACLBIN ||
11954            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11955                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11956                 ACLBIN=$USER0
11957                 if ! id $ACLBIN ; then
11958                         cat /etc/passwd
11959                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11960                 fi
11961         fi
11962         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11963            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11964                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11965                 ACLDMN=$USER1
11966                 if ! id $ACLDMN ; then
11967                         cat /etc/passwd
11968                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11969                 fi
11970         fi
11971         if ! getent group $ACLGRP; then
11972                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11973                 ACLGRP="$TSTUSR"
11974                 if ! getent group $ACLGRP; then
11975                         echo "cannot find group '$ACLGRP', adding it"
11976                         cat /etc/group
11977                         add_group 60000 $ACLGRP
11978                 fi
11979         fi
11980
11981         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11982         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11983         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11984
11985         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11986                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11987                 ACLGRP="$TSTUSR"
11988                 if ! getent group $ACLGRP; then
11989                         echo "cannot find group '$ACLGRP', adding it"
11990                         cat /etc/group
11991                         add_group 60000 $ACLGRP
11992                 fi
11993                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11994                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11995                         cat /etc/group
11996                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11997                 fi
11998         fi
11999
12000         gpasswd -a $ACLDMN $ACLBIN ||
12001                 error "setting client group failed"             # LU-5641
12002         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12003                 error "setting MDS group failed"                # LU-5641
12004
12005         declare -a identity_old
12006
12007         for num in $(seq $MDSCOUNT); do
12008                 switch_identity $num true || identity_old[$num]=$?
12009         done
12010
12011         SAVE_UMASK=$(umask)
12012         umask 0022
12013         mkdir -p $DIR/$tdir
12014         cd $DIR/$tdir
12015
12016         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12017         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12018         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12019         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12020         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12021         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12022         if ! id -u $ACLNBD ||
12023            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12024                 ACLNBD="nfsnobody"
12025                 if ! id -u $ACLNBD; then
12026                         ACLNBD=""
12027                 fi
12028         fi
12029         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12030                 add_group $(id -u $ACLNBD) $ACLNBD
12031                 if ! getent group $ACLNBD; then
12032                         ACLNBD=""
12033                 fi
12034         fi
12035         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12036            [[ -n "$ACLNBD" ]] && which setfattr; then
12037                 run_acl_subtest permissions_xattr \
12038                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12039         elif [[ -z "$ACLNBD" ]]; then
12040                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12041         else
12042                 echo "skip 'permission_xattr' test - missing setfattr command"
12043         fi
12044         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12045
12046         # inheritance test got from HP
12047         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12048         chmod +x make-tree || error "chmod +x failed"
12049         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12050         rm -f make-tree
12051
12052         echo "LU-974 ignore umask when acl is enabled..."
12053         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12054         if [ $MDSCOUNT -ge 2 ]; then
12055                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12056         fi
12057
12058         echo "LU-2561 newly created file is same size as directory..."
12059         if [ "$mds1_FSTYPE" != "zfs" ]; then
12060                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12061         else
12062                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12063         fi
12064
12065         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12066
12067         cd $SAVE_PWD
12068         umask $SAVE_UMASK
12069
12070         for num in $(seq $MDSCOUNT); do
12071                 if [ "${identity_old[$num]}" = 1 ]; then
12072                         switch_identity $num false || identity_old[$num]=$?
12073                 fi
12074         done
12075 }
12076 run_test 103a "acl test"
12077
12078 test_103b() {
12079         declare -a pids
12080         local U
12081
12082         for U in {0..511}; do
12083                 {
12084                 local O=$(printf "%04o" $U)
12085
12086                 umask $(printf "%04o" $((511 ^ $O)))
12087                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12088                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12089
12090                 (( $S == ($O & 0666) )) ||
12091                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12092
12093                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12094                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12095                 (( $S == ($O & 0666) )) ||
12096                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12097
12098                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12099                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12100                 (( $S == ($O & 0666) )) ||
12101                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12102                 rm -f $DIR/$tfile.[smp]$0
12103                 } &
12104                 local pid=$!
12105
12106                 # limit the concurrently running threads to 64. LU-11878
12107                 local idx=$((U % 64))
12108                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12109                 pids[idx]=$pid
12110         done
12111         wait
12112 }
12113 run_test 103b "umask lfs setstripe"
12114
12115 test_103c() {
12116         mkdir -p $DIR/$tdir
12117         cp -rp $DIR/$tdir $DIR/$tdir.bak
12118
12119         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12120                 error "$DIR/$tdir shouldn't contain default ACL"
12121         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12122                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12123         true
12124 }
12125 run_test 103c "'cp -rp' won't set empty acl"
12126
12127 test_103e() {
12128         local numacl
12129         local fileacl
12130         local saved_debug=$($LCTL get_param -n debug)
12131
12132         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12133                 skip "MDS needs to be at least 2.14.52"
12134
12135         large_xattr_enabled || skip_env "ea_inode feature disabled"
12136
12137         mkdir -p $DIR/$tdir
12138         # add big LOV EA to cause reply buffer overflow earlier
12139         $LFS setstripe -C 1000 $DIR/$tdir
12140         lctl set_param mdc.*-mdc*.stats=clear
12141
12142         $LCTL set_param debug=0
12143         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12144         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12145
12146         # add a large number of default ACLs (expect 8000+ for 2.13+)
12147         for U in {2..7000}; do
12148                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12149                         error "Able to add just $U default ACLs"
12150         done
12151         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12152         echo "$numacl default ACLs created"
12153
12154         stat $DIR/$tdir || error "Cannot stat directory"
12155         # check file creation
12156         touch $DIR/$tdir/$tfile ||
12157                 error "failed to create $tfile with $numacl default ACLs"
12158         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12159         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12160         echo "$fileacl ACLs were inherited"
12161         (( $fileacl == $numacl )) ||
12162                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12163         # check that new ACLs creation adds new ACLs to inherited ACLs
12164         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12165                 error "Cannot set new ACL"
12166         numacl=$((numacl + 1))
12167         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12168         (( $fileacl == $numacl )) ||
12169                 error "failed to add new ACL: $fileacl != $numacl as expected"
12170         # adds more ACLs to a file to reach their maximum at 8000+
12171         numacl=0
12172         for U in {20000..25000}; do
12173                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12174                 numacl=$((numacl + 1))
12175         done
12176         echo "Added $numacl more ACLs to the file"
12177         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12178         echo "Total $fileacl ACLs in file"
12179         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12180         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12181         rmdir $DIR/$tdir || error "Cannot remove directory"
12182 }
12183 run_test 103e "inheritance of big amount of default ACLs"
12184
12185 test_103f() {
12186         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12187                 skip "MDS needs to be at least 2.14.51"
12188
12189         large_xattr_enabled || skip_env "ea_inode feature disabled"
12190
12191         # enable changelog to consume more internal MDD buffers
12192         changelog_register
12193
12194         mkdir -p $DIR/$tdir
12195         # add big LOV EA
12196         $LFS setstripe -C 1000 $DIR/$tdir
12197         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12198         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12199         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12200         rmdir $DIR/$tdir || error "Cannot remove directory"
12201 }
12202 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12203
12204 test_104a() {
12205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12206
12207         touch $DIR/$tfile
12208         lfs df || error "lfs df failed"
12209         lfs df -ih || error "lfs df -ih failed"
12210         lfs df -h $DIR || error "lfs df -h $DIR failed"
12211         lfs df -i $DIR || error "lfs df -i $DIR failed"
12212         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12213         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12214
12215         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12216         lctl --device %$OSC deactivate
12217         lfs df || error "lfs df with deactivated OSC failed"
12218         lctl --device %$OSC activate
12219         # wait the osc back to normal
12220         wait_osc_import_ready client ost
12221
12222         lfs df || error "lfs df with reactivated OSC failed"
12223         rm -f $DIR/$tfile
12224 }
12225 run_test 104a "lfs df [-ih] [path] test ========================="
12226
12227 test_104b() {
12228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12229         [ $RUNAS_ID -eq $UID ] &&
12230                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12231
12232         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12233                         grep "Permission denied" | wc -l)))
12234         if [ $denied_cnt -ne 0 ]; then
12235                 error "lfs check servers test failed"
12236         fi
12237 }
12238 run_test 104b "$RUNAS lfs check servers test ===================="
12239
12240 #
12241 # Verify $1 is within range of $2.
12242 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12243 # $1 is <= 2% of $2. Else Fail.
12244 #
12245 value_in_range() {
12246         # Strip all units (M, G, T)
12247         actual=$(echo $1 | tr -d A-Z)
12248         expect=$(echo $2 | tr -d A-Z)
12249
12250         expect_lo=$(($expect * 98 / 100)) # 2% below
12251         expect_hi=$(($expect * 102 / 100)) # 2% above
12252
12253         # permit 2% drift above and below
12254         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12255 }
12256
12257 test_104c() {
12258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12259         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12260
12261         local ost_param="osd-zfs.$FSNAME-OST0000."
12262         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12263         local ofacets=$(get_facets OST)
12264         local mfacets=$(get_facets MDS)
12265         local saved_ost_blocks=
12266         local saved_mdt_blocks=
12267
12268         echo "Before recordsize change"
12269         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12270         df=($(df -h | grep "$MOUNT"$))
12271
12272         # For checking.
12273         echo "lfs output : ${lfs_df[*]}"
12274         echo "df  output : ${df[*]}"
12275
12276         for facet in ${ofacets//,/ }; do
12277                 if [ -z $saved_ost_blocks ]; then
12278                         saved_ost_blocks=$(do_facet $facet \
12279                                 lctl get_param -n $ost_param.blocksize)
12280                         echo "OST Blocksize: $saved_ost_blocks"
12281                 fi
12282                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12283                 do_facet $facet zfs set recordsize=32768 $ost
12284         done
12285
12286         # BS too small. Sufficient for functional testing.
12287         for facet in ${mfacets//,/ }; do
12288                 if [ -z $saved_mdt_blocks ]; then
12289                         saved_mdt_blocks=$(do_facet $facet \
12290                                 lctl get_param -n $mdt_param.blocksize)
12291                         echo "MDT Blocksize: $saved_mdt_blocks"
12292                 fi
12293                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12294                 do_facet $facet zfs set recordsize=32768 $mdt
12295         done
12296
12297         # Give new values chance to reflect change
12298         sleep 2
12299
12300         echo "After recordsize change"
12301         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12302         df_after=($(df -h | grep "$MOUNT"$))
12303
12304         # For checking.
12305         echo "lfs output : ${lfs_df_after[*]}"
12306         echo "df  output : ${df_after[*]}"
12307
12308         # Verify lfs df
12309         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12310                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12311         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12312                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12313         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12314                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12315
12316         # Verify df
12317         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12318                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12319         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12320                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12321         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12322                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12323
12324         # Restore MDT recordize back to original
12325         for facet in ${mfacets//,/ }; do
12326                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12327                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12328         done
12329
12330         # Restore OST recordize back to original
12331         for facet in ${ofacets//,/ }; do
12332                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12333                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12334         done
12335
12336         return 0
12337 }
12338 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12339
12340 test_104d() {
12341         (( $RUNAS_ID != $UID )) ||
12342                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12343
12344         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12345                 skip "lustre version doesn't support lctl dl with non-root"
12346
12347         # debugfs only allows root users to access files, so the
12348         # previous move of the "devices" file to debugfs broke
12349         # "lctl dl" for non-root users. The LU-9680 Netlink
12350         # interface again allows non-root users to list devices.
12351         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12352                 error "lctl dl doesn't work for non root"
12353
12354         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12355         [ "$ost_count" -eq $OSTCOUNT ]  ||
12356                 error "lctl dl reports wrong number of OST devices"
12357
12358         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12359         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12360                 error "lctl dl reports wrong number of MDT devices"
12361 }
12362 run_test 104d "$RUNAS lctl dl test"
12363
12364 test_105a() {
12365         # doesn't work on 2.4 kernels
12366         touch $DIR/$tfile
12367         if $(flock_is_enabled); then
12368                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12369         else
12370                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12371         fi
12372         rm -f $DIR/$tfile
12373 }
12374 run_test 105a "flock when mounted without -o flock test ========"
12375
12376 test_105b() {
12377         touch $DIR/$tfile
12378         if $(flock_is_enabled); then
12379                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12380         else
12381                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12382         fi
12383         rm -f $DIR/$tfile
12384 }
12385 run_test 105b "fcntl when mounted without -o flock test ========"
12386
12387 test_105c() {
12388         touch $DIR/$tfile
12389         if $(flock_is_enabled); then
12390                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12391         else
12392                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12393         fi
12394         rm -f $DIR/$tfile
12395 }
12396 run_test 105c "lockf when mounted without -o flock test"
12397
12398 test_105d() { # bug 15924
12399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12400
12401         test_mkdir $DIR/$tdir
12402         flock_is_enabled || skip_env "mount w/o flock enabled"
12403         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12404         $LCTL set_param fail_loc=0x80000315
12405         flocks_test 2 $DIR/$tdir
12406 }
12407 run_test 105d "flock race (should not freeze) ========"
12408
12409 test_105e() { # bug 22660 && 22040
12410         flock_is_enabled || skip_env "mount w/o flock enabled"
12411
12412         touch $DIR/$tfile
12413         flocks_test 3 $DIR/$tfile
12414 }
12415 run_test 105e "Two conflicting flocks from same process"
12416
12417 test_106() { #bug 10921
12418         test_mkdir $DIR/$tdir
12419         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12420         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12421 }
12422 run_test 106 "attempt exec of dir followed by chown of that dir"
12423
12424 test_107() {
12425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12426
12427         CDIR=`pwd`
12428         local file=core
12429
12430         cd $DIR
12431         rm -f $file
12432
12433         local save_pattern=$(sysctl -n kernel.core_pattern)
12434         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12435         sysctl -w kernel.core_pattern=$file
12436         sysctl -w kernel.core_uses_pid=0
12437
12438         ulimit -c unlimited
12439         sleep 60 &
12440         SLEEPPID=$!
12441
12442         sleep 1
12443
12444         kill -s 11 $SLEEPPID
12445         wait $SLEEPPID
12446         if [ -e $file ]; then
12447                 size=`stat -c%s $file`
12448                 [ $size -eq 0 ] && error "Fail to create core file $file"
12449         else
12450                 error "Fail to create core file $file"
12451         fi
12452         rm -f $file
12453         sysctl -w kernel.core_pattern=$save_pattern
12454         sysctl -w kernel.core_uses_pid=$save_uses_pid
12455         cd $CDIR
12456 }
12457 run_test 107 "Coredump on SIG"
12458
12459 test_110() {
12460         test_mkdir $DIR/$tdir
12461         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12462         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12463                 error "mkdir with 256 char should fail, but did not"
12464         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12465                 error "create with 255 char failed"
12466         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12467                 error "create with 256 char should fail, but did not"
12468
12469         ls -l $DIR/$tdir
12470         rm -rf $DIR/$tdir
12471 }
12472 run_test 110 "filename length checking"
12473
12474 test_116a() { # was previously test_116()
12475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12476         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12477         remote_mds_nodsh && skip "remote MDS with nodsh"
12478
12479         echo -n "Free space priority "
12480         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12481                 head -n1
12482         declare -a AVAIL
12483         free_min_max
12484
12485         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12486         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12487         stack_trap simple_cleanup_common
12488
12489         # Check if we need to generate uneven OSTs
12490         test_mkdir -p $DIR/$tdir/OST${MINI}
12491         local FILL=$((MINV / 4))
12492         local DIFF=$((MAXV - MINV))
12493         local DIFF2=$((DIFF * 100 / MINV))
12494
12495         local threshold=$(do_facet $SINGLEMDS \
12496                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12497         threshold=${threshold%%%}
12498         echo -n "Check for uneven OSTs: "
12499         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12500
12501         if [[ $DIFF2 -gt $threshold ]]; then
12502                 echo "ok"
12503                 echo "Don't need to fill OST$MINI"
12504         else
12505                 # generate uneven OSTs. Write 2% over the QOS threshold value
12506                 echo "no"
12507                 DIFF=$((threshold - DIFF2 + 2))
12508                 DIFF2=$((MINV * DIFF / 100))
12509                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12510                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12511                         error "setstripe failed"
12512                 DIFF=$((DIFF2 / 2048))
12513                 i=0
12514                 while [ $i -lt $DIFF ]; do
12515                         i=$((i + 1))
12516                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12517                                 bs=2M count=1 2>/dev/null
12518                         echo -n .
12519                 done
12520                 echo .
12521                 sync
12522                 sleep_maxage
12523                 free_min_max
12524         fi
12525
12526         DIFF=$((MAXV - MINV))
12527         DIFF2=$((DIFF * 100 / MINV))
12528         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12529         if [ $DIFF2 -gt $threshold ]; then
12530                 echo "ok"
12531         else
12532                 skip "QOS imbalance criteria not met"
12533         fi
12534
12535         MINI1=$MINI
12536         MINV1=$MINV
12537         MAXI1=$MAXI
12538         MAXV1=$MAXV
12539
12540         # now fill using QOS
12541         $LFS setstripe -c 1 $DIR/$tdir
12542         FILL=$((FILL / 200))
12543         if [ $FILL -gt 600 ]; then
12544                 FILL=600
12545         fi
12546         echo "writing $FILL files to QOS-assigned OSTs"
12547         i=0
12548         while [ $i -lt $FILL ]; do
12549                 i=$((i + 1))
12550                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12551                         count=1 2>/dev/null
12552                 echo -n .
12553         done
12554         echo "wrote $i 200k files"
12555         sync
12556         sleep_maxage
12557
12558         echo "Note: free space may not be updated, so measurements might be off"
12559         free_min_max
12560         DIFF2=$((MAXV - MINV))
12561         echo "free space delta: orig $DIFF final $DIFF2"
12562         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12563         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12564         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12565         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12566         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12567         if [[ $DIFF -gt 0 ]]; then
12568                 FILL=$((DIFF2 * 100 / DIFF - 100))
12569                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12570         fi
12571
12572         # Figure out which files were written where
12573         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12574                awk '/'$MINI1': / {print $2; exit}')
12575         echo $UUID
12576         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12577         echo "$MINC files created on smaller OST $MINI1"
12578         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12579                awk '/'$MAXI1': / {print $2; exit}')
12580         echo $UUID
12581         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12582         echo "$MAXC files created on larger OST $MAXI1"
12583         if [[ $MINC -gt 0 ]]; then
12584                 FILL=$((MAXC * 100 / MINC - 100))
12585                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12586         fi
12587         [[ $MAXC -gt $MINC ]] ||
12588                 error_ignore LU-9 "stripe QOS didn't balance free space"
12589 }
12590 run_test 116a "stripe QOS: free space balance ==================="
12591
12592 test_116b() { # LU-2093
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594         remote_mds_nodsh && skip "remote MDS with nodsh"
12595
12596 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12597         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12598                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12599         [ -z "$old_rr" ] && skip "no QOS"
12600         do_facet $SINGLEMDS lctl set_param \
12601                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12602         mkdir -p $DIR/$tdir
12603         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12604         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12605         do_facet $SINGLEMDS lctl set_param fail_loc=0
12606         rm -rf $DIR/$tdir
12607         do_facet $SINGLEMDS lctl set_param \
12608                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12609 }
12610 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12611
12612 test_117() # bug 10891
12613 {
12614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12615
12616         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12617         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12618         lctl set_param fail_loc=0x21e
12619         > $DIR/$tfile || error "truncate failed"
12620         lctl set_param fail_loc=0
12621         echo "Truncate succeeded."
12622         rm -f $DIR/$tfile
12623 }
12624 run_test 117 "verify osd extend =========="
12625
12626 NO_SLOW_RESENDCOUNT=4
12627 export OLD_RESENDCOUNT=""
12628 set_resend_count () {
12629         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12630         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12631         lctl set_param -n $PROC_RESENDCOUNT $1
12632         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12633 }
12634
12635 # for reduce test_118* time (b=14842)
12636 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12637
12638 # Reset async IO behavior after error case
12639 reset_async() {
12640         FILE=$DIR/reset_async
12641
12642         # Ensure all OSCs are cleared
12643         $LFS setstripe -c -1 $FILE
12644         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12645         sync
12646         rm $FILE
12647 }
12648
12649 test_118a() #bug 11710
12650 {
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652
12653         reset_async
12654
12655         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12656         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12657         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12658
12659         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12660                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12661                 return 1;
12662         fi
12663         rm -f $DIR/$tfile
12664 }
12665 run_test 118a "verify O_SYNC works =========="
12666
12667 test_118b()
12668 {
12669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12670         remote_ost_nodsh && skip "remote OST with nodsh"
12671
12672         reset_async
12673
12674         #define OBD_FAIL_SRV_ENOENT 0x217
12675         set_nodes_failloc "$(osts_nodes)" 0x217
12676         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12677         RC=$?
12678         set_nodes_failloc "$(osts_nodes)" 0
12679         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12680         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12681                     grep -c writeback)
12682
12683         if [[ $RC -eq 0 ]]; then
12684                 error "Must return error due to dropped pages, rc=$RC"
12685                 return 1;
12686         fi
12687
12688         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12689                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12690                 return 1;
12691         fi
12692
12693         echo "Dirty pages not leaked on ENOENT"
12694
12695         # Due to the above error the OSC will issue all RPCs syncronously
12696         # until a subsequent RPC completes successfully without error.
12697         $MULTIOP $DIR/$tfile Ow4096yc
12698         rm -f $DIR/$tfile
12699
12700         return 0
12701 }
12702 run_test 118b "Reclaim dirty pages on fatal error =========="
12703
12704 test_118c()
12705 {
12706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12707
12708         # for 118c, restore the original resend count, LU-1940
12709         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12710                                 set_resend_count $OLD_RESENDCOUNT
12711         remote_ost_nodsh && skip "remote OST with nodsh"
12712
12713         reset_async
12714
12715         #define OBD_FAIL_OST_EROFS               0x216
12716         set_nodes_failloc "$(osts_nodes)" 0x216
12717
12718         # multiop should block due to fsync until pages are written
12719         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12720         MULTIPID=$!
12721         sleep 1
12722
12723         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12724                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12725         fi
12726
12727         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12728                     grep -c writeback)
12729         if [[ $WRITEBACK -eq 0 ]]; then
12730                 error "No page in writeback, writeback=$WRITEBACK"
12731         fi
12732
12733         set_nodes_failloc "$(osts_nodes)" 0
12734         wait $MULTIPID
12735         RC=$?
12736         if [[ $RC -ne 0 ]]; then
12737                 error "Multiop fsync failed, rc=$RC"
12738         fi
12739
12740         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12741         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12742                     grep -c writeback)
12743         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12744                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12745         fi
12746
12747         rm -f $DIR/$tfile
12748         echo "Dirty pages flushed via fsync on EROFS"
12749         return 0
12750 }
12751 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12752
12753 # continue to use small resend count to reduce test_118* time (b=14842)
12754 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12755
12756 test_118d()
12757 {
12758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12759         remote_ost_nodsh && skip "remote OST with nodsh"
12760
12761         reset_async
12762
12763         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12764         set_nodes_failloc "$(osts_nodes)" 0x214
12765         # multiop should block due to fsync until pages are written
12766         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12767         MULTIPID=$!
12768         sleep 1
12769
12770         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12771                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12772         fi
12773
12774         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12775                     grep -c writeback)
12776         if [[ $WRITEBACK -eq 0 ]]; then
12777                 error "No page in writeback, writeback=$WRITEBACK"
12778         fi
12779
12780         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12781         set_nodes_failloc "$(osts_nodes)" 0
12782
12783         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12784         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12785                     grep -c writeback)
12786         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12787                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12788         fi
12789
12790         rm -f $DIR/$tfile
12791         echo "Dirty pages gaurenteed flushed via fsync"
12792         return 0
12793 }
12794 run_test 118d "Fsync validation inject a delay of the bulk =========="
12795
12796 test_118f() {
12797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12798
12799         reset_async
12800
12801         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12802         lctl set_param fail_loc=0x8000040a
12803
12804         # Should simulate EINVAL error which is fatal
12805         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12806         RC=$?
12807         if [[ $RC -eq 0 ]]; then
12808                 error "Must return error due to dropped pages, rc=$RC"
12809         fi
12810
12811         lctl set_param fail_loc=0x0
12812
12813         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12814         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12815         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12816                     grep -c writeback)
12817         if [[ $LOCKED -ne 0 ]]; then
12818                 error "Locked pages remain in cache, locked=$LOCKED"
12819         fi
12820
12821         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12822                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12823         fi
12824
12825         rm -f $DIR/$tfile
12826         echo "No pages locked after fsync"
12827
12828         reset_async
12829         return 0
12830 }
12831 run_test 118f "Simulate unrecoverable OSC side error =========="
12832
12833 test_118g() {
12834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12835
12836         reset_async
12837
12838         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12839         lctl set_param fail_loc=0x406
12840
12841         # simulate local -ENOMEM
12842         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12843         RC=$?
12844
12845         lctl set_param fail_loc=0
12846         if [[ $RC -eq 0 ]]; then
12847                 error "Must return error due to dropped pages, rc=$RC"
12848         fi
12849
12850         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12851         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12852         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12853                         grep -c writeback)
12854         if [[ $LOCKED -ne 0 ]]; then
12855                 error "Locked pages remain in cache, locked=$LOCKED"
12856         fi
12857
12858         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12859                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12860         fi
12861
12862         rm -f $DIR/$tfile
12863         echo "No pages locked after fsync"
12864
12865         reset_async
12866         return 0
12867 }
12868 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12869
12870 test_118h() {
12871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12872         remote_ost_nodsh && skip "remote OST with nodsh"
12873
12874         reset_async
12875
12876         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12877         set_nodes_failloc "$(osts_nodes)" 0x20e
12878         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12879         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12880         RC=$?
12881
12882         set_nodes_failloc "$(osts_nodes)" 0
12883         if [[ $RC -eq 0 ]]; then
12884                 error "Must return error due to dropped pages, rc=$RC"
12885         fi
12886
12887         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12888         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12889         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12890                     grep -c writeback)
12891         if [[ $LOCKED -ne 0 ]]; then
12892                 error "Locked pages remain in cache, locked=$LOCKED"
12893         fi
12894
12895         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12896                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12897         fi
12898
12899         rm -f $DIR/$tfile
12900         echo "No pages locked after fsync"
12901
12902         return 0
12903 }
12904 run_test 118h "Verify timeout in handling recoverables errors  =========="
12905
12906 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12907
12908 test_118i() {
12909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12910         remote_ost_nodsh && skip "remote OST with nodsh"
12911
12912         reset_async
12913
12914         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12915         set_nodes_failloc "$(osts_nodes)" 0x20e
12916
12917         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12918         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12919         PID=$!
12920         sleep 5
12921         set_nodes_failloc "$(osts_nodes)" 0
12922
12923         wait $PID
12924         RC=$?
12925         if [[ $RC -ne 0 ]]; then
12926                 error "got error, but should be not, rc=$RC"
12927         fi
12928
12929         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12930         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12931         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12932         if [[ $LOCKED -ne 0 ]]; then
12933                 error "Locked pages remain in cache, locked=$LOCKED"
12934         fi
12935
12936         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12937                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12938         fi
12939
12940         rm -f $DIR/$tfile
12941         echo "No pages locked after fsync"
12942
12943         return 0
12944 }
12945 run_test 118i "Fix error before timeout in recoverable error  =========="
12946
12947 [ "$SLOW" = "no" ] && set_resend_count 4
12948
12949 test_118j() {
12950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12951         remote_ost_nodsh && skip "remote OST with nodsh"
12952
12953         reset_async
12954
12955         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12956         set_nodes_failloc "$(osts_nodes)" 0x220
12957
12958         # return -EIO from OST
12959         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12960         RC=$?
12961         set_nodes_failloc "$(osts_nodes)" 0x0
12962         if [[ $RC -eq 0 ]]; then
12963                 error "Must return error due to dropped pages, rc=$RC"
12964         fi
12965
12966         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12967         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12968         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12969         if [[ $LOCKED -ne 0 ]]; then
12970                 error "Locked pages remain in cache, locked=$LOCKED"
12971         fi
12972
12973         # in recoverable error on OST we want resend and stay until it finished
12974         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12975                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12976         fi
12977
12978         rm -f $DIR/$tfile
12979         echo "No pages locked after fsync"
12980
12981         return 0
12982 }
12983 run_test 118j "Simulate unrecoverable OST side error =========="
12984
12985 test_118k()
12986 {
12987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12988         remote_ost_nodsh && skip "remote OSTs with nodsh"
12989
12990         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12991         set_nodes_failloc "$(osts_nodes)" 0x20e
12992         test_mkdir $DIR/$tdir
12993
12994         for ((i=0;i<10;i++)); do
12995                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12996                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12997                 SLEEPPID=$!
12998                 sleep 0.500s
12999                 kill $SLEEPPID
13000                 wait $SLEEPPID
13001         done
13002
13003         set_nodes_failloc "$(osts_nodes)" 0
13004         rm -rf $DIR/$tdir
13005 }
13006 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13007
13008 test_118l() # LU-646
13009 {
13010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13011
13012         test_mkdir $DIR/$tdir
13013         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13014         rm -rf $DIR/$tdir
13015 }
13016 run_test 118l "fsync dir"
13017
13018 test_118m() # LU-3066
13019 {
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021
13022         test_mkdir $DIR/$tdir
13023         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13024         rm -rf $DIR/$tdir
13025 }
13026 run_test 118m "fdatasync dir ========="
13027
13028 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13029
13030 test_118n()
13031 {
13032         local begin
13033         local end
13034
13035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13036         remote_ost_nodsh && skip "remote OSTs with nodsh"
13037
13038         # Sleep to avoid a cached response.
13039         #define OBD_STATFS_CACHE_SECONDS 1
13040         sleep 2
13041
13042         # Inject a 10 second delay in the OST_STATFS handler.
13043         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13044         set_nodes_failloc "$(osts_nodes)" 0x242
13045
13046         begin=$SECONDS
13047         stat --file-system $MOUNT > /dev/null
13048         end=$SECONDS
13049
13050         set_nodes_failloc "$(osts_nodes)" 0
13051
13052         if ((end - begin > 20)); then
13053             error "statfs took $((end - begin)) seconds, expected 10"
13054         fi
13055 }
13056 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13057
13058 test_119a() # bug 11737
13059 {
13060         BSIZE=$((512 * 1024))
13061         directio write $DIR/$tfile 0 1 $BSIZE
13062         # We ask to read two blocks, which is more than a file size.
13063         # directio will indicate an error when requested and actual
13064         # sizes aren't equeal (a normal situation in this case) and
13065         # print actual read amount.
13066         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13067         if [ "$NOB" != "$BSIZE" ]; then
13068                 error "read $NOB bytes instead of $BSIZE"
13069         fi
13070         rm -f $DIR/$tfile
13071 }
13072 run_test 119a "Short directIO read must return actual read amount"
13073
13074 test_119b() # bug 11737
13075 {
13076         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13077
13078         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13079         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13080         sync
13081         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13082                 error "direct read failed"
13083         rm -f $DIR/$tfile
13084 }
13085 run_test 119b "Sparse directIO read must return actual read amount"
13086
13087 test_119c() # bug 13099
13088 {
13089         BSIZE=1048576
13090         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13091         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13092         rm -f $DIR/$tfile
13093 }
13094 run_test 119c "Testing for direct read hitting hole"
13095
13096 test_119d() # bug 15950
13097 {
13098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13099
13100         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13101         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13102         BSIZE=1048576
13103         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13104         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13105         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13106         lctl set_param fail_loc=0x40d
13107         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13108         pid_dio=$!
13109         sleep 1
13110         cat $DIR/$tfile > /dev/null &
13111         lctl set_param fail_loc=0
13112         pid_reads=$!
13113         wait $pid_dio
13114         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13115         sleep 2
13116         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13117         error "the read rpcs have not completed in 2s"
13118         rm -f $DIR/$tfile
13119         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13120 }
13121 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13122
13123 test_120a() {
13124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13125         remote_mds_nodsh && skip "remote MDS with nodsh"
13126         test_mkdir -i0 -c1 $DIR/$tdir
13127         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13128                 skip_env "no early lock cancel on server"
13129
13130         lru_resize_disable mdc
13131         lru_resize_disable osc
13132         cancel_lru_locks mdc
13133         # asynchronous object destroy at MDT could cause bl ast to client
13134         cancel_lru_locks osc
13135
13136         stat $DIR/$tdir > /dev/null
13137         can1=$(do_facet mds1 \
13138                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13139                awk '/ldlm_cancel/ {print $2}')
13140         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13141                awk '/ldlm_bl_callback/ {print $2}')
13142         test_mkdir -i0 -c1 $DIR/$tdir/d1
13143         can2=$(do_facet mds1 \
13144                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13145                awk '/ldlm_cancel/ {print $2}')
13146         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13147                awk '/ldlm_bl_callback/ {print $2}')
13148         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13149         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13150         lru_resize_enable mdc
13151         lru_resize_enable osc
13152 }
13153 run_test 120a "Early Lock Cancel: mkdir test"
13154
13155 test_120b() {
13156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13157         remote_mds_nodsh && skip "remote MDS with nodsh"
13158         test_mkdir $DIR/$tdir
13159         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13160                 skip_env "no early lock cancel on server"
13161
13162         lru_resize_disable mdc
13163         lru_resize_disable osc
13164         cancel_lru_locks mdc
13165         stat $DIR/$tdir > /dev/null
13166         can1=$(do_facet $SINGLEMDS \
13167                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13168                awk '/ldlm_cancel/ {print $2}')
13169         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13170                awk '/ldlm_bl_callback/ {print $2}')
13171         touch $DIR/$tdir/f1
13172         can2=$(do_facet $SINGLEMDS \
13173                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13174                awk '/ldlm_cancel/ {print $2}')
13175         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13176                awk '/ldlm_bl_callback/ {print $2}')
13177         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13178         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13179         lru_resize_enable mdc
13180         lru_resize_enable osc
13181 }
13182 run_test 120b "Early Lock Cancel: create test"
13183
13184 test_120c() {
13185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13186         remote_mds_nodsh && skip "remote MDS with nodsh"
13187         test_mkdir -i0 -c1 $DIR/$tdir
13188         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13189                 skip "no early lock cancel on server"
13190
13191         lru_resize_disable mdc
13192         lru_resize_disable osc
13193         test_mkdir -i0 -c1 $DIR/$tdir/d1
13194         test_mkdir -i0 -c1 $DIR/$tdir/d2
13195         touch $DIR/$tdir/d1/f1
13196         cancel_lru_locks mdc
13197         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13198         can1=$(do_facet mds1 \
13199                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13200                awk '/ldlm_cancel/ {print $2}')
13201         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13202                awk '/ldlm_bl_callback/ {print $2}')
13203         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13204         can2=$(do_facet mds1 \
13205                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13206                awk '/ldlm_cancel/ {print $2}')
13207         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13208                awk '/ldlm_bl_callback/ {print $2}')
13209         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13210         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13211         lru_resize_enable mdc
13212         lru_resize_enable osc
13213 }
13214 run_test 120c "Early Lock Cancel: link test"
13215
13216 test_120d() {
13217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13218         remote_mds_nodsh && skip "remote MDS with nodsh"
13219         test_mkdir -i0 -c1 $DIR/$tdir
13220         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13221                 skip_env "no early lock cancel on server"
13222
13223         lru_resize_disable mdc
13224         lru_resize_disable osc
13225         touch $DIR/$tdir
13226         cancel_lru_locks mdc
13227         stat $DIR/$tdir > /dev/null
13228         can1=$(do_facet mds1 \
13229                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13230                awk '/ldlm_cancel/ {print $2}')
13231         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13232                awk '/ldlm_bl_callback/ {print $2}')
13233         chmod a+x $DIR/$tdir
13234         can2=$(do_facet mds1 \
13235                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13236                awk '/ldlm_cancel/ {print $2}')
13237         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13238                awk '/ldlm_bl_callback/ {print $2}')
13239         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13240         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13241         lru_resize_enable mdc
13242         lru_resize_enable osc
13243 }
13244 run_test 120d "Early Lock Cancel: setattr test"
13245
13246 test_120e() {
13247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13248         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13249                 skip_env "no early lock cancel on server"
13250         remote_mds_nodsh && skip "remote MDS with nodsh"
13251
13252         local dlmtrace_set=false
13253
13254         test_mkdir -i0 -c1 $DIR/$tdir
13255         lru_resize_disable mdc
13256         lru_resize_disable osc
13257         ! $LCTL get_param debug | grep -q dlmtrace &&
13258                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13259         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13260         cancel_lru_locks mdc
13261         cancel_lru_locks osc
13262         dd if=$DIR/$tdir/f1 of=/dev/null
13263         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13264         # XXX client can not do early lock cancel of OST lock
13265         # during unlink (LU-4206), so cancel osc lock now.
13266         sleep 2
13267         cancel_lru_locks osc
13268         can1=$(do_facet mds1 \
13269                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13270                awk '/ldlm_cancel/ {print $2}')
13271         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13272                awk '/ldlm_bl_callback/ {print $2}')
13273         unlink $DIR/$tdir/f1
13274         sleep 5
13275         can2=$(do_facet mds1 \
13276                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13277                awk '/ldlm_cancel/ {print $2}')
13278         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13279                awk '/ldlm_bl_callback/ {print $2}')
13280         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13281                 $LCTL dk $TMP/cancel.debug.txt
13282         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13283                 $LCTL dk $TMP/blocking.debug.txt
13284         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13285         lru_resize_enable mdc
13286         lru_resize_enable osc
13287 }
13288 run_test 120e "Early Lock Cancel: unlink test"
13289
13290 test_120f() {
13291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13292         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13293                 skip_env "no early lock cancel on server"
13294         remote_mds_nodsh && skip "remote MDS with nodsh"
13295
13296         test_mkdir -i0 -c1 $DIR/$tdir
13297         lru_resize_disable mdc
13298         lru_resize_disable osc
13299         test_mkdir -i0 -c1 $DIR/$tdir/d1
13300         test_mkdir -i0 -c1 $DIR/$tdir/d2
13301         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13302         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13303         cancel_lru_locks mdc
13304         cancel_lru_locks osc
13305         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13306         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13307         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13308         # XXX client can not do early lock cancel of OST lock
13309         # during rename (LU-4206), so cancel osc lock now.
13310         sleep 2
13311         cancel_lru_locks osc
13312         can1=$(do_facet mds1 \
13313                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13314                awk '/ldlm_cancel/ {print $2}')
13315         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13316                awk '/ldlm_bl_callback/ {print $2}')
13317         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13318         sleep 5
13319         can2=$(do_facet mds1 \
13320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13321                awk '/ldlm_cancel/ {print $2}')
13322         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13323                awk '/ldlm_bl_callback/ {print $2}')
13324         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13325         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13326         lru_resize_enable mdc
13327         lru_resize_enable osc
13328 }
13329 run_test 120f "Early Lock Cancel: rename test"
13330
13331 test_120g() {
13332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13333         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13334                 skip_env "no early lock cancel on server"
13335         remote_mds_nodsh && skip "remote MDS with nodsh"
13336
13337         lru_resize_disable mdc
13338         lru_resize_disable osc
13339         count=10000
13340         echo create $count files
13341         test_mkdir $DIR/$tdir
13342         cancel_lru_locks mdc
13343         cancel_lru_locks osc
13344         t0=$(date +%s)
13345
13346         can0=$(do_facet $SINGLEMDS \
13347                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13348                awk '/ldlm_cancel/ {print $2}')
13349         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13350                awk '/ldlm_bl_callback/ {print $2}')
13351         createmany -o $DIR/$tdir/f $count
13352         sync
13353         can1=$(do_facet $SINGLEMDS \
13354                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13355                awk '/ldlm_cancel/ {print $2}')
13356         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13357                awk '/ldlm_bl_callback/ {print $2}')
13358         t1=$(date +%s)
13359         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13360         echo rm $count files
13361         rm -r $DIR/$tdir
13362         sync
13363         can2=$(do_facet $SINGLEMDS \
13364                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13365                awk '/ldlm_cancel/ {print $2}')
13366         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13367                awk '/ldlm_bl_callback/ {print $2}')
13368         t2=$(date +%s)
13369         echo total: $count removes in $((t2-t1))
13370         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13371         sleep 2
13372         # wait for commitment of removal
13373         lru_resize_enable mdc
13374         lru_resize_enable osc
13375 }
13376 run_test 120g "Early Lock Cancel: performance test"
13377
13378 test_121() { #bug #10589
13379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13380
13381         rm -rf $DIR/$tfile
13382         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13383 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13384         lctl set_param fail_loc=0x310
13385         cancel_lru_locks osc > /dev/null
13386         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13387         lctl set_param fail_loc=0
13388         [[ $reads -eq $writes ]] ||
13389                 error "read $reads blocks, must be $writes blocks"
13390 }
13391 run_test 121 "read cancel race ========="
13392
13393 test_123a_base() { # was test 123, statahead(bug 11401)
13394         local lsx="$1"
13395
13396         SLOWOK=0
13397         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13398                 log "testing UP system. Performance may be lower than expected."
13399                 SLOWOK=1
13400         fi
13401         running_in_vm && SLOWOK=1
13402
13403         rm -rf $DIR/$tdir
13404         test_mkdir $DIR/$tdir
13405         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13406         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13407         MULT=10
13408         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13409                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13410
13411                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13412                 lctl set_param -n llite.*.statahead_max 0
13413                 lctl get_param llite.*.statahead_max
13414                 cancel_lru_locks mdc
13415                 cancel_lru_locks osc
13416                 stime=$(date +%s)
13417                 time $lsx $DIR/$tdir | wc -l
13418                 etime=$(date +%s)
13419                 delta=$((etime - stime))
13420                 log "$lsx $i files without statahead: $delta sec"
13421                 lctl set_param llite.*.statahead_max=$max
13422
13423                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13424                          awk '/statahead.wrong:/ { print $NF }')
13425                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13426                 cancel_lru_locks mdc
13427                 cancel_lru_locks osc
13428                 stime=$(date +%s)
13429                 time $lsx $DIR/$tdir | wc -l
13430                 etime=$(date +%s)
13431                 delta_sa=$((etime - stime))
13432                 log "$lsx $i files with statahead: $delta_sa sec"
13433                 lctl get_param -n llite.*.statahead_stats
13434                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13435                          awk '/statahead.wrong:/ { print $NF }')
13436
13437                 [[ $swrong -lt $ewrong ]] &&
13438                         log "statahead was stopped, maybe too many locks held!"
13439                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13440
13441                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13442                         max=$(lctl get_param -n llite.*.statahead_max |
13443                                 head -n 1)
13444                         lctl set_param -n llite.*.statahead_max 0
13445                         lctl get_param llite.*.statahead_max
13446                         cancel_lru_locks mdc
13447                         cancel_lru_locks osc
13448                         stime=$(date +%s)
13449                         time $lsx $DIR/$tdir | wc -l
13450                         etime=$(date +%s)
13451                         delta=$((etime - stime))
13452                         log "$lsx $i files again without statahead: $delta sec"
13453                         lctl set_param llite.*.statahead_max=$max
13454                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13455                                 if [ $SLOWOK -eq 0 ]; then
13456                                         error "$lsx $i files is slower with statahead!"
13457                                 else
13458                                         log "$lsx $i files is slower with statahead!"
13459                                 fi
13460                                 break
13461                         fi
13462                 fi
13463
13464                 [ $delta -gt 20 ] && break
13465                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13466                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13467         done
13468         log "$lsx done"
13469
13470         stime=$(date +%s)
13471         rm -r $DIR/$tdir
13472         sync
13473         etime=$(date +%s)
13474         delta=$((etime - stime))
13475         log "rm -r $DIR/$tdir/: $delta seconds"
13476         log "rm done"
13477         lctl get_param -n llite.*.statahead_stats
13478 }
13479
13480 test_123aa() {
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482
13483         test_123a_base "ls -l"
13484 }
13485 run_test 123aa "verify statahead work"
13486
13487 test_123ab() {
13488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13489
13490         statx_supported || skip_env "Test must be statx() syscall supported"
13491
13492         test_123a_base "$STATX -l"
13493 }
13494 run_test 123ab "verify statahead work by using statx"
13495
13496 test_123ac() {
13497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13498
13499         statx_supported || skip_env "Test must be statx() syscall supported"
13500
13501         local rpcs_before
13502         local rpcs_after
13503         local agl_before
13504         local agl_after
13505
13506         cancel_lru_locks $OSC
13507         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13508         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13509                      awk '/agl.total:/ { print $NF }')
13510         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13511         test_123a_base "$STATX --cached=always -D"
13512         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13513                     awk '/agl.total:/ { print $NF }')
13514         [ $agl_before -eq $agl_after ] ||
13515                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13516         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13517         [ $rpcs_after -eq $rpcs_before ] ||
13518                 error "$STATX should not send glimpse RPCs to $OSC"
13519 }
13520 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13521
13522 test_123b () { # statahead(bug 15027)
13523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13524
13525         test_mkdir $DIR/$tdir
13526         createmany -o $DIR/$tdir/$tfile-%d 1000
13527
13528         cancel_lru_locks mdc
13529         cancel_lru_locks osc
13530
13531 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13532         lctl set_param fail_loc=0x80000803
13533         ls -lR $DIR/$tdir > /dev/null
13534         log "ls done"
13535         lctl set_param fail_loc=0x0
13536         lctl get_param -n llite.*.statahead_stats
13537         rm -r $DIR/$tdir
13538         sync
13539
13540 }
13541 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13542
13543 test_123c() {
13544         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13545
13546         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13547         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13548         touch $DIR/$tdir.1/{1..3}
13549         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13550
13551         remount_client $MOUNT
13552
13553         $MULTIOP $DIR/$tdir.0 Q
13554
13555         # let statahead to complete
13556         ls -l $DIR/$tdir.0 > /dev/null
13557
13558         testid=$(echo $TESTNAME | tr '_' ' ')
13559         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13560                 error "statahead warning" || true
13561 }
13562 run_test 123c "Can not initialize inode warning on DNE statahead"
13563
13564 test_123d() {
13565         local num=100
13566         local swrong
13567         local ewrong
13568
13569         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13570         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13571                 error "setdirstripe $DIR/$tdir failed"
13572         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13573         remount_client $MOUNT
13574         $LCTL get_param llite.*.statahead_max
13575         $LCTL set_param llite.*.statahead_stats=0 ||
13576                 error "clear statahead_stats failed"
13577         swrong=$(lctl get_param -n llite.*.statahead_stats |
13578                  awk '/statahead.wrong:/ { print $NF }')
13579         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13580         # wait for statahead thread finished to update hit/miss stats.
13581         sleep 1
13582         $LCTL get_param -n llite.*.statahead_stats
13583         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13584                  awk '/statahead.wrong:/ { print $NF }')
13585         (( $swrong == $ewrong )) ||
13586                 log "statahead was stopped, maybe too many locks held!"
13587 }
13588 run_test 123d "Statahead on striped directories works correctly"
13589
13590 test_124a() {
13591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13592         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13593                 skip_env "no lru resize on server"
13594
13595         local NR=2000
13596
13597         test_mkdir $DIR/$tdir
13598
13599         log "create $NR files at $DIR/$tdir"
13600         createmany -o $DIR/$tdir/f $NR ||
13601                 error "failed to create $NR files in $DIR/$tdir"
13602
13603         cancel_lru_locks mdc
13604         ls -l $DIR/$tdir > /dev/null
13605
13606         local NSDIR=""
13607         local LRU_SIZE=0
13608         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13609                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13610                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13611                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13612                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13613                         log "NSDIR=$NSDIR"
13614                         log "NS=$(basename $NSDIR)"
13615                         break
13616                 fi
13617         done
13618
13619         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13620                 skip "Not enough cached locks created!"
13621         fi
13622         log "LRU=$LRU_SIZE"
13623
13624         local SLEEP=30
13625
13626         # We know that lru resize allows one client to hold $LIMIT locks
13627         # for 10h. After that locks begin to be killed by client.
13628         local MAX_HRS=10
13629         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13630         log "LIMIT=$LIMIT"
13631         if [ $LIMIT -lt $LRU_SIZE ]; then
13632                 skip "Limit is too small $LIMIT"
13633         fi
13634
13635         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13636         # killing locks. Some time was spent for creating locks. This means
13637         # that up to the moment of sleep finish we must have killed some of
13638         # them (10-100 locks). This depends on how fast ther were created.
13639         # Many of them were touched in almost the same moment and thus will
13640         # be killed in groups.
13641         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13642
13643         # Use $LRU_SIZE_B here to take into account real number of locks
13644         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13645         local LRU_SIZE_B=$LRU_SIZE
13646         log "LVF=$LVF"
13647         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13648         log "OLD_LVF=$OLD_LVF"
13649         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13650
13651         # Let's make sure that we really have some margin. Client checks
13652         # cached locks every 10 sec.
13653         SLEEP=$((SLEEP+20))
13654         log "Sleep ${SLEEP} sec"
13655         local SEC=0
13656         while ((SEC<$SLEEP)); do
13657                 echo -n "..."
13658                 sleep 5
13659                 SEC=$((SEC+5))
13660                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13661                 echo -n "$LRU_SIZE"
13662         done
13663         echo ""
13664         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13665         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13666
13667         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13668                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13669                 unlinkmany $DIR/$tdir/f $NR
13670                 return
13671         }
13672
13673         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13674         log "unlink $NR files at $DIR/$tdir"
13675         unlinkmany $DIR/$tdir/f $NR
13676 }
13677 run_test 124a "lru resize ======================================="
13678
13679 get_max_pool_limit()
13680 {
13681         local limit=$($LCTL get_param \
13682                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13683         local max=0
13684         for l in $limit; do
13685                 if [[ $l -gt $max ]]; then
13686                         max=$l
13687                 fi
13688         done
13689         echo $max
13690 }
13691
13692 test_124b() {
13693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13694         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13695                 skip_env "no lru resize on server"
13696
13697         LIMIT=$(get_max_pool_limit)
13698
13699         NR=$(($(default_lru_size)*20))
13700         if [[ $NR -gt $LIMIT ]]; then
13701                 log "Limit lock number by $LIMIT locks"
13702                 NR=$LIMIT
13703         fi
13704
13705         IFree=$(mdsrate_inodes_available)
13706         if [ $IFree -lt $NR ]; then
13707                 log "Limit lock number by $IFree inodes"
13708                 NR=$IFree
13709         fi
13710
13711         lru_resize_disable mdc
13712         test_mkdir -p $DIR/$tdir/disable_lru_resize
13713
13714         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13715         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13716         cancel_lru_locks mdc
13717         stime=`date +%s`
13718         PID=""
13719         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13720         PID="$PID $!"
13721         sleep 2
13722         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13723         PID="$PID $!"
13724         sleep 2
13725         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13726         PID="$PID $!"
13727         wait $PID
13728         etime=`date +%s`
13729         nolruresize_delta=$((etime-stime))
13730         log "ls -la time: $nolruresize_delta seconds"
13731         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13732         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13733
13734         lru_resize_enable mdc
13735         test_mkdir -p $DIR/$tdir/enable_lru_resize
13736
13737         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13738         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13739         cancel_lru_locks mdc
13740         stime=`date +%s`
13741         PID=""
13742         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13743         PID="$PID $!"
13744         sleep 2
13745         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13746         PID="$PID $!"
13747         sleep 2
13748         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13749         PID="$PID $!"
13750         wait $PID
13751         etime=`date +%s`
13752         lruresize_delta=$((etime-stime))
13753         log "ls -la time: $lruresize_delta seconds"
13754         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13755
13756         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13757                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13758         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13759                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13760         else
13761                 log "lru resize performs the same with no lru resize"
13762         fi
13763         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13764 }
13765 run_test 124b "lru resize (performance test) ======================="
13766
13767 test_124c() {
13768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13769         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13770                 skip_env "no lru resize on server"
13771
13772         # cache ununsed locks on client
13773         local nr=100
13774         cancel_lru_locks mdc
13775         test_mkdir $DIR/$tdir
13776         createmany -o $DIR/$tdir/f $nr ||
13777                 error "failed to create $nr files in $DIR/$tdir"
13778         ls -l $DIR/$tdir > /dev/null
13779
13780         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13781         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13782         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13783         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13784         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13785
13786         # set lru_max_age to 1 sec
13787         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13788         echo "sleep $((recalc_p * 2)) seconds..."
13789         sleep $((recalc_p * 2))
13790
13791         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13792         # restore lru_max_age
13793         $LCTL set_param -n $nsdir.lru_max_age $max_age
13794         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13795         unlinkmany $DIR/$tdir/f $nr
13796 }
13797 run_test 124c "LRUR cancel very aged locks"
13798
13799 test_124d() {
13800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13801         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13802                 skip_env "no lru resize on server"
13803
13804         # cache ununsed locks on client
13805         local nr=100
13806
13807         lru_resize_disable mdc
13808         stack_trap "lru_resize_enable mdc" EXIT
13809
13810         cancel_lru_locks mdc
13811
13812         # asynchronous object destroy at MDT could cause bl ast to client
13813         test_mkdir $DIR/$tdir
13814         createmany -o $DIR/$tdir/f $nr ||
13815                 error "failed to create $nr files in $DIR/$tdir"
13816         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13817
13818         ls -l $DIR/$tdir > /dev/null
13819
13820         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13821         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13822         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13823         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13824
13825         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13826
13827         # set lru_max_age to 1 sec
13828         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13829         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13830
13831         echo "sleep $((recalc_p * 2)) seconds..."
13832         sleep $((recalc_p * 2))
13833
13834         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13835
13836         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13837 }
13838 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13839
13840 test_125() { # 13358
13841         $LCTL get_param -n llite.*.client_type | grep -q local ||
13842                 skip "must run as local client"
13843         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13844                 skip_env "must have acl enabled"
13845         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13846
13847         test_mkdir $DIR/$tdir
13848         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13849         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13850                 error "setfacl $DIR/$tdir failed"
13851         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13852 }
13853 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13854
13855 test_126() { # bug 12829/13455
13856         $GSS && skip_env "must run as gss disabled"
13857         $LCTL get_param -n llite.*.client_type | grep -q local ||
13858                 skip "must run as local client"
13859         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13860
13861         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13862         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13863         rm -f $DIR/$tfile
13864         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13865 }
13866 run_test 126 "check that the fsgid provided by the client is taken into account"
13867
13868 test_127a() { # bug 15521
13869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13870         local name count samp unit min max sum sumsq
13871         local tmpfile=$TMP/$tfile.tmp
13872
13873         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13874         echo "stats before reset"
13875         stack_trap "rm -f $tmpfile"
13876         local now=$(date +%s)
13877
13878         $LCTL get_param osc.*.stats | tee $tmpfile
13879
13880         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13881         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13882         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13883         local uptime=$(awk '{ print $1 }' /proc/uptime)
13884
13885         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13886         (( ${snapshot_time%\.*} >= $now - 5 &&
13887            ${snapshot_time%\.*} <= $now + 5 )) ||
13888                 error "snapshot_time=$snapshot_time != now=$now"
13889         # elapsed _should_ be from mount, but at least less than uptime
13890         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13891                 error "elapsed=$elapsed > uptime=$uptime"
13892         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13893            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13894                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13895
13896         $LCTL set_param osc.*.stats=0
13897         local reset=$(date +%s)
13898         local fsize=$((2048 * 1024))
13899
13900         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13901         cancel_lru_locks osc
13902         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13903
13904         now=$(date +%s)
13905         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13906         while read name count samp unit min max sum sumsq; do
13907                 [[ "$samp" == "samples" ]] || continue
13908
13909                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13910                 [ ! $min ] && error "Missing min value for $name proc entry"
13911                 eval $name=$count || error "Wrong proc format"
13912
13913                 case $name in
13914                 read_bytes|write_bytes)
13915                         [[ "$unit" =~ "bytes" ]] ||
13916                                 error "unit is not 'bytes': $unit"
13917                         (( $min >= 4096 )) || error "min is too small: $min"
13918                         (( $min <= $fsize )) || error "min is too big: $min"
13919                         (( $max >= 4096 )) || error "max is too small: $max"
13920                         (( $max <= $fsize )) || error "max is too big: $max"
13921                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13922                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13923                                 error "sumsquare is too small: $sumsq"
13924                         (( $sumsq <= $fsize * $fsize )) ||
13925                                 error "sumsquare is too big: $sumsq"
13926                         ;;
13927                 ost_read|ost_write)
13928                         [[ "$unit" =~ "usec" ]] ||
13929                                 error "unit is not 'usec': $unit"
13930                         ;;
13931                 *)      ;;
13932                 esac
13933         done < $tmpfile
13934
13935         #check that we actually got some stats
13936         [ "$read_bytes" ] || error "Missing read_bytes stats"
13937         [ "$write_bytes" ] || error "Missing write_bytes stats"
13938         [ "$read_bytes" != 0 ] || error "no read done"
13939         [ "$write_bytes" != 0 ] || error "no write done"
13940
13941         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13942         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13943         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13944
13945         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13946         (( ${snapshot_time%\.*} >= $now - 5 &&
13947            ${snapshot_time%\.*} <= $now + 5 )) ||
13948                 error "reset snapshot_time=$snapshot_time != now=$now"
13949         # elapsed should be from time of stats reset
13950         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13951            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13952                 error "reset elapsed=$elapsed > $now - $reset"
13953         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13954            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13955                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13956 }
13957 run_test 127a "verify the client stats are sane"
13958
13959 test_127b() { # bug LU-333
13960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13961         local name count samp unit min max sum sumsq
13962
13963         echo "stats before reset"
13964         $LCTL get_param llite.*.stats
13965         $LCTL set_param llite.*.stats=0
13966
13967         # perform 2 reads and writes so MAX is different from SUM.
13968         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13969         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13970         cancel_lru_locks osc
13971         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13972         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13973
13974         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13975         stack_trap "rm -f $TMP/$tfile.tmp"
13976         while read name count samp unit min max sum sumsq; do
13977                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13978                 eval $name=$count || error "Wrong proc format"
13979
13980                 case $name in
13981                 read_bytes|write_bytes)
13982                         [[ "$unit" =~ "bytes" ]] ||
13983                                 error "unit is not 'bytes': $unit"
13984                         (( $count == 2 )) || error "count is not 2: $count"
13985                         (( $min == $PAGE_SIZE )) ||
13986                                 error "min is not $PAGE_SIZE: $min"
13987                         (( $max == $PAGE_SIZE )) ||
13988                                 error "max is not $PAGE_SIZE: $max"
13989                         (( $sum == $PAGE_SIZE * 2 )) ||
13990                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13991                         ;;
13992                 read|write)
13993                         [[ "$unit" =~ "usec" ]] ||
13994                                 error "unit is not 'usec': $unit"
13995                         ;;
13996                 *)      ;;
13997                 esac
13998         done < $TMP/$tfile.tmp
13999
14000         #check that we actually got some stats
14001         [ "$read_bytes" ] || error "Missing read_bytes stats"
14002         [ "$write_bytes" ] || error "Missing write_bytes stats"
14003         [ "$read_bytes" != 0 ] || error "no read done"
14004         [ "$write_bytes" != 0 ] || error "no write done"
14005 }
14006 run_test 127b "verify the llite client stats are sane"
14007
14008 test_127c() { # LU-12394
14009         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14010         local size
14011         local bsize
14012         local reads
14013         local writes
14014         local count
14015
14016         $LCTL set_param llite.*.extents_stats=1
14017         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14018
14019         # Use two stripes so there is enough space in default config
14020         $LFS setstripe -c 2 $DIR/$tfile
14021
14022         # Extent stats start at 0-4K and go in power of two buckets
14023         # LL_HIST_START = 12 --> 2^12 = 4K
14024         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14025         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14026         # small configs
14027         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14028                 do
14029                 # Write and read, 2x each, second time at a non-zero offset
14030                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14031                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14032                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14033                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14034                 rm -f $DIR/$tfile
14035         done
14036
14037         $LCTL get_param llite.*.extents_stats
14038
14039         count=2
14040         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14041                 do
14042                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14043                                 grep -m 1 $bsize)
14044                 reads=$(echo $bucket | awk '{print $5}')
14045                 writes=$(echo $bucket | awk '{print $9}')
14046                 [ "$reads" -eq $count ] ||
14047                         error "$reads reads in < $bsize bucket, expect $count"
14048                 [ "$writes" -eq $count ] ||
14049                         error "$writes writes in < $bsize bucket, expect $count"
14050         done
14051
14052         # Test mmap write and read
14053         $LCTL set_param llite.*.extents_stats=c
14054         size=512
14055         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14056         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14057         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14058
14059         $LCTL get_param llite.*.extents_stats
14060
14061         count=$(((size*1024) / PAGE_SIZE))
14062
14063         bsize=$((2 * PAGE_SIZE / 1024))K
14064
14065         bucket=$($LCTL get_param -n llite.*.extents_stats |
14066                         grep -m 1 $bsize)
14067         reads=$(echo $bucket | awk '{print $5}')
14068         writes=$(echo $bucket | awk '{print $9}')
14069         # mmap writes fault in the page first, creating an additonal read
14070         [ "$reads" -eq $((2 * count)) ] ||
14071                 error "$reads reads in < $bsize bucket, expect $count"
14072         [ "$writes" -eq $count ] ||
14073                 error "$writes writes in < $bsize bucket, expect $count"
14074 }
14075 run_test 127c "test llite extent stats with regular & mmap i/o"
14076
14077 test_128() { # bug 15212
14078         touch $DIR/$tfile
14079         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14080                 find $DIR/$tfile
14081                 find $DIR/$tfile
14082         EOF
14083
14084         result=$(grep error $TMP/$tfile.log)
14085         rm -f $DIR/$tfile $TMP/$tfile.log
14086         [ -z "$result" ] ||
14087                 error "consecutive find's under interactive lfs failed"
14088 }
14089 run_test 128 "interactive lfs for 2 consecutive find's"
14090
14091 set_dir_limits () {
14092         local mntdev
14093         local canondev
14094         local node
14095
14096         local ldproc=/proc/fs/ldiskfs
14097         local facets=$(get_facets MDS)
14098
14099         for facet in ${facets//,/ }; do
14100                 canondev=$(ldiskfs_canon \
14101                            *.$(convert_facet2label $facet).mntdev $facet)
14102                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14103                         ldproc=/sys/fs/ldiskfs
14104                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14105                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14106         done
14107 }
14108
14109 check_mds_dmesg() {
14110         local facets=$(get_facets MDS)
14111         for facet in ${facets//,/ }; do
14112                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14113         done
14114         return 1
14115 }
14116
14117 test_129() {
14118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14119         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14120                 skip "Need MDS version with at least 2.5.56"
14121         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14122                 skip_env "ldiskfs only test"
14123         fi
14124         remote_mds_nodsh && skip "remote MDS with nodsh"
14125
14126         local ENOSPC=28
14127         local has_warning=false
14128
14129         rm -rf $DIR/$tdir
14130         mkdir -p $DIR/$tdir
14131
14132         # block size of mds1
14133         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14134         set_dir_limits $maxsize $((maxsize * 6 / 8))
14135         stack_trap "set_dir_limits 0 0"
14136         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14137         local dirsize=$(stat -c%s "$DIR/$tdir")
14138         local nfiles=0
14139         while (( $dirsize <= $maxsize )); do
14140                 $MCREATE $DIR/$tdir/file_base_$nfiles
14141                 rc=$?
14142                 # check two errors:
14143                 # ENOSPC for ext4 max_dir_size, which has been used since
14144                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14145                 if (( rc == ENOSPC )); then
14146                         set_dir_limits 0 0
14147                         echo "rc=$rc returned as expected after $nfiles files"
14148
14149                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14150                                 error "create failed w/o dir size limit"
14151
14152                         # messages may be rate limited if test is run repeatedly
14153                         check_mds_dmesg '"is approaching max"' ||
14154                                 echo "warning message should be output"
14155                         check_mds_dmesg '"has reached max"' ||
14156                                 echo "reached message should be output"
14157
14158                         dirsize=$(stat -c%s "$DIR/$tdir")
14159
14160                         [[ $dirsize -ge $maxsize ]] && return 0
14161                         error "dirsize $dirsize < $maxsize after $nfiles files"
14162                 elif (( rc != 0 )); then
14163                         break
14164                 fi
14165                 nfiles=$((nfiles + 1))
14166                 dirsize=$(stat -c%s "$DIR/$tdir")
14167         done
14168
14169         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14170 }
14171 run_test 129 "test directory size limit ========================"
14172
14173 OLDIFS="$IFS"
14174 cleanup_130() {
14175         trap 0
14176         IFS="$OLDIFS"
14177 }
14178
14179 test_130a() {
14180         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14181         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14182
14183         trap cleanup_130 EXIT RETURN
14184
14185         local fm_file=$DIR/$tfile
14186         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14187         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14188                 error "dd failed for $fm_file"
14189
14190         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14191         filefrag -ves $fm_file
14192         local rc=$?
14193         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14194                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14195         (( $rc == 0 )) || error "filefrag $fm_file failed"
14196
14197         filefrag_op=$(filefrag -ve -k $fm_file |
14198                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14199         local lun=$($LFS getstripe -i $fm_file)
14200
14201         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14202         IFS=$'\n'
14203         local tot_len=0
14204         for line in $filefrag_op; do
14205                 local frag_lun=$(echo $line | cut -d: -f5)
14206                 local ext_len=$(echo $line | cut -d: -f4)
14207
14208                 if (( $frag_lun != $lun )); then
14209                         error "FIEMAP on 1-stripe file($fm_file) failed"
14210                         return
14211                 fi
14212                 (( tot_len += ext_len ))
14213         done
14214
14215         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14216                 error "FIEMAP on 1-stripe file($fm_file) failed"
14217                 return
14218         fi
14219
14220         echo "FIEMAP on single striped file succeeded"
14221 }
14222 run_test 130a "FIEMAP (1-stripe file)"
14223
14224 test_130b() {
14225         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14226
14227         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14228         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14229         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14230                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14231
14232         trap cleanup_130 EXIT RETURN
14233
14234         local fm_file=$DIR/$tfile
14235         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14236                 error "setstripe on $fm_file"
14237
14238         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14239                 error "dd failed on $fm_file"
14240
14241         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14242         filefrag_op=$(filefrag -ve -k $fm_file |
14243                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14244
14245         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14246                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14247
14248         IFS=$'\n'
14249         local tot_len=0
14250         local num_luns=1
14251
14252         for line in $filefrag_op; do
14253                 local frag_lun=$(echo $line | cut -d: -f5 |
14254                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14255                 local ext_len=$(echo $line | cut -d: -f4)
14256                 if (( $frag_lun != $last_lun )); then
14257                         if (( tot_len != 1024 )); then
14258                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14259                                 return
14260                         else
14261                                 (( num_luns += 1 ))
14262                                 tot_len=0
14263                         fi
14264                 fi
14265                 (( tot_len += ext_len ))
14266                 last_lun=$frag_lun
14267         done
14268         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14269                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14270                 return
14271         fi
14272
14273         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14274 }
14275 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14276
14277 test_130c() {
14278         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14279
14280         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14281         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14282         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14283                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14284
14285         trap cleanup_130 EXIT RETURN
14286
14287         local fm_file=$DIR/$tfile
14288         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14289
14290         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14291                 error "dd failed on $fm_file"
14292
14293         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14294         filefrag_op=$(filefrag -ve -k $fm_file |
14295                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14296
14297         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14298                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14299
14300         IFS=$'\n'
14301         local tot_len=0
14302         local num_luns=1
14303         for line in $filefrag_op; do
14304                 local frag_lun=$(echo $line | cut -d: -f5 |
14305                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14306                 local ext_len=$(echo $line | cut -d: -f4)
14307                 if (( $frag_lun != $last_lun )); then
14308                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14309                         if (( logical != 512 )); then
14310                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14311                                 return
14312                         fi
14313                         if (( tot_len != 512 )); then
14314                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14315                                 return
14316                         else
14317                                 (( num_luns += 1 ))
14318                                 tot_len=0
14319                         fi
14320                 fi
14321                 (( tot_len += ext_len ))
14322                 last_lun=$frag_lun
14323         done
14324         if (( num_luns != 2 || tot_len != 512 )); then
14325                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14326                 return
14327         fi
14328
14329         echo "FIEMAP on 2-stripe file with hole succeeded"
14330 }
14331 run_test 130c "FIEMAP (2-stripe file with hole)"
14332
14333 test_130d() {
14334         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14335
14336         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14337         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14338         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14339                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14340
14341         trap cleanup_130 EXIT RETURN
14342
14343         local fm_file=$DIR/$tfile
14344         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14345                         error "setstripe on $fm_file"
14346
14347         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14348         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14349                 error "dd failed on $fm_file"
14350
14351         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14352         filefrag_op=$(filefrag -ve -k $fm_file |
14353                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14354
14355         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14356                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14357
14358         IFS=$'\n'
14359         local tot_len=0
14360         local num_luns=1
14361         for line in $filefrag_op; do
14362                 local frag_lun=$(echo $line | cut -d: -f5 |
14363                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14364                 local ext_len=$(echo $line | cut -d: -f4)
14365                 if (( $frag_lun != $last_lun )); then
14366                         if (( tot_len != 1024 )); then
14367                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14368                                 return
14369                         else
14370                                 (( num_luns += 1 ))
14371                                 local tot_len=0
14372                         fi
14373                 fi
14374                 (( tot_len += ext_len ))
14375                 last_lun=$frag_lun
14376         done
14377         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14378                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14379                 return
14380         fi
14381
14382         echo "FIEMAP on N-stripe file succeeded"
14383 }
14384 run_test 130d "FIEMAP (N-stripe file)"
14385
14386 test_130e() {
14387         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14388
14389         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14390         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14391         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14392                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14393
14394         trap cleanup_130 EXIT RETURN
14395
14396         local fm_file=$DIR/$tfile
14397         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14398
14399         local num_blks=512
14400         local expected_len=$(( (num_blks / 2) * 64 ))
14401         for ((i = 0; i < $num_blks; i++)); do
14402                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14403                         conv=notrunc > /dev/null 2>&1
14404         done
14405
14406         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14407         filefrag_op=$(filefrag -ve -k $fm_file |
14408                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14409
14410         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14411
14412         IFS=$'\n'
14413         local tot_len=0
14414         local num_luns=1
14415         for line in $filefrag_op; do
14416                 local frag_lun=$(echo $line | cut -d: -f5)
14417                 local ext_len=$(echo $line | cut -d: -f4)
14418                 if (( $frag_lun != $last_lun )); then
14419                         if (( tot_len != $expected_len )); then
14420                                 error "OST$last_lun $tot_len != $expected_len"
14421                         else
14422                                 (( num_luns += 1 ))
14423                                 tot_len=0
14424                         fi
14425                 fi
14426                 (( tot_len += ext_len ))
14427                 last_lun=$frag_lun
14428         done
14429         if (( num_luns != 2 || tot_len != $expected_len )); then
14430                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14431         fi
14432
14433         echo "FIEMAP with continuation calls succeeded"
14434 }
14435 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14436
14437 test_130f() {
14438         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14439         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14440         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14441                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14442
14443         local fm_file=$DIR/$tfile
14444         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14445                 error "multiop create with lov_delay_create on $fm_file"
14446
14447         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14448         filefrag_extents=$(filefrag -vek $fm_file |
14449                            awk '/extents? found/ { print $2 }')
14450         if (( $filefrag_extents != 0 )); then
14451                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14452         fi
14453
14454         rm -f $fm_file
14455 }
14456 run_test 130f "FIEMAP (unstriped file)"
14457
14458 test_130g() {
14459         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14460                 skip "Need MDS version with at least 2.12.53 for overstriping"
14461         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14462         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14463         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14464                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14465
14466         local file=$DIR/$tfile
14467         local nr=$((OSTCOUNT * 100))
14468
14469         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14470
14471         stack_trap "rm -f $file"
14472         dd if=/dev/zero of=$file count=$nr bs=1M
14473         sync
14474         nr=$($LFS getstripe -c $file)
14475
14476         local extents=$(filefrag -v $file |
14477                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14478
14479         echo "filefrag list $extents extents in file with stripecount $nr"
14480         if (( extents < nr )); then
14481                 $LFS getstripe $file
14482                 filefrag -v $file
14483                 error "filefrag printed $extents < $nr extents"
14484         fi
14485 }
14486 run_test 130g "FIEMAP (overstripe file)"
14487
14488 # Test for writev/readv
14489 test_131a() {
14490         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14491                 error "writev test failed"
14492         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14493                 error "readv failed"
14494         rm -f $DIR/$tfile
14495 }
14496 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14497
14498 test_131b() {
14499         local fsize=$((524288 + 1048576 + 1572864))
14500         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14501                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14502                         error "append writev test failed"
14503
14504         ((fsize += 1572864 + 1048576))
14505         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14506                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14507                         error "append writev test failed"
14508         rm -f $DIR/$tfile
14509 }
14510 run_test 131b "test append writev"
14511
14512 test_131c() {
14513         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14514         error "NOT PASS"
14515 }
14516 run_test 131c "test read/write on file w/o objects"
14517
14518 test_131d() {
14519         rwv -f $DIR/$tfile -w -n 1 1572864
14520         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14521         if [ "$NOB" != 1572864 ]; then
14522                 error "Short read filed: read $NOB bytes instead of 1572864"
14523         fi
14524         rm -f $DIR/$tfile
14525 }
14526 run_test 131d "test short read"
14527
14528 test_131e() {
14529         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14530         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14531         error "read hitting hole failed"
14532         rm -f $DIR/$tfile
14533 }
14534 run_test 131e "test read hitting hole"
14535
14536 check_stats() {
14537         local facet=$1
14538         local op=$2
14539         local want=${3:-0}
14540         local res
14541
14542         # open             11 samples [usecs] 468 4793 13658 35791898
14543         case $facet in
14544         mds*) res=($(do_facet $facet \
14545                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14546                  ;;
14547         ost*) res=($(do_facet $facet \
14548                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14549                  ;;
14550         *) error "Wrong facet '$facet'" ;;
14551         esac
14552         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14553         # if $want is zero, it means any stat increment is ok.
14554         if (( $want > 0 )); then
14555                 local count=${res[1]}
14556
14557                 if (( $count != $want )); then
14558                         if [[ $facet =~ "mds" ]]; then
14559                                 do_nodes $(comma_list $(mdts_nodes)) \
14560                                         $LCTL get_param mdt.*.md_stats
14561                         else
14562                                 do_nodes $(comma_list $(osts-nodes)) \
14563                                         $LCTL get_param obdfilter.*.stats
14564                         fi
14565                         error "The $op counter on $facet is $count, not $want"
14566                 fi
14567         fi
14568 }
14569
14570 test_133a() {
14571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14572         remote_ost_nodsh && skip "remote OST with nodsh"
14573         remote_mds_nodsh && skip "remote MDS with nodsh"
14574         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14575                 skip_env "MDS doesn't support rename stats"
14576
14577         local testdir=$DIR/${tdir}/stats_testdir
14578
14579         mkdir -p $DIR/${tdir}
14580
14581         # clear stats.
14582         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14583         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14584
14585         # verify mdt stats first.
14586         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14587         check_stats $SINGLEMDS "mkdir" 1
14588
14589         # clear "open" from "lfs mkdir" above
14590         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14591         touch ${testdir}/${tfile} || error "touch failed"
14592         check_stats $SINGLEMDS "open" 1
14593         check_stats $SINGLEMDS "close" 1
14594         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14595                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14596                 check_stats $SINGLEMDS "mknod" 2
14597         }
14598         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14599         check_stats $SINGLEMDS "unlink" 1
14600         rm -f ${testdir}/${tfile} || error "file remove failed"
14601         check_stats $SINGLEMDS "unlink" 2
14602
14603         # remove working dir and check mdt stats again.
14604         rmdir ${testdir} || error "rmdir failed"
14605         check_stats $SINGLEMDS "rmdir" 1
14606
14607         local testdir1=$DIR/${tdir}/stats_testdir1
14608         mkdir_on_mdt0 -p ${testdir}
14609         mkdir_on_mdt0 -p ${testdir1}
14610         touch ${testdir1}/test1
14611         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14612         check_stats $SINGLEMDS "crossdir_rename" 1
14613
14614         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14615         check_stats $SINGLEMDS "samedir_rename" 1
14616
14617         rm -rf $DIR/${tdir}
14618 }
14619 run_test 133a "Verifying MDT stats ========================================"
14620
14621 test_133b() {
14622         local res
14623
14624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14625         remote_ost_nodsh && skip "remote OST with nodsh"
14626         remote_mds_nodsh && skip "remote MDS with nodsh"
14627
14628         local testdir=$DIR/${tdir}/stats_testdir
14629
14630         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14631         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14632         touch ${testdir}/${tfile} || error "touch failed"
14633         cancel_lru_locks mdc
14634
14635         # clear stats.
14636         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14637         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14638
14639         # extra mdt stats verification.
14640         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14641         check_stats $SINGLEMDS "setattr" 1
14642         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14643         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14644         then            # LU-1740
14645                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14646                 check_stats $SINGLEMDS "getattr" 1
14647         fi
14648         rm -rf $DIR/${tdir}
14649
14650         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14651         # so the check below is not reliable
14652         [ $MDSCOUNT -eq 1 ] || return 0
14653
14654         # Sleep to avoid a cached response.
14655         #define OBD_STATFS_CACHE_SECONDS 1
14656         sleep 2
14657         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14658         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14659         $LFS df || error "lfs failed"
14660         check_stats $SINGLEMDS "statfs" 1
14661
14662         # check aggregated statfs (LU-10018)
14663         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14664                 return 0
14665         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14666                 return 0
14667         sleep 2
14668         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14669         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14670         df $DIR
14671         check_stats $SINGLEMDS "statfs" 1
14672
14673         # We want to check that the client didn't send OST_STATFS to
14674         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14675         # extra care is needed here.
14676         if remote_mds; then
14677                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14678                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14679
14680                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14681                 [ "$res" ] && error "OST got STATFS"
14682         fi
14683
14684         return 0
14685 }
14686 run_test 133b "Verifying extra MDT stats =================================="
14687
14688 test_133c() {
14689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14690         remote_ost_nodsh && skip "remote OST with nodsh"
14691         remote_mds_nodsh && skip "remote MDS with nodsh"
14692
14693         local testdir=$DIR/$tdir/stats_testdir
14694
14695         test_mkdir -p $testdir
14696
14697         # verify obdfilter stats.
14698         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14699         sync
14700         cancel_lru_locks osc
14701         wait_delete_completed
14702
14703         # clear stats.
14704         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14705         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14706
14707         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14708                 error "dd failed"
14709         sync
14710         cancel_lru_locks osc
14711         check_stats ost1 "write" 1
14712
14713         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14714         check_stats ost1 "read" 1
14715
14716         > $testdir/$tfile || error "truncate failed"
14717         check_stats ost1 "punch" 1
14718
14719         rm -f $testdir/$tfile || error "file remove failed"
14720         wait_delete_completed
14721         check_stats ost1 "destroy" 1
14722
14723         rm -rf $DIR/$tdir
14724 }
14725 run_test 133c "Verifying OST stats ========================================"
14726
14727 order_2() {
14728         local value=$1
14729         local orig=$value
14730         local order=1
14731
14732         while [ $value -ge 2 ]; do
14733                 order=$((order*2))
14734                 value=$((value/2))
14735         done
14736
14737         if [ $orig -gt $order ]; then
14738                 order=$((order*2))
14739         fi
14740         echo $order
14741 }
14742
14743 size_in_KMGT() {
14744     local value=$1
14745     local size=('K' 'M' 'G' 'T');
14746     local i=0
14747     local size_string=$value
14748
14749     while [ $value -ge 1024 ]; do
14750         if [ $i -gt 3 ]; then
14751             #T is the biggest unit we get here, if that is bigger,
14752             #just return XXXT
14753             size_string=${value}T
14754             break
14755         fi
14756         value=$((value >> 10))
14757         if [ $value -lt 1024 ]; then
14758             size_string=${value}${size[$i]}
14759             break
14760         fi
14761         i=$((i + 1))
14762     done
14763
14764     echo $size_string
14765 }
14766
14767 get_rename_size() {
14768         local size=$1
14769         local context=${2:-.}
14770         local sample=$(do_facet $SINGLEMDS $LCTL \
14771                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14772                 grep -A1 $context |
14773                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14774         echo $sample
14775 }
14776
14777 test_133d() {
14778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14779         remote_ost_nodsh && skip "remote OST with nodsh"
14780         remote_mds_nodsh && skip "remote MDS with nodsh"
14781         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14782                 skip_env "MDS doesn't support rename stats"
14783
14784         local testdir1=$DIR/${tdir}/stats_testdir1
14785         local testdir2=$DIR/${tdir}/stats_testdir2
14786         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14787
14788         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14789
14790         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14791         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14792
14793         createmany -o $testdir1/test 512 || error "createmany failed"
14794
14795         # check samedir rename size
14796         mv ${testdir1}/test0 ${testdir1}/test_0
14797
14798         local testdir1_size=$(ls -l $DIR/${tdir} |
14799                 awk '/stats_testdir1/ {print $5}')
14800         local testdir2_size=$(ls -l $DIR/${tdir} |
14801                 awk '/stats_testdir2/ {print $5}')
14802
14803         testdir1_size=$(order_2 $testdir1_size)
14804         testdir2_size=$(order_2 $testdir2_size)
14805
14806         testdir1_size=$(size_in_KMGT $testdir1_size)
14807         testdir2_size=$(size_in_KMGT $testdir2_size)
14808
14809         echo "source rename dir size: ${testdir1_size}"
14810         echo "target rename dir size: ${testdir2_size}"
14811
14812         local cmd="do_facet $SINGLEMDS $LCTL "
14813         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14814
14815         eval $cmd || error "$cmd failed"
14816         local samedir=$($cmd | grep 'same_dir')
14817         local same_sample=$(get_rename_size $testdir1_size)
14818         [ -z "$samedir" ] && error "samedir_rename_size count error"
14819         [[ $same_sample -eq 1 ]] ||
14820                 error "samedir_rename_size error $same_sample"
14821         echo "Check same dir rename stats success"
14822
14823         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14824
14825         # check crossdir rename size
14826         mv ${testdir1}/test_0 ${testdir2}/test_0
14827
14828         testdir1_size=$(ls -l $DIR/${tdir} |
14829                 awk '/stats_testdir1/ {print $5}')
14830         testdir2_size=$(ls -l $DIR/${tdir} |
14831                 awk '/stats_testdir2/ {print $5}')
14832
14833         testdir1_size=$(order_2 $testdir1_size)
14834         testdir2_size=$(order_2 $testdir2_size)
14835
14836         testdir1_size=$(size_in_KMGT $testdir1_size)
14837         testdir2_size=$(size_in_KMGT $testdir2_size)
14838
14839         echo "source rename dir size: ${testdir1_size}"
14840         echo "target rename dir size: ${testdir2_size}"
14841
14842         eval $cmd || error "$cmd failed"
14843         local crossdir=$($cmd | grep 'crossdir')
14844         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14845         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14846         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14847         [[ $src_sample -eq 1 ]] ||
14848                 error "crossdir_rename_size error $src_sample"
14849         [[ $tgt_sample -eq 1 ]] ||
14850                 error "crossdir_rename_size error $tgt_sample"
14851         echo "Check cross dir rename stats success"
14852         rm -rf $DIR/${tdir}
14853 }
14854 run_test 133d "Verifying rename_stats ========================================"
14855
14856 test_133e() {
14857         remote_mds_nodsh && skip "remote MDS with nodsh"
14858         remote_ost_nodsh && skip "remote OST with nodsh"
14859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14860
14861         local testdir=$DIR/${tdir}/stats_testdir
14862         local ctr f0 f1 bs=32768 count=42 sum
14863
14864         mkdir -p ${testdir} || error "mkdir failed"
14865
14866         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14867
14868         for ctr in {write,read}_bytes; do
14869                 sync
14870                 cancel_lru_locks osc
14871
14872                 do_facet ost1 $LCTL set_param -n \
14873                         "obdfilter.*.exports.clear=clear"
14874
14875                 if [ $ctr = write_bytes ]; then
14876                         f0=/dev/zero
14877                         f1=${testdir}/${tfile}
14878                 else
14879                         f0=${testdir}/${tfile}
14880                         f1=/dev/null
14881                 fi
14882
14883                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14884                         error "dd failed"
14885                 sync
14886                 cancel_lru_locks osc
14887
14888                 sum=$(do_facet ost1 $LCTL get_param \
14889                         "obdfilter.*.exports.*.stats" |
14890                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14891                                 $1 == ctr { sum += $7 }
14892                                 END { printf("%0.0f", sum) }')
14893
14894                 if ((sum != bs * count)); then
14895                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14896                 fi
14897         done
14898
14899         rm -rf $DIR/${tdir}
14900 }
14901 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14902
14903 test_133f() {
14904         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14905                 skip "too old lustre for get_param -R ($facet_ver)"
14906
14907         # verifying readability.
14908         $LCTL get_param -R '*' &> /dev/null
14909
14910         # Verifing writability with badarea_io.
14911         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14912         local skipped_params='force_lbug|changelog_mask|daemon_file'
14913         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14914                 egrep -v "$skipped_params" |
14915                 xargs -n 1 find $proc_dirs -name |
14916                 xargs -n 1 badarea_io ||
14917                 error "client badarea_io failed"
14918
14919         # remount the FS in case writes/reads /proc break the FS
14920         cleanup || error "failed to unmount"
14921         setup || error "failed to setup"
14922 }
14923 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14924
14925 test_133g() {
14926         remote_mds_nodsh && skip "remote MDS with nodsh"
14927         remote_ost_nodsh && skip "remote OST with nodsh"
14928
14929         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14930         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14931         local facet
14932         for facet in mds1 ost1; do
14933                 local facet_ver=$(lustre_version_code $facet)
14934                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14935                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14936                 else
14937                         log "$facet: too old lustre for get_param -R"
14938                 fi
14939                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14940                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14941                                 tr -d = | egrep -v $skipped_params |
14942                                 xargs -n 1 find $proc_dirs -name |
14943                                 xargs -n 1 badarea_io" ||
14944                                         error "$facet badarea_io failed"
14945                 else
14946                         skip_noexit "$facet: too old lustre for get_param -R"
14947                 fi
14948         done
14949
14950         # remount the FS in case writes/reads /proc break the FS
14951         cleanup || error "failed to unmount"
14952         setup || error "failed to setup"
14953 }
14954 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14955
14956 test_133h() {
14957         remote_mds_nodsh && skip "remote MDS with nodsh"
14958         remote_ost_nodsh && skip "remote OST with nodsh"
14959         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14960                 skip "Need MDS version at least 2.9.54"
14961
14962         local facet
14963         for facet in client mds1 ost1; do
14964                 # Get the list of files that are missing the terminating newline
14965                 local plist=$(do_facet $facet
14966                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14967                 local ent
14968                 for ent in $plist; do
14969                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14970                                 awk -v FS='\v' -v RS='\v\v' \
14971                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14972                                         print FILENAME}'" 2>/dev/null)
14973                         [ -z $missing ] || {
14974                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14975                                 error "file does not end with newline: $facet-$ent"
14976                         }
14977                 done
14978         done
14979 }
14980 run_test 133h "Proc files should end with newlines"
14981
14982 test_134a() {
14983         remote_mds_nodsh && skip "remote MDS with nodsh"
14984         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14985                 skip "Need MDS version at least 2.7.54"
14986
14987         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14988         cancel_lru_locks mdc
14989
14990         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14991         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14992         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14993
14994         local nr=1000
14995         createmany -o $DIR/$tdir/f $nr ||
14996                 error "failed to create $nr files in $DIR/$tdir"
14997         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14998
14999         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15000         do_facet mds1 $LCTL set_param fail_loc=0x327
15001         do_facet mds1 $LCTL set_param fail_val=500
15002         touch $DIR/$tdir/m
15003
15004         echo "sleep 10 seconds ..."
15005         sleep 10
15006         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15007
15008         do_facet mds1 $LCTL set_param fail_loc=0
15009         do_facet mds1 $LCTL set_param fail_val=0
15010         [ $lck_cnt -lt $unused ] ||
15011                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15012
15013         rm $DIR/$tdir/m
15014         unlinkmany $DIR/$tdir/f $nr
15015 }
15016 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15017
15018 test_134b() {
15019         remote_mds_nodsh && skip "remote MDS with nodsh"
15020         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15021                 skip "Need MDS version at least 2.7.54"
15022
15023         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15024         cancel_lru_locks mdc
15025
15026         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15027                         ldlm.lock_reclaim_threshold_mb)
15028         # disable reclaim temporarily
15029         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15030
15031         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15032         do_facet mds1 $LCTL set_param fail_loc=0x328
15033         do_facet mds1 $LCTL set_param fail_val=500
15034
15035         $LCTL set_param debug=+trace
15036
15037         local nr=600
15038         createmany -o $DIR/$tdir/f $nr &
15039         local create_pid=$!
15040
15041         echo "Sleep $TIMEOUT seconds ..."
15042         sleep $TIMEOUT
15043         if ! ps -p $create_pid  > /dev/null 2>&1; then
15044                 do_facet mds1 $LCTL set_param fail_loc=0
15045                 do_facet mds1 $LCTL set_param fail_val=0
15046                 do_facet mds1 $LCTL set_param \
15047                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15048                 error "createmany finished incorrectly!"
15049         fi
15050         do_facet mds1 $LCTL set_param fail_loc=0
15051         do_facet mds1 $LCTL set_param fail_val=0
15052         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15053         wait $create_pid || return 1
15054
15055         unlinkmany $DIR/$tdir/f $nr
15056 }
15057 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15058
15059 test_135() {
15060         remote_mds_nodsh && skip "remote MDS with nodsh"
15061         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15062                 skip "Need MDS version at least 2.13.50"
15063         local fname
15064
15065         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15066
15067 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15068         #set only one record at plain llog
15069         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15070
15071         #fill already existed plain llog each 64767
15072         #wrapping whole catalog
15073         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15074
15075         createmany -o $DIR/$tdir/$tfile_ 64700
15076         for (( i = 0; i < 64700; i = i + 2 ))
15077         do
15078                 rm $DIR/$tdir/$tfile_$i &
15079                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15080                 local pid=$!
15081                 wait $pid
15082         done
15083
15084         #waiting osp synchronization
15085         wait_delete_completed
15086 }
15087 run_test 135 "Race catalog processing"
15088
15089 test_136() {
15090         remote_mds_nodsh && skip "remote MDS with nodsh"
15091         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15092                 skip "Need MDS version at least 2.13.50"
15093         local fname
15094
15095         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15096         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15097         #set only one record at plain llog
15098 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15099         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15100
15101         #fill already existed 2 plain llogs each 64767
15102         #wrapping whole catalog
15103         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15104         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15105         wait_delete_completed
15106
15107         createmany -o $DIR/$tdir/$tfile_ 10
15108         sleep 25
15109
15110         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15111         for (( i = 0; i < 10; i = i + 3 ))
15112         do
15113                 rm $DIR/$tdir/$tfile_$i &
15114                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15115                 local pid=$!
15116                 wait $pid
15117                 sleep 7
15118                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15119         done
15120
15121         #waiting osp synchronization
15122         wait_delete_completed
15123 }
15124 run_test 136 "Race catalog processing 2"
15125
15126 test_140() { #bug-17379
15127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15128
15129         test_mkdir $DIR/$tdir
15130         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15131         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15132
15133         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15134         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15135         local i=0
15136         while i=$((i + 1)); do
15137                 test_mkdir $i
15138                 cd $i || error "Changing to $i"
15139                 ln -s ../stat stat || error "Creating stat symlink"
15140                 # Read the symlink until ELOOP present,
15141                 # not LBUGing the system is considered success,
15142                 # we didn't overrun the stack.
15143                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15144                 if [ $ret -ne 0 ]; then
15145                         if [ $ret -eq 40 ]; then
15146                                 break  # -ELOOP
15147                         else
15148                                 error "Open stat symlink"
15149                                         return
15150                         fi
15151                 fi
15152         done
15153         i=$((i - 1))
15154         echo "The symlink depth = $i"
15155         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15156                 error "Invalid symlink depth"
15157
15158         # Test recursive symlink
15159         ln -s symlink_self symlink_self
15160         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15161         echo "open symlink_self returns $ret"
15162         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15163 }
15164 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15165
15166 test_150a() {
15167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15168
15169         local TF="$TMP/$tfile"
15170
15171         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15172         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15173         cp $TF $DIR/$tfile
15174         cancel_lru_locks $OSC
15175         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15176         remount_client $MOUNT
15177         df -P $MOUNT
15178         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15179
15180         $TRUNCATE $TF 6000
15181         $TRUNCATE $DIR/$tfile 6000
15182         cancel_lru_locks $OSC
15183         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15184
15185         echo "12345" >>$TF
15186         echo "12345" >>$DIR/$tfile
15187         cancel_lru_locks $OSC
15188         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15189
15190         echo "12345" >>$TF
15191         echo "12345" >>$DIR/$tfile
15192         cancel_lru_locks $OSC
15193         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15194 }
15195 run_test 150a "truncate/append tests"
15196
15197 test_150b() {
15198         check_set_fallocate_or_skip
15199         local out
15200
15201         touch $DIR/$tfile
15202         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15203         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15204                 skip_eopnotsupp "$out|check_fallocate failed"
15205 }
15206 run_test 150b "Verify fallocate (prealloc) functionality"
15207
15208 test_150bb() {
15209         check_set_fallocate_or_skip
15210
15211         touch $DIR/$tfile
15212         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15213         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15214         > $DIR/$tfile
15215         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15216         # precomputed md5sum for 20MB of zeroes
15217         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15218         local sum=($(md5sum $DIR/$tfile))
15219
15220         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15221
15222         check_set_fallocate 1
15223
15224         > $DIR/$tfile
15225         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15226         sum=($(md5sum $DIR/$tfile))
15227
15228         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15229 }
15230 run_test 150bb "Verify fallocate modes both zero space"
15231
15232 test_150c() {
15233         check_set_fallocate_or_skip
15234         local striping="-c2"
15235
15236         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15237         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15238         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15239         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15240         local want=$((OSTCOUNT * 1048576))
15241
15242         # Must allocate all requested space, not more than 5% extra
15243         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15244                 error "bytes $bytes is not $want"
15245
15246         rm -f $DIR/$tfile
15247
15248         echo "verify fallocate on PFL file"
15249
15250         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15251
15252         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15253                 error "Create $DIR/$tfile failed"
15254         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15255         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15256         want=$((512 * 1048576))
15257
15258         # Must allocate all requested space, not more than 5% extra
15259         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15260                 error "bytes $bytes is not $want"
15261 }
15262 run_test 150c "Verify fallocate Size and Blocks"
15263
15264 test_150d() {
15265         check_set_fallocate_or_skip
15266         local striping="-c2"
15267
15268         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15269
15270         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15271         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15272                 error "setstripe failed"
15273         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15274         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15275         local want=$((OSTCOUNT * 1048576))
15276
15277         # Must allocate all requested space, not more than 5% extra
15278         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15279                 error "bytes $bytes is not $want"
15280 }
15281 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15282
15283 test_150e() {
15284         check_set_fallocate_or_skip
15285
15286         echo "df before:"
15287         $LFS df
15288         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15289         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15290                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15291
15292         # Find OST with Minimum Size
15293         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15294                        sort -un | head -1)
15295
15296         # Get 100MB per OST of the available space to reduce run time
15297         # else 60% of the available space if we are running SLOW tests
15298         if [ $SLOW == "no" ]; then
15299                 local space=$((1024 * 100 * OSTCOUNT))
15300         else
15301                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15302         fi
15303
15304         fallocate -l${space}k $DIR/$tfile ||
15305                 error "fallocate ${space}k $DIR/$tfile failed"
15306         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15307
15308         # get size immediately after fallocate. This should be correctly
15309         # updated
15310         local size=$(stat -c '%s' $DIR/$tfile)
15311         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15312
15313         # Sleep for a while for statfs to get updated. And not pull from cache.
15314         sleep 2
15315
15316         echo "df after fallocate:"
15317         $LFS df
15318
15319         (( size / 1024 == space )) || error "size $size != requested $space"
15320         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15321                 error "used $used < space $space"
15322
15323         rm $DIR/$tfile || error "rm failed"
15324         sync
15325         wait_delete_completed
15326
15327         echo "df after unlink:"
15328         $LFS df
15329 }
15330 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15331
15332 test_150f() {
15333         local size
15334         local blocks
15335         local want_size_before=20480 # in bytes
15336         local want_blocks_before=40 # 512 sized blocks
15337         local want_blocks_after=24  # 512 sized blocks
15338         local length=$(((want_blocks_before - want_blocks_after) * 512))
15339
15340         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15341                 skip "need at least 2.14.0 for fallocate punch"
15342
15343         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15344                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15345         fi
15346
15347         check_set_fallocate_or_skip
15348         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15349
15350         [[ "x$DOM" == "xyes" ]] &&
15351                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15352
15353         echo "Verify fallocate punch: Range within the file range"
15354         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15355                 error "dd failed for bs 4096 and count 5"
15356
15357         # Call fallocate with punch range which is within the file range
15358         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15359                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15360         # client must see changes immediately after fallocate
15361         size=$(stat -c '%s' $DIR/$tfile)
15362         blocks=$(stat -c '%b' $DIR/$tfile)
15363
15364         # Verify punch worked.
15365         (( blocks == want_blocks_after )) ||
15366                 error "punch failed: blocks $blocks != $want_blocks_after"
15367
15368         (( size == want_size_before )) ||
15369                 error "punch failed: size $size != $want_size_before"
15370
15371         # Verify there is hole in file
15372         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15373         # precomputed md5sum
15374         local expect="4a9a834a2db02452929c0a348273b4aa"
15375
15376         cksum=($(md5sum $DIR/$tfile))
15377         [[ "${cksum[0]}" == "$expect" ]] ||
15378                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15379
15380         # Start second sub-case for fallocate punch.
15381         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15382         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15383                 error "dd failed for bs 4096 and count 5"
15384
15385         # Punch range less than block size will have no change in block count
15386         want_blocks_after=40  # 512 sized blocks
15387
15388         # Punch overlaps two blocks and less than blocksize
15389         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15390                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15391         size=$(stat -c '%s' $DIR/$tfile)
15392         blocks=$(stat -c '%b' $DIR/$tfile)
15393
15394         # Verify punch worked.
15395         (( blocks == want_blocks_after )) ||
15396                 error "punch failed: blocks $blocks != $want_blocks_after"
15397
15398         (( size == want_size_before )) ||
15399                 error "punch failed: size $size != $want_size_before"
15400
15401         # Verify if range is really zero'ed out. We expect Zeros.
15402         # precomputed md5sum
15403         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15404         cksum=($(md5sum $DIR/$tfile))
15405         [[ "${cksum[0]}" == "$expect" ]] ||
15406                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15407 }
15408 run_test 150f "Verify fallocate punch functionality"
15409
15410 test_150g() {
15411         local space
15412         local size
15413         local blocks
15414         local blocks_after
15415         local size_after
15416         local BS=4096 # Block size in bytes
15417
15418         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15419                 skip "need at least 2.14.0 for fallocate punch"
15420
15421         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15422                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15423         fi
15424
15425         check_set_fallocate_or_skip
15426         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15427
15428         if [[ "x$DOM" == "xyes" ]]; then
15429                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15430                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15431         else
15432                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15433                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15434         fi
15435
15436         # Get 100MB per OST of the available space to reduce run time
15437         # else 60% of the available space if we are running SLOW tests
15438         if [ $SLOW == "no" ]; then
15439                 space=$((1024 * 100 * OSTCOUNT))
15440         else
15441                 # Find OST with Minimum Size
15442                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15443                         sort -un | head -1)
15444                 echo "min size OST: $space"
15445                 space=$(((space * 60)/100 * OSTCOUNT))
15446         fi
15447         # space in 1k units, round to 4k blocks
15448         local blkcount=$((space * 1024 / $BS))
15449
15450         echo "Verify fallocate punch: Very large Range"
15451         fallocate -l${space}k $DIR/$tfile ||
15452                 error "fallocate ${space}k $DIR/$tfile failed"
15453         # write 1M at the end, start and in the middle
15454         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15455                 error "dd failed: bs $BS count 256"
15456         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15457                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15458         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15459                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15460
15461         # Gather stats.
15462         size=$(stat -c '%s' $DIR/$tfile)
15463
15464         # gather punch length.
15465         local punch_size=$((size - (BS * 2)))
15466
15467         echo "punch_size = $punch_size"
15468         echo "size - punch_size: $((size - punch_size))"
15469         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15470
15471         # Call fallocate to punch all except 2 blocks. We leave the
15472         # first and the last block
15473         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15474         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15475                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15476
15477         size_after=$(stat -c '%s' $DIR/$tfile)
15478         blocks_after=$(stat -c '%b' $DIR/$tfile)
15479
15480         # Verify punch worked.
15481         # Size should be kept
15482         (( size == size_after )) ||
15483                 error "punch failed: size $size != $size_after"
15484
15485         # two 4k data blocks to remain plus possible 1 extra extent block
15486         (( blocks_after <= ((BS / 512) * 3) )) ||
15487                 error "too many blocks remains: $blocks_after"
15488
15489         # Verify that file has hole between the first and the last blocks
15490         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15491         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15492
15493         echo "Hole at [$hole_start, $hole_end)"
15494         (( hole_start == BS )) ||
15495                 error "no hole at offset $BS after punch"
15496
15497         (( hole_end == BS + punch_size )) ||
15498                 error "data at offset $hole_end < $((BS + punch_size))"
15499 }
15500 run_test 150g "Verify fallocate punch on large range"
15501
15502 test_150h() {
15503         local file=$DIR/$tfile
15504         local size
15505
15506         check_set_fallocate_or_skip
15507         statx_supported || skip_env "Test must be statx() syscall supported"
15508
15509         # fallocate() does not update the size information on the MDT
15510         fallocate -l 16K $file || error "failed to fallocate $file"
15511         cancel_lru_locks $OSC
15512         # STATX with cached-always mode will not send glimpse RPCs to OST,
15513         # it uses the caching attrs on the client side as much as possible.
15514         size=$($STATX --cached=always -c %s $file)
15515         [ $size == 16384 ] ||
15516                 error "size after fallocate() is $size, expected 16384"
15517 }
15518 run_test 150h "Verify extend fallocate updates the file size"
15519
15520 #LU-2902 roc_hit was not able to read all values from lproc
15521 function roc_hit_init() {
15522         local list=$(comma_list $(osts_nodes))
15523         local dir=$DIR/$tdir-check
15524         local file=$dir/$tfile
15525         local BEFORE
15526         local AFTER
15527         local idx
15528
15529         test_mkdir $dir
15530         #use setstripe to do a write to every ost
15531         for i in $(seq 0 $((OSTCOUNT-1))); do
15532                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15533                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15534                 idx=$(printf %04x $i)
15535                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15536                         awk '$1 == "cache_access" {sum += $7}
15537                                 END { printf("%0.0f", sum) }')
15538
15539                 cancel_lru_locks osc
15540                 cat $file >/dev/null
15541
15542                 AFTER=$(get_osd_param $list *OST*$idx stats |
15543                         awk '$1 == "cache_access" {sum += $7}
15544                                 END { printf("%0.0f", sum) }')
15545
15546                 echo BEFORE:$BEFORE AFTER:$AFTER
15547                 if ! let "AFTER - BEFORE == 4"; then
15548                         rm -rf $dir
15549                         error "roc_hit is not safe to use"
15550                 fi
15551                 rm $file
15552         done
15553
15554         rm -rf $dir
15555 }
15556
15557 function roc_hit() {
15558         local list=$(comma_list $(osts_nodes))
15559         echo $(get_osd_param $list '' stats |
15560                 awk '$1 == "cache_hit" {sum += $7}
15561                         END { printf("%0.0f", sum) }')
15562 }
15563
15564 function set_cache() {
15565         local on=1
15566
15567         if [ "$2" == "off" ]; then
15568                 on=0;
15569         fi
15570         local list=$(comma_list $(osts_nodes))
15571         set_osd_param $list '' $1_cache_enable $on
15572
15573         cancel_lru_locks osc
15574 }
15575
15576 test_151() {
15577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15578         remote_ost_nodsh && skip "remote OST with nodsh"
15579
15580         local CPAGES=3
15581         local list=$(comma_list $(osts_nodes))
15582
15583         # check whether obdfilter is cache capable at all
15584         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15585                 skip "not cache-capable obdfilter"
15586         fi
15587
15588         # check cache is enabled on all obdfilters
15589         if get_osd_param $list '' read_cache_enable | grep 0; then
15590                 skip "oss cache is disabled"
15591         fi
15592
15593         set_osd_param $list '' writethrough_cache_enable 1
15594
15595         # check write cache is enabled on all obdfilters
15596         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15597                 skip "oss write cache is NOT enabled"
15598         fi
15599
15600         roc_hit_init
15601
15602         #define OBD_FAIL_OBD_NO_LRU  0x609
15603         do_nodes $list $LCTL set_param fail_loc=0x609
15604
15605         # pages should be in the case right after write
15606         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15607                 error "dd failed"
15608
15609         local BEFORE=$(roc_hit)
15610         cancel_lru_locks osc
15611         cat $DIR/$tfile >/dev/null
15612         local AFTER=$(roc_hit)
15613
15614         do_nodes $list $LCTL set_param fail_loc=0
15615
15616         if ! let "AFTER - BEFORE == CPAGES"; then
15617                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15618         fi
15619
15620         cancel_lru_locks osc
15621         # invalidates OST cache
15622         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15623         set_osd_param $list '' read_cache_enable 0
15624         cat $DIR/$tfile >/dev/null
15625
15626         # now data shouldn't be found in the cache
15627         BEFORE=$(roc_hit)
15628         cancel_lru_locks osc
15629         cat $DIR/$tfile >/dev/null
15630         AFTER=$(roc_hit)
15631         if let "AFTER - BEFORE != 0"; then
15632                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15633         fi
15634
15635         set_osd_param $list '' read_cache_enable 1
15636         rm -f $DIR/$tfile
15637 }
15638 run_test 151 "test cache on oss and controls ==============================="
15639
15640 test_152() {
15641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15642
15643         local TF="$TMP/$tfile"
15644
15645         # simulate ENOMEM during write
15646 #define OBD_FAIL_OST_NOMEM      0x226
15647         lctl set_param fail_loc=0x80000226
15648         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15649         cp $TF $DIR/$tfile
15650         sync || error "sync failed"
15651         lctl set_param fail_loc=0
15652
15653         # discard client's cache
15654         cancel_lru_locks osc
15655
15656         # simulate ENOMEM during read
15657         lctl set_param fail_loc=0x80000226
15658         cmp $TF $DIR/$tfile || error "cmp failed"
15659         lctl set_param fail_loc=0
15660
15661         rm -f $TF
15662 }
15663 run_test 152 "test read/write with enomem ============================"
15664
15665 test_153() {
15666         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15667 }
15668 run_test 153 "test if fdatasync does not crash ======================="
15669
15670 dot_lustre_fid_permission_check() {
15671         local fid=$1
15672         local ffid=$MOUNT/.lustre/fid/$fid
15673         local test_dir=$2
15674
15675         echo "stat fid $fid"
15676         stat $ffid || error "stat $ffid failed."
15677         echo "touch fid $fid"
15678         touch $ffid || error "touch $ffid failed."
15679         echo "write to fid $fid"
15680         cat /etc/hosts > $ffid || error "write $ffid failed."
15681         echo "read fid $fid"
15682         diff /etc/hosts $ffid || error "read $ffid failed."
15683         echo "append write to fid $fid"
15684         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15685         echo "rename fid $fid"
15686         mv $ffid $test_dir/$tfile.1 &&
15687                 error "rename $ffid to $tfile.1 should fail."
15688         touch $test_dir/$tfile.1
15689         mv $test_dir/$tfile.1 $ffid &&
15690                 error "rename $tfile.1 to $ffid should fail."
15691         rm -f $test_dir/$tfile.1
15692         echo "truncate fid $fid"
15693         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15694         echo "link fid $fid"
15695         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15696         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15697                 echo "setfacl fid $fid"
15698                 setfacl -R -m u:$USER0:rwx $ffid ||
15699                         error "setfacl $ffid failed"
15700                 echo "getfacl fid $fid"
15701                 getfacl $ffid || error "getfacl $ffid failed."
15702         fi
15703         echo "unlink fid $fid"
15704         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15705         echo "mknod fid $fid"
15706         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15707
15708         fid=[0xf00000400:0x1:0x0]
15709         ffid=$MOUNT/.lustre/fid/$fid
15710
15711         echo "stat non-exist fid $fid"
15712         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15713         echo "write to non-exist fid $fid"
15714         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15715         echo "link new fid $fid"
15716         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15717
15718         mkdir -p $test_dir/$tdir
15719         touch $test_dir/$tdir/$tfile
15720         fid=$($LFS path2fid $test_dir/$tdir)
15721         rc=$?
15722         [ $rc -ne 0 ] &&
15723                 error "error: could not get fid for $test_dir/$dir/$tfile."
15724
15725         ffid=$MOUNT/.lustre/fid/$fid
15726
15727         echo "ls $fid"
15728         ls $ffid || error "ls $ffid failed."
15729         echo "touch $fid/$tfile.1"
15730         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15731
15732         echo "touch $MOUNT/.lustre/fid/$tfile"
15733         touch $MOUNT/.lustre/fid/$tfile && \
15734                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15735
15736         echo "setxattr to $MOUNT/.lustre/fid"
15737         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15738
15739         echo "listxattr for $MOUNT/.lustre/fid"
15740         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15741
15742         echo "delxattr from $MOUNT/.lustre/fid"
15743         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15744
15745         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15746         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15747                 error "touch invalid fid should fail."
15748
15749         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15750         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15751                 error "touch non-normal fid should fail."
15752
15753         echo "rename $tdir to $MOUNT/.lustre/fid"
15754         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15755                 error "rename to $MOUNT/.lustre/fid should fail."
15756
15757         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15758         then            # LU-3547
15759                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15760                 local new_obf_mode=777
15761
15762                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15763                 chmod $new_obf_mode $DIR/.lustre/fid ||
15764                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15765
15766                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15767                 [ $obf_mode -eq $new_obf_mode ] ||
15768                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15769
15770                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15771                 chmod $old_obf_mode $DIR/.lustre/fid ||
15772                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15773         fi
15774
15775         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15776         fid=$($LFS path2fid $test_dir/$tfile-2)
15777
15778         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15779         then # LU-5424
15780                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15781                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15782                         error "create lov data thru .lustre failed"
15783         fi
15784         echo "cp /etc/passwd $test_dir/$tfile-2"
15785         cp /etc/passwd $test_dir/$tfile-2 ||
15786                 error "copy to $test_dir/$tfile-2 failed."
15787         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15788         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15789                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15790
15791         rm -rf $test_dir/tfile.lnk
15792         rm -rf $test_dir/$tfile-2
15793 }
15794
15795 test_154A() {
15796         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15797                 skip "Need MDS version at least 2.4.1"
15798
15799         local tf=$DIR/$tfile
15800         touch $tf
15801
15802         local fid=$($LFS path2fid $tf)
15803         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15804
15805         # check that we get the same pathname back
15806         local rootpath
15807         local found
15808         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15809                 echo "$rootpath $fid"
15810                 found=$($LFS fid2path $rootpath "$fid")
15811                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15812                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15813         done
15814
15815         # check wrong root path format
15816         rootpath=$MOUNT"_wrong"
15817         found=$($LFS fid2path $rootpath "$fid")
15818         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15819 }
15820 run_test 154A "lfs path2fid and fid2path basic checks"
15821
15822 test_154B() {
15823         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15824                 skip "Need MDS version at least 2.4.1"
15825
15826         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15827         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15828         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15829         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15830
15831         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15832         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15833
15834         # check that we get the same pathname
15835         echo "PFID: $PFID, name: $name"
15836         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15837         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15838         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15839                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15840
15841         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15842 }
15843 run_test 154B "verify the ll_decode_linkea tool"
15844
15845 test_154a() {
15846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15847         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15848         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15849                 skip "Need MDS version at least 2.2.51"
15850         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15851
15852         cp /etc/hosts $DIR/$tfile
15853
15854         fid=$($LFS path2fid $DIR/$tfile)
15855         rc=$?
15856         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15857
15858         dot_lustre_fid_permission_check "$fid" $DIR ||
15859                 error "dot lustre permission check $fid failed"
15860
15861         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15862
15863         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15864
15865         touch $MOUNT/.lustre/file &&
15866                 error "creation is not allowed under .lustre"
15867
15868         mkdir $MOUNT/.lustre/dir &&
15869                 error "mkdir is not allowed under .lustre"
15870
15871         rm -rf $DIR/$tfile
15872 }
15873 run_test 154a "Open-by-FID"
15874
15875 test_154b() {
15876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15877         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15879         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15880                 skip "Need MDS version at least 2.2.51"
15881
15882         local remote_dir=$DIR/$tdir/remote_dir
15883         local MDTIDX=1
15884         local rc=0
15885
15886         mkdir -p $DIR/$tdir
15887         $LFS mkdir -i $MDTIDX $remote_dir ||
15888                 error "create remote directory failed"
15889
15890         cp /etc/hosts $remote_dir/$tfile
15891
15892         fid=$($LFS path2fid $remote_dir/$tfile)
15893         rc=$?
15894         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15895
15896         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15897                 error "dot lustre permission check $fid failed"
15898         rm -rf $DIR/$tdir
15899 }
15900 run_test 154b "Open-by-FID for remote directory"
15901
15902 test_154c() {
15903         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15904                 skip "Need MDS version at least 2.4.1"
15905
15906         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15907         local FID1=$($LFS path2fid $DIR/$tfile.1)
15908         local FID2=$($LFS path2fid $DIR/$tfile.2)
15909         local FID3=$($LFS path2fid $DIR/$tfile.3)
15910
15911         local N=1
15912         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15913                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15914                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15915                 local want=FID$N
15916                 [ "$FID" = "${!want}" ] ||
15917                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15918                 N=$((N + 1))
15919         done
15920
15921         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15922         do
15923                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15924                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15925                 N=$((N + 1))
15926         done
15927 }
15928 run_test 154c "lfs path2fid and fid2path multiple arguments"
15929
15930 test_154d() {
15931         remote_mds_nodsh && skip "remote MDS with nodsh"
15932         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15933                 skip "Need MDS version at least 2.5.53"
15934
15935         if remote_mds; then
15936                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15937         else
15938                 nid="0@lo"
15939         fi
15940         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15941         local fd
15942         local cmd
15943
15944         rm -f $DIR/$tfile
15945         touch $DIR/$tfile
15946
15947         local fid=$($LFS path2fid $DIR/$tfile)
15948         # Open the file
15949         fd=$(free_fd)
15950         cmd="exec $fd<$DIR/$tfile"
15951         eval $cmd
15952         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15953         echo "$fid_list" | grep "$fid"
15954         rc=$?
15955
15956         cmd="exec $fd>/dev/null"
15957         eval $cmd
15958         if [ $rc -ne 0 ]; then
15959                 error "FID $fid not found in open files list $fid_list"
15960         fi
15961 }
15962 run_test 154d "Verify open file fid"
15963
15964 test_154e()
15965 {
15966         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15967                 skip "Need MDS version at least 2.6.50"
15968
15969         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15970                 error ".lustre returned by readdir"
15971         fi
15972 }
15973 run_test 154e ".lustre is not returned by readdir"
15974
15975 test_154f() {
15976         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15977
15978         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15979         mkdir_on_mdt0 $DIR/$tdir
15980         # test dirs inherit from its stripe
15981         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15982         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15983         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15984         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15985         touch $DIR/f
15986
15987         # get fid of parents
15988         local FID0=$($LFS path2fid $DIR/$tdir)
15989         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15990         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15991         local FID3=$($LFS path2fid $DIR)
15992
15993         # check that path2fid --parents returns expected <parent_fid>/name
15994         # 1) test for a directory (single parent)
15995         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15996         [ "$parent" == "$FID0/foo1" ] ||
15997                 error "expected parent: $FID0/foo1, got: $parent"
15998
15999         # 2) test for a file with nlink > 1 (multiple parents)
16000         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16001         echo "$parent" | grep -F "$FID1/$tfile" ||
16002                 error "$FID1/$tfile not returned in parent list"
16003         echo "$parent" | grep -F "$FID2/link" ||
16004                 error "$FID2/link not returned in parent list"
16005
16006         # 3) get parent by fid
16007         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16008         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16009         echo "$parent" | grep -F "$FID1/$tfile" ||
16010                 error "$FID1/$tfile not returned in parent list (by fid)"
16011         echo "$parent" | grep -F "$FID2/link" ||
16012                 error "$FID2/link not returned in parent list (by fid)"
16013
16014         # 4) test for entry in root directory
16015         parent=$($LFS path2fid --parents $DIR/f)
16016         echo "$parent" | grep -F "$FID3/f" ||
16017                 error "$FID3/f not returned in parent list"
16018
16019         # 5) test it on root directory
16020         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16021                 error "$MOUNT should not have parents"
16022
16023         # enable xattr caching and check that linkea is correctly updated
16024         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16025         save_lustre_params client "llite.*.xattr_cache" > $save
16026         lctl set_param llite.*.xattr_cache 1
16027
16028         # 6.1) linkea update on rename
16029         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16030
16031         # get parents by fid
16032         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16033         # foo1 should no longer be returned in parent list
16034         echo "$parent" | grep -F "$FID1" &&
16035                 error "$FID1 should no longer be in parent list"
16036         # the new path should appear
16037         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16038                 error "$FID2/$tfile.moved is not in parent list"
16039
16040         # 6.2) linkea update on unlink
16041         rm -f $DIR/$tdir/foo2/link
16042         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16043         # foo2/link should no longer be returned in parent list
16044         echo "$parent" | grep -F "$FID2/link" &&
16045                 error "$FID2/link should no longer be in parent list"
16046         true
16047
16048         rm -f $DIR/f
16049         restore_lustre_params < $save
16050         rm -f $save
16051 }
16052 run_test 154f "get parent fids by reading link ea"
16053
16054 test_154g()
16055 {
16056         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16057            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16058                 skip "Need MDS version at least 2.6.92"
16059
16060         mkdir_on_mdt0 $DIR/$tdir
16061         llapi_fid_test -d $DIR/$tdir
16062 }
16063 run_test 154g "various llapi FID tests"
16064
16065 test_155_small_load() {
16066     local temp=$TMP/$tfile
16067     local file=$DIR/$tfile
16068
16069     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16070         error "dd of=$temp bs=6096 count=1 failed"
16071     cp $temp $file
16072     cancel_lru_locks $OSC
16073     cmp $temp $file || error "$temp $file differ"
16074
16075     $TRUNCATE $temp 6000
16076     $TRUNCATE $file 6000
16077     cmp $temp $file || error "$temp $file differ (truncate1)"
16078
16079     echo "12345" >>$temp
16080     echo "12345" >>$file
16081     cmp $temp $file || error "$temp $file differ (append1)"
16082
16083     echo "12345" >>$temp
16084     echo "12345" >>$file
16085     cmp $temp $file || error "$temp $file differ (append2)"
16086
16087     rm -f $temp $file
16088     true
16089 }
16090
16091 test_155_big_load() {
16092         remote_ost_nodsh && skip "remote OST with nodsh"
16093
16094         local temp=$TMP/$tfile
16095         local file=$DIR/$tfile
16096
16097         free_min_max
16098         local cache_size=$(do_facet ost$((MAXI+1)) \
16099                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16100
16101         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16102         # pre-set value
16103         if [ -z "$cache_size" ]; then
16104                 cache_size=256
16105         fi
16106         local large_file_size=$((cache_size * 2))
16107
16108         echo "OSS cache size: $cache_size KB"
16109         echo "Large file size: $large_file_size KB"
16110
16111         [ $MAXV -le $large_file_size ] &&
16112                 skip_env "max available OST size needs > $large_file_size KB"
16113
16114         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16115
16116         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16117                 error "dd of=$temp bs=$large_file_size count=1k failed"
16118         cp $temp $file
16119         ls -lh $temp $file
16120         cancel_lru_locks osc
16121         cmp $temp $file || error "$temp $file differ"
16122
16123         rm -f $temp $file
16124         true
16125 }
16126
16127 save_writethrough() {
16128         local facets=$(get_facets OST)
16129
16130         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16131 }
16132
16133 test_155a() {
16134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16135
16136         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16137
16138         save_writethrough $p
16139
16140         set_cache read on
16141         set_cache writethrough on
16142         test_155_small_load
16143         restore_lustre_params < $p
16144         rm -f $p
16145 }
16146 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16147
16148 test_155b() {
16149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16150
16151         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16152
16153         save_writethrough $p
16154
16155         set_cache read on
16156         set_cache writethrough off
16157         test_155_small_load
16158         restore_lustre_params < $p
16159         rm -f $p
16160 }
16161 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16162
16163 test_155c() {
16164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16165
16166         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16167
16168         save_writethrough $p
16169
16170         set_cache read off
16171         set_cache writethrough on
16172         test_155_small_load
16173         restore_lustre_params < $p
16174         rm -f $p
16175 }
16176 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16177
16178 test_155d() {
16179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16180
16181         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16182
16183         save_writethrough $p
16184
16185         set_cache read off
16186         set_cache writethrough off
16187         test_155_small_load
16188         restore_lustre_params < $p
16189         rm -f $p
16190 }
16191 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16192
16193 test_155e() {
16194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16195
16196         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16197
16198         save_writethrough $p
16199
16200         set_cache read on
16201         set_cache writethrough on
16202         test_155_big_load
16203         restore_lustre_params < $p
16204         rm -f $p
16205 }
16206 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16207
16208 test_155f() {
16209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16210
16211         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16212
16213         save_writethrough $p
16214
16215         set_cache read on
16216         set_cache writethrough off
16217         test_155_big_load
16218         restore_lustre_params < $p
16219         rm -f $p
16220 }
16221 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16222
16223 test_155g() {
16224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16225
16226         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16227
16228         save_writethrough $p
16229
16230         set_cache read off
16231         set_cache writethrough on
16232         test_155_big_load
16233         restore_lustre_params < $p
16234         rm -f $p
16235 }
16236 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16237
16238 test_155h() {
16239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16240
16241         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16242
16243         save_writethrough $p
16244
16245         set_cache read off
16246         set_cache writethrough off
16247         test_155_big_load
16248         restore_lustre_params < $p
16249         rm -f $p
16250 }
16251 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16252
16253 test_156() {
16254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16255         remote_ost_nodsh && skip "remote OST with nodsh"
16256         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16257                 skip "stats not implemented on old servers"
16258         [ "$ost1_FSTYPE" = "zfs" ] &&
16259                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16260
16261         local CPAGES=3
16262         local BEFORE
16263         local AFTER
16264         local file="$DIR/$tfile"
16265         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16266
16267         save_writethrough $p
16268         roc_hit_init
16269
16270         log "Turn on read and write cache"
16271         set_cache read on
16272         set_cache writethrough on
16273
16274         log "Write data and read it back."
16275         log "Read should be satisfied from the cache."
16276         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16277         BEFORE=$(roc_hit)
16278         cancel_lru_locks osc
16279         cat $file >/dev/null
16280         AFTER=$(roc_hit)
16281         if ! let "AFTER - BEFORE == CPAGES"; then
16282                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16283         else
16284                 log "cache hits: before: $BEFORE, after: $AFTER"
16285         fi
16286
16287         log "Read again; it should be satisfied from the cache."
16288         BEFORE=$AFTER
16289         cancel_lru_locks osc
16290         cat $file >/dev/null
16291         AFTER=$(roc_hit)
16292         if ! let "AFTER - BEFORE == CPAGES"; then
16293                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16294         else
16295                 log "cache hits:: before: $BEFORE, after: $AFTER"
16296         fi
16297
16298         log "Turn off the read cache and turn on the write cache"
16299         set_cache read off
16300         set_cache writethrough on
16301
16302         log "Read again; it should be satisfied from the cache."
16303         BEFORE=$(roc_hit)
16304         cancel_lru_locks osc
16305         cat $file >/dev/null
16306         AFTER=$(roc_hit)
16307         if ! let "AFTER - BEFORE == CPAGES"; then
16308                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16309         else
16310                 log "cache hits:: before: $BEFORE, after: $AFTER"
16311         fi
16312
16313         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16314                 # > 2.12.56 uses pagecache if cached
16315                 log "Read again; it should not be satisfied from the cache."
16316                 BEFORE=$AFTER
16317                 cancel_lru_locks osc
16318                 cat $file >/dev/null
16319                 AFTER=$(roc_hit)
16320                 if ! let "AFTER - BEFORE == 0"; then
16321                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16322                 else
16323                         log "cache hits:: before: $BEFORE, after: $AFTER"
16324                 fi
16325         fi
16326
16327         log "Write data and read it back."
16328         log "Read should be satisfied from the cache."
16329         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16330         BEFORE=$(roc_hit)
16331         cancel_lru_locks osc
16332         cat $file >/dev/null
16333         AFTER=$(roc_hit)
16334         if ! let "AFTER - BEFORE == CPAGES"; then
16335                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16336         else
16337                 log "cache hits:: before: $BEFORE, after: $AFTER"
16338         fi
16339
16340         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16341                 # > 2.12.56 uses pagecache if cached
16342                 log "Read again; it should not be satisfied from the cache."
16343                 BEFORE=$AFTER
16344                 cancel_lru_locks osc
16345                 cat $file >/dev/null
16346                 AFTER=$(roc_hit)
16347                 if ! let "AFTER - BEFORE == 0"; then
16348                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16349                 else
16350                         log "cache hits:: before: $BEFORE, after: $AFTER"
16351                 fi
16352         fi
16353
16354         log "Turn off read and write cache"
16355         set_cache read off
16356         set_cache writethrough off
16357
16358         log "Write data and read it back"
16359         log "It should not be satisfied from the cache."
16360         rm -f $file
16361         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16362         cancel_lru_locks osc
16363         BEFORE=$(roc_hit)
16364         cat $file >/dev/null
16365         AFTER=$(roc_hit)
16366         if ! let "AFTER - BEFORE == 0"; then
16367                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16368         else
16369                 log "cache hits:: before: $BEFORE, after: $AFTER"
16370         fi
16371
16372         log "Turn on the read cache and turn off the write cache"
16373         set_cache read on
16374         set_cache writethrough off
16375
16376         log "Write data and read it back"
16377         log "It should not be satisfied from the cache."
16378         rm -f $file
16379         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16380         BEFORE=$(roc_hit)
16381         cancel_lru_locks osc
16382         cat $file >/dev/null
16383         AFTER=$(roc_hit)
16384         if ! let "AFTER - BEFORE == 0"; then
16385                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16386         else
16387                 log "cache hits:: before: $BEFORE, after: $AFTER"
16388         fi
16389
16390         log "Read again; it should be satisfied from the cache."
16391         BEFORE=$(roc_hit)
16392         cancel_lru_locks osc
16393         cat $file >/dev/null
16394         AFTER=$(roc_hit)
16395         if ! let "AFTER - BEFORE == CPAGES"; then
16396                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16397         else
16398                 log "cache hits:: before: $BEFORE, after: $AFTER"
16399         fi
16400
16401         restore_lustre_params < $p
16402         rm -f $p $file
16403 }
16404 run_test 156 "Verification of tunables"
16405
16406 test_160a() {
16407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16408         remote_mds_nodsh && skip "remote MDS with nodsh"
16409         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16410                 skip "Need MDS version at least 2.2.0"
16411
16412         changelog_register || error "changelog_register failed"
16413         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16414         changelog_users $SINGLEMDS | grep -q $cl_user ||
16415                 error "User $cl_user not found in changelog_users"
16416
16417         mkdir_on_mdt0 $DIR/$tdir
16418
16419         # change something
16420         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16421         changelog_clear 0 || error "changelog_clear failed"
16422         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16423         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16424         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16425         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16426         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16427         rm $DIR/$tdir/pics/desktop.jpg
16428
16429         echo "verifying changelog mask"
16430         changelog_chmask "-MKDIR"
16431         changelog_chmask "-CLOSE"
16432
16433         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16434         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16435
16436         changelog_chmask "+MKDIR"
16437         changelog_chmask "+CLOSE"
16438
16439         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16440         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16441
16442         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16443         CLOSES=$(changelog_dump | grep -c "CLOSE")
16444         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16445         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16446
16447         # verify contents
16448         echo "verifying target fid"
16449         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16450         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16451         [ "$fidc" == "$fidf" ] ||
16452                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16453         echo "verifying parent fid"
16454         # The FID returned from the Changelog may be the directory shard on
16455         # a different MDT, and not the FID returned by path2fid on the parent.
16456         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16457         # since this is what will matter when recreating this file in the tree.
16458         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16459         local pathp=$($LFS fid2path $MOUNT "$fidp")
16460         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16461                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16462
16463         echo "getting records for $cl_user"
16464         changelog_users $SINGLEMDS
16465         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16466         local nclr=3
16467         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16468                 error "changelog_clear failed"
16469         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16470         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16471         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16472                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16473
16474         local min0_rec=$(changelog_users $SINGLEMDS |
16475                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16476         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16477                           awk '{ print $1; exit; }')
16478
16479         changelog_dump | tail -n 5
16480         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16481         [ $first_rec == $((min0_rec + 1)) ] ||
16482                 error "first index should be $min0_rec + 1 not $first_rec"
16483
16484         # LU-3446 changelog index reset on MDT restart
16485         local cur_rec1=$(changelog_users $SINGLEMDS |
16486                          awk '/^current.index:/ { print $NF }')
16487         changelog_clear 0 ||
16488                 error "clear all changelog records for $cl_user failed"
16489         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16490         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16491                 error "Fail to start $SINGLEMDS"
16492         local cur_rec2=$(changelog_users $SINGLEMDS |
16493                          awk '/^current.index:/ { print $NF }')
16494         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16495         [ $cur_rec1 == $cur_rec2 ] ||
16496                 error "current index should be $cur_rec1 not $cur_rec2"
16497
16498         echo "verifying users from this test are deregistered"
16499         changelog_deregister || error "changelog_deregister failed"
16500         changelog_users $SINGLEMDS | grep -q $cl_user &&
16501                 error "User '$cl_user' still in changelog_users"
16502
16503         # lctl get_param -n mdd.*.changelog_users
16504         # current_index: 144
16505         # ID    index (idle seconds)
16506         # cl3   144   (2) mask=<list>
16507         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16508                 # this is the normal case where all users were deregistered
16509                 # make sure no new records are added when no users are present
16510                 local last_rec1=$(changelog_users $SINGLEMDS |
16511                                   awk '/^current.index:/ { print $NF }')
16512                 touch $DIR/$tdir/chloe
16513                 local last_rec2=$(changelog_users $SINGLEMDS |
16514                                   awk '/^current.index:/ { print $NF }')
16515                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16516                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16517         else
16518                 # any changelog users must be leftovers from a previous test
16519                 changelog_users $SINGLEMDS
16520                 echo "other changelog users; can't verify off"
16521         fi
16522 }
16523 run_test 160a "changelog sanity"
16524
16525 test_160b() { # LU-3587
16526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16527         remote_mds_nodsh && skip "remote MDS with nodsh"
16528         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16529                 skip "Need MDS version at least 2.2.0"
16530
16531         changelog_register || error "changelog_register failed"
16532         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16533         changelog_users $SINGLEMDS | grep -q $cl_user ||
16534                 error "User '$cl_user' not found in changelog_users"
16535
16536         local longname1=$(str_repeat a 255)
16537         local longname2=$(str_repeat b 255)
16538
16539         cd $DIR
16540         echo "creating very long named file"
16541         touch $longname1 || error "create of '$longname1' failed"
16542         echo "renaming very long named file"
16543         mv $longname1 $longname2
16544
16545         changelog_dump | grep RENME | tail -n 5
16546         rm -f $longname2
16547 }
16548 run_test 160b "Verify that very long rename doesn't crash in changelog"
16549
16550 test_160c() {
16551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16552         remote_mds_nodsh && skip "remote MDS with nodsh"
16553
16554         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16555                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16556                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16557                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16558
16559         local rc=0
16560
16561         # Registration step
16562         changelog_register || error "changelog_register failed"
16563
16564         rm -rf $DIR/$tdir
16565         mkdir -p $DIR/$tdir
16566         $MCREATE $DIR/$tdir/foo_160c
16567         changelog_chmask "-TRUNC"
16568         $TRUNCATE $DIR/$tdir/foo_160c 200
16569         changelog_chmask "+TRUNC"
16570         $TRUNCATE $DIR/$tdir/foo_160c 199
16571         changelog_dump | tail -n 5
16572         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16573         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16574 }
16575 run_test 160c "verify that changelog log catch the truncate event"
16576
16577 test_160d() {
16578         remote_mds_nodsh && skip "remote MDS with nodsh"
16579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16581         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16582                 skip "Need MDS version at least 2.7.60"
16583
16584         # Registration step
16585         changelog_register || error "changelog_register failed"
16586
16587         mkdir -p $DIR/$tdir/migrate_dir
16588         changelog_clear 0 || error "changelog_clear failed"
16589
16590         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16591         changelog_dump | tail -n 5
16592         local migrates=$(changelog_dump | grep -c "MIGRT")
16593         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16594 }
16595 run_test 160d "verify that changelog log catch the migrate event"
16596
16597 test_160e() {
16598         remote_mds_nodsh && skip "remote MDS with nodsh"
16599
16600         # Create a user
16601         changelog_register || error "changelog_register failed"
16602
16603         local MDT0=$(facet_svc $SINGLEMDS)
16604         local rc
16605
16606         # No user (expect fail)
16607         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16608         rc=$?
16609         if [ $rc -eq 0 ]; then
16610                 error "Should fail without user"
16611         elif [ $rc -ne 4 ]; then
16612                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16613         fi
16614
16615         # Delete a future user (expect fail)
16616         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16617         rc=$?
16618         if [ $rc -eq 0 ]; then
16619                 error "Deleted non-existant user cl77"
16620         elif [ $rc -ne 2 ]; then
16621                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16622         fi
16623
16624         # Clear to a bad index (1 billion should be safe)
16625         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16626         rc=$?
16627
16628         if [ $rc -eq 0 ]; then
16629                 error "Successfully cleared to invalid CL index"
16630         elif [ $rc -ne 22 ]; then
16631                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16632         fi
16633 }
16634 run_test 160e "changelog negative testing (should return errors)"
16635
16636 test_160f() {
16637         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16638         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16639                 skip "Need MDS version at least 2.10.56"
16640
16641         local mdts=$(comma_list $(mdts_nodes))
16642
16643         # Create a user
16644         changelog_register || error "first changelog_register failed"
16645         changelog_register || error "second changelog_register failed"
16646         local cl_users
16647         declare -A cl_user1
16648         declare -A cl_user2
16649         local user_rec1
16650         local user_rec2
16651         local i
16652
16653         # generate some changelog records to accumulate on each MDT
16654         # use all_char because created files should be evenly distributed
16655         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16656                 error "test_mkdir $tdir failed"
16657         log "$(date +%s): creating first files"
16658         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16659                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16660                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16661         done
16662
16663         # check changelogs have been generated
16664         local start=$SECONDS
16665         local idle_time=$((MDSCOUNT * 5 + 5))
16666         local nbcl=$(changelog_dump | wc -l)
16667         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16668
16669         for param in "changelog_max_idle_time=$idle_time" \
16670                      "changelog_gc=1" \
16671                      "changelog_min_gc_interval=2" \
16672                      "changelog_min_free_cat_entries=3"; do
16673                 local MDT0=$(facet_svc $SINGLEMDS)
16674                 local var="${param%=*}"
16675                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16676
16677                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16678                 do_nodes $mdts $LCTL set_param mdd.*.$param
16679         done
16680
16681         # force cl_user2 to be idle (1st part), but also cancel the
16682         # cl_user1 records so that it is not evicted later in the test.
16683         local sleep1=$((idle_time / 2))
16684         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16685         sleep $sleep1
16686
16687         # simulate changelog catalog almost full
16688         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16689         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16690
16691         for i in $(seq $MDSCOUNT); do
16692                 cl_users=(${CL_USERS[mds$i]})
16693                 cl_user1[mds$i]="${cl_users[0]}"
16694                 cl_user2[mds$i]="${cl_users[1]}"
16695
16696                 [ -n "${cl_user1[mds$i]}" ] ||
16697                         error "mds$i: no user registered"
16698                 [ -n "${cl_user2[mds$i]}" ] ||
16699                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16700
16701                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16702                 [ -n "$user_rec1" ] ||
16703                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16704                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16705                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16706                 [ -n "$user_rec2" ] ||
16707                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16708                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16709                      "$user_rec1 + 2 == $user_rec2"
16710                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16711                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16712                               "$user_rec1 + 2, but is $user_rec2"
16713                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16714                 [ -n "$user_rec2" ] ||
16715                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16716                 [ $user_rec1 == $user_rec2 ] ||
16717                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16718                               "$user_rec1, but is $user_rec2"
16719         done
16720
16721         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16722         local sleep2=$((idle_time - (SECONDS - start) + 1))
16723         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16724         sleep $sleep2
16725
16726         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16727         # cl_user1 should be OK because it recently processed records.
16728         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16729         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16730                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16731                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16732         done
16733
16734         # ensure gc thread is done
16735         for i in $(mdts_nodes); do
16736                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16737                         error "$i: GC-thread not done"
16738         done
16739
16740         local first_rec
16741         for (( i = 1; i <= MDSCOUNT; i++ )); do
16742                 # check cl_user1 still registered
16743                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16744                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16745                 # check cl_user2 unregistered
16746                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16747                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16748
16749                 # check changelogs are present and starting at $user_rec1 + 1
16750                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16751                 [ -n "$user_rec1" ] ||
16752                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16753                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16754                             awk '{ print $1; exit; }')
16755
16756                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16757                 [ $((user_rec1 + 1)) == $first_rec ] ||
16758                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16759         done
16760 }
16761 run_test 160f "changelog garbage collect (timestamped users)"
16762
16763 test_160g() {
16764         remote_mds_nodsh && skip "remote MDS with nodsh"
16765         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16766                 skip "Need MDS version at least 2.14.55"
16767
16768         local mdts=$(comma_list $(mdts_nodes))
16769
16770         # Create a user
16771         changelog_register || error "first changelog_register failed"
16772         changelog_register || error "second changelog_register failed"
16773         local cl_users
16774         declare -A cl_user1
16775         declare -A cl_user2
16776         local user_rec1
16777         local user_rec2
16778         local i
16779
16780         # generate some changelog records to accumulate on each MDT
16781         # use all_char because created files should be evenly distributed
16782         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16783                 error "test_mkdir $tdir failed"
16784         for ((i = 0; i < MDSCOUNT; i++)); do
16785                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16786                         error "create $DIR/$tdir/d$i.1 failed"
16787         done
16788
16789         # check changelogs have been generated
16790         local nbcl=$(changelog_dump | wc -l)
16791         (( $nbcl > 0 )) || error "no changelogs found"
16792
16793         # reduce the max_idle_indexes value to make sure we exceed it
16794         for param in "changelog_max_idle_indexes=2" \
16795                      "changelog_gc=1" \
16796                      "changelog_min_gc_interval=2"; do
16797                 local MDT0=$(facet_svc $SINGLEMDS)
16798                 local var="${param%=*}"
16799                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16800
16801                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16802                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16803                         error "unable to set mdd.*.$param"
16804         done
16805
16806         local start=$SECONDS
16807         for i in $(seq $MDSCOUNT); do
16808                 cl_users=(${CL_USERS[mds$i]})
16809                 cl_user1[mds$i]="${cl_users[0]}"
16810                 cl_user2[mds$i]="${cl_users[1]}"
16811
16812                 [ -n "${cl_user1[mds$i]}" ] ||
16813                         error "mds$i: user1 is not registered"
16814                 [ -n "${cl_user2[mds$i]}" ] ||
16815                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16816
16817                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16818                 [ -n "$user_rec1" ] ||
16819                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16820                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16821                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16822                 [ -n "$user_rec2" ] ||
16823                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16824                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16825                      "$user_rec1 + 2 == $user_rec2"
16826                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16827                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16828                               "expected $user_rec1 + 2, but is $user_rec2"
16829                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16830                 [ -n "$user_rec2" ] ||
16831                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16832                 [ $user_rec1 == $user_rec2 ] ||
16833                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16834                               "expected $user_rec1, but is $user_rec2"
16835         done
16836
16837         # ensure we are past the previous changelog_min_gc_interval set above
16838         local sleep2=$((start + 2 - SECONDS))
16839         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16840         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16841         # cl_user1 should be OK because it recently processed records.
16842         for ((i = 0; i < MDSCOUNT; i++)); do
16843                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16844                         error "create $DIR/$tdir/d$i.3 failed"
16845         done
16846
16847         # ensure gc thread is done
16848         for i in $(mdts_nodes); do
16849                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16850                         error "$i: GC-thread not done"
16851         done
16852
16853         local first_rec
16854         for (( i = 1; i <= MDSCOUNT; i++ )); do
16855                 # check cl_user1 still registered
16856                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16857                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16858                 # check cl_user2 unregistered
16859                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16860                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16861
16862                 # check changelogs are present and starting at $user_rec1 + 1
16863                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16864                 [ -n "$user_rec1" ] ||
16865                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16866                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16867                             awk '{ print $1; exit; }')
16868
16869                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16870                 [ $((user_rec1 + 1)) == $first_rec ] ||
16871                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16872         done
16873 }
16874 run_test 160g "changelog garbage collect on idle records"
16875
16876 test_160h() {
16877         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16878         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16879                 skip "Need MDS version at least 2.10.56"
16880
16881         local mdts=$(comma_list $(mdts_nodes))
16882
16883         # Create a user
16884         changelog_register || error "first changelog_register failed"
16885         changelog_register || error "second changelog_register failed"
16886         local cl_users
16887         declare -A cl_user1
16888         declare -A cl_user2
16889         local user_rec1
16890         local user_rec2
16891         local i
16892
16893         # generate some changelog records to accumulate on each MDT
16894         # use all_char because created files should be evenly distributed
16895         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16896                 error "test_mkdir $tdir failed"
16897         for ((i = 0; i < MDSCOUNT; i++)); do
16898                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16899                         error "create $DIR/$tdir/d$i.1 failed"
16900         done
16901
16902         # check changelogs have been generated
16903         local nbcl=$(changelog_dump | wc -l)
16904         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16905
16906         for param in "changelog_max_idle_time=10" \
16907                      "changelog_gc=1" \
16908                      "changelog_min_gc_interval=2"; do
16909                 local MDT0=$(facet_svc $SINGLEMDS)
16910                 local var="${param%=*}"
16911                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16912
16913                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16914                 do_nodes $mdts $LCTL set_param mdd.*.$param
16915         done
16916
16917         # force cl_user2 to be idle (1st part)
16918         sleep 9
16919
16920         for i in $(seq $MDSCOUNT); do
16921                 cl_users=(${CL_USERS[mds$i]})
16922                 cl_user1[mds$i]="${cl_users[0]}"
16923                 cl_user2[mds$i]="${cl_users[1]}"
16924
16925                 [ -n "${cl_user1[mds$i]}" ] ||
16926                         error "mds$i: no user registered"
16927                 [ -n "${cl_user2[mds$i]}" ] ||
16928                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16929
16930                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16931                 [ -n "$user_rec1" ] ||
16932                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16933                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16934                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16935                 [ -n "$user_rec2" ] ||
16936                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16937                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16938                      "$user_rec1 + 2 == $user_rec2"
16939                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16940                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16941                               "$user_rec1 + 2, but is $user_rec2"
16942                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16943                 [ -n "$user_rec2" ] ||
16944                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16945                 [ $user_rec1 == $user_rec2 ] ||
16946                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16947                               "$user_rec1, but is $user_rec2"
16948         done
16949
16950         # force cl_user2 to be idle (2nd part) and to reach
16951         # changelog_max_idle_time
16952         sleep 2
16953
16954         # force each GC-thread start and block then
16955         # one per MDT/MDD, set fail_val accordingly
16956         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16957         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16958
16959         # generate more changelogs to trigger fail_loc
16960         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16961                 error "create $DIR/$tdir/${tfile}bis failed"
16962
16963         # stop MDT to stop GC-thread, should be done in back-ground as it will
16964         # block waiting for the thread to be released and exit
16965         declare -A stop_pids
16966         for i in $(seq $MDSCOUNT); do
16967                 stop mds$i &
16968                 stop_pids[mds$i]=$!
16969         done
16970
16971         for i in $(mdts_nodes); do
16972                 local facet
16973                 local nb=0
16974                 local facets=$(facets_up_on_host $i)
16975
16976                 for facet in ${facets//,/ }; do
16977                         if [[ $facet == mds* ]]; then
16978                                 nb=$((nb + 1))
16979                         fi
16980                 done
16981                 # ensure each MDS's gc threads are still present and all in "R"
16982                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16983                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16984                         error "$i: expected $nb GC-thread"
16985                 wait_update $i \
16986                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16987                         "R" 20 ||
16988                         error "$i: GC-thread not found in R-state"
16989                 # check umounts of each MDT on MDS have reached kthread_stop()
16990                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16991                         error "$i: expected $nb umount"
16992                 wait_update $i \
16993                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16994                         error "$i: umount not found in D-state"
16995         done
16996
16997         # release all GC-threads
16998         do_nodes $mdts $LCTL set_param fail_loc=0
16999
17000         # wait for MDT stop to complete
17001         for i in $(seq $MDSCOUNT); do
17002                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17003         done
17004
17005         # XXX
17006         # may try to check if any orphan changelog records are present
17007         # via ldiskfs/zfs and llog_reader...
17008
17009         # re-start/mount MDTs
17010         for i in $(seq $MDSCOUNT); do
17011                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17012                         error "Fail to start mds$i"
17013         done
17014
17015         local first_rec
17016         for i in $(seq $MDSCOUNT); do
17017                 # check cl_user1 still registered
17018                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17019                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17020                 # check cl_user2 unregistered
17021                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17022                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17023
17024                 # check changelogs are present and starting at $user_rec1 + 1
17025                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17026                 [ -n "$user_rec1" ] ||
17027                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17028                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17029                             awk '{ print $1; exit; }')
17030
17031                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17032                 [ $((user_rec1 + 1)) == $first_rec ] ||
17033                         error "mds$i: first index should be $user_rec1 + 1, " \
17034                               "but is $first_rec"
17035         done
17036 }
17037 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17038               "during mount"
17039
17040 test_160i() {
17041
17042         local mdts=$(comma_list $(mdts_nodes))
17043
17044         changelog_register || error "first changelog_register failed"
17045
17046         # generate some changelog records to accumulate on each MDT
17047         # use all_char because created files should be evenly distributed
17048         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17049                 error "test_mkdir $tdir failed"
17050         for ((i = 0; i < MDSCOUNT; i++)); do
17051                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17052                         error "create $DIR/$tdir/d$i.1 failed"
17053         done
17054
17055         # check changelogs have been generated
17056         local nbcl=$(changelog_dump | wc -l)
17057         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17058
17059         # simulate race between register and unregister
17060         # XXX as fail_loc is set per-MDS, with DNE configs the race
17061         # simulation will only occur for one MDT per MDS and for the
17062         # others the normal race scenario will take place
17063         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17064         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17065         do_nodes $mdts $LCTL set_param fail_val=1
17066
17067         # unregister 1st user
17068         changelog_deregister &
17069         local pid1=$!
17070         # wait some time for deregister work to reach race rdv
17071         sleep 2
17072         # register 2nd user
17073         changelog_register || error "2nd user register failed"
17074
17075         wait $pid1 || error "1st user deregister failed"
17076
17077         local i
17078         local last_rec
17079         declare -A LAST_REC
17080         for i in $(seq $MDSCOUNT); do
17081                 if changelog_users mds$i | grep "^cl"; then
17082                         # make sure new records are added with one user present
17083                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17084                                           awk '/^current.index:/ { print $NF }')
17085                 else
17086                         error "mds$i has no user registered"
17087                 fi
17088         done
17089
17090         # generate more changelog records to accumulate on each MDT
17091         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17092                 error "create $DIR/$tdir/${tfile}bis failed"
17093
17094         for i in $(seq $MDSCOUNT); do
17095                 last_rec=$(changelog_users $SINGLEMDS |
17096                            awk '/^current.index:/ { print $NF }')
17097                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17098                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17099                         error "changelogs are off on mds$i"
17100         done
17101 }
17102 run_test 160i "changelog user register/unregister race"
17103
17104 test_160j() {
17105         remote_mds_nodsh && skip "remote MDS with nodsh"
17106         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17107                 skip "Need MDS version at least 2.12.56"
17108
17109         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17110         stack_trap "umount $MOUNT2" EXIT
17111
17112         changelog_register || error "first changelog_register failed"
17113         stack_trap "changelog_deregister" EXIT
17114
17115         # generate some changelog
17116         # use all_char because created files should be evenly distributed
17117         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17118                 error "mkdir $tdir failed"
17119         for ((i = 0; i < MDSCOUNT; i++)); do
17120                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17121                         error "create $DIR/$tdir/d$i.1 failed"
17122         done
17123
17124         # open the changelog device
17125         exec 3>/dev/changelog-$FSNAME-MDT0000
17126         stack_trap "exec 3>&-" EXIT
17127         exec 4</dev/changelog-$FSNAME-MDT0000
17128         stack_trap "exec 4<&-" EXIT
17129
17130         # umount the first lustre mount
17131         umount $MOUNT
17132         stack_trap "mount_client $MOUNT" EXIT
17133
17134         # read changelog, which may or may not fail, but should not crash
17135         cat <&4 >/dev/null
17136
17137         # clear changelog
17138         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17139         changelog_users $SINGLEMDS | grep -q $cl_user ||
17140                 error "User $cl_user not found in changelog_users"
17141
17142         printf 'clear:'$cl_user':0' >&3
17143 }
17144 run_test 160j "client can be umounted while its chanangelog is being used"
17145
17146 test_160k() {
17147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17148         remote_mds_nodsh && skip "remote MDS with nodsh"
17149
17150         mkdir -p $DIR/$tdir/1/1
17151
17152         changelog_register || error "changelog_register failed"
17153         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17154
17155         changelog_users $SINGLEMDS | grep -q $cl_user ||
17156                 error "User '$cl_user' not found in changelog_users"
17157 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17158         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17159         rmdir $DIR/$tdir/1/1 & sleep 1
17160         mkdir $DIR/$tdir/2
17161         touch $DIR/$tdir/2/2
17162         rm -rf $DIR/$tdir/2
17163
17164         wait
17165         sleep 4
17166
17167         changelog_dump | grep rmdir || error "rmdir not recorded"
17168 }
17169 run_test 160k "Verify that changelog records are not lost"
17170
17171 # Verifies that a file passed as a parameter has recently had an operation
17172 # performed on it that has generated an MTIME changelog which contains the
17173 # correct parent FID. As files might reside on a different MDT from the
17174 # parent directory in DNE configurations, the FIDs are translated to paths
17175 # before being compared, which should be identical
17176 compare_mtime_changelog() {
17177         local file="${1}"
17178         local mdtidx
17179         local mtime
17180         local cl_fid
17181         local pdir
17182         local dir
17183
17184         mdtidx=$($LFS getstripe --mdt-index $file)
17185         mdtidx=$(printf "%04x" $mdtidx)
17186
17187         # Obtain the parent FID from the MTIME changelog
17188         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17189         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17190
17191         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17192         [ -z "$cl_fid" ] && error "parent FID not present"
17193
17194         # Verify that the path for the parent FID is the same as the path for
17195         # the test directory
17196         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17197
17198         dir=$(dirname $1)
17199
17200         [[ "${pdir%/}" == "$dir" ]] ||
17201                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17202 }
17203
17204 test_160l() {
17205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17206
17207         remote_mds_nodsh && skip "remote MDS with nodsh"
17208         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17209                 skip "Need MDS version at least 2.13.55"
17210
17211         local cl_user
17212
17213         changelog_register || error "changelog_register failed"
17214         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17215
17216         changelog_users $SINGLEMDS | grep -q $cl_user ||
17217                 error "User '$cl_user' not found in changelog_users"
17218
17219         # Clear some types so that MTIME changelogs are generated
17220         changelog_chmask "-CREAT"
17221         changelog_chmask "-CLOSE"
17222
17223         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17224
17225         # Test CL_MTIME during setattr
17226         touch $DIR/$tdir/$tfile
17227         compare_mtime_changelog $DIR/$tdir/$tfile
17228
17229         # Test CL_MTIME during close
17230         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17231         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17232 }
17233 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17234
17235 test_160m() {
17236         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17237         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17238                 skip "Need MDS version at least 2.14.51"
17239         local cl_users
17240         local cl_user1
17241         local cl_user2
17242         local pid1
17243
17244         # Create a user
17245         changelog_register || error "first changelog_register failed"
17246         changelog_register || error "second changelog_register failed"
17247
17248         cl_users=(${CL_USERS[mds1]})
17249         cl_user1="${cl_users[0]}"
17250         cl_user2="${cl_users[1]}"
17251         # generate some changelog records to accumulate on MDT0
17252         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17253         createmany -m $DIR/$tdir/$tfile 50 ||
17254                 error "create $DIR/$tdir/$tfile failed"
17255         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17256         rm -f $DIR/$tdir
17257
17258         # check changelogs have been generated
17259         local nbcl=$(changelog_dump | wc -l)
17260         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17261
17262 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17263         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17264
17265         __changelog_clear mds1 $cl_user1 +10
17266         __changelog_clear mds1 $cl_user2 0 &
17267         pid1=$!
17268         sleep 2
17269         __changelog_clear mds1 $cl_user1 0 ||
17270                 error "fail to cancel record for $cl_user1"
17271         wait $pid1
17272         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17273 }
17274 run_test 160m "Changelog clear race"
17275
17276 test_160n() {
17277         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17278         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17279                 skip "Need MDS version at least 2.14.51"
17280         local cl_users
17281         local cl_user1
17282         local cl_user2
17283         local pid1
17284         local first_rec
17285         local last_rec=0
17286
17287         # Create a user
17288         changelog_register || error "first changelog_register failed"
17289
17290         cl_users=(${CL_USERS[mds1]})
17291         cl_user1="${cl_users[0]}"
17292
17293         # generate some changelog records to accumulate on MDT0
17294         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17295         first_rec=$(changelog_users $SINGLEMDS |
17296                         awk '/^current.index:/ { print $NF }')
17297         while (( last_rec < (( first_rec + 65000)) )); do
17298                 createmany -m $DIR/$tdir/$tfile 10000 ||
17299                         error "create $DIR/$tdir/$tfile failed"
17300
17301                 for i in $(seq 0 10000); do
17302                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17303                                 > /dev/null
17304                 done
17305
17306                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17307                         error "unlinkmany failed unlink"
17308                 last_rec=$(changelog_users $SINGLEMDS |
17309                         awk '/^current.index:/ { print $NF }')
17310                 echo last record $last_rec
17311                 (( last_rec == 0 )) && error "no changelog found"
17312         done
17313
17314 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17315         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17316
17317         __changelog_clear mds1 $cl_user1 0 &
17318         pid1=$!
17319         sleep 2
17320         __changelog_clear mds1 $cl_user1 0 ||
17321                 error "fail to cancel record for $cl_user1"
17322         wait $pid1
17323         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17324 }
17325 run_test 160n "Changelog destroy race"
17326
17327 test_160o() {
17328         local mdt="$(facet_svc $SINGLEMDS)"
17329
17330         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17331         remote_mds_nodsh && skip "remote MDS with nodsh"
17332         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17333                 skip "Need MDS version at least 2.14.52"
17334
17335         changelog_register --user test_160o -m unlnk+close+open ||
17336                 error "changelog_register failed"
17337
17338         do_facet $SINGLEMDS $LCTL --device $mdt \
17339                                 changelog_register -u "Tt3_-#" &&
17340                 error "bad symbols in name should fail"
17341
17342         do_facet $SINGLEMDS $LCTL --device $mdt \
17343                                 changelog_register -u test_160o &&
17344                 error "the same name registration should fail"
17345
17346         do_facet $SINGLEMDS $LCTL --device $mdt \
17347                         changelog_register -u test_160toolongname &&
17348                 error "too long name registration should fail"
17349
17350         changelog_chmask "MARK+HSM"
17351         lctl get_param mdd.*.changelog*mask
17352         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17353         changelog_users $SINGLEMDS | grep -q $cl_user ||
17354                 error "User $cl_user not found in changelog_users"
17355         #verify username
17356         echo $cl_user | grep -q test_160o ||
17357                 error "User $cl_user has no specific name 'test160o'"
17358
17359         # change something
17360         changelog_clear 0 || error "changelog_clear failed"
17361         # generate some changelog records to accumulate on MDT0
17362         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17363         touch $DIR/$tdir/$tfile                 # open 1
17364
17365         OPENS=$(changelog_dump | grep -c "OPEN")
17366         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17367
17368         # must be no MKDIR it wasn't set as user mask
17369         MKDIR=$(changelog_dump | grep -c "MKDIR")
17370         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17371
17372         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17373                                 mdd.$mdt.changelog_current_mask -n)
17374         # register maskless user
17375         changelog_register || error "changelog_register failed"
17376         # effective mask should be not changed because it is not minimal
17377         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17378                                 mdd.$mdt.changelog_current_mask -n)
17379         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17380         # set server mask to minimal value
17381         changelog_chmask "MARK"
17382         # check effective mask again, should be treated as DEFMASK now
17383         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17384                                 mdd.$mdt.changelog_current_mask -n)
17385         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17386
17387         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17388                 # set server mask back to some value
17389                 changelog_chmask "CLOSE,UNLNK"
17390                 # check effective mask again, should not remain as DEFMASK
17391                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17392                                 mdd.$mdt.changelog_current_mask -n)
17393                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17394         fi
17395
17396         do_facet $SINGLEMDS $LCTL --device $mdt \
17397                                 changelog_deregister -u test_160o ||
17398                 error "cannot deregister by name"
17399 }
17400 run_test 160o "changelog user name and mask"
17401
17402 test_160p() {
17403         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17404         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17405                 skip "Need MDS version at least 2.14.51"
17406         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17407         local cl_users
17408         local cl_user1
17409         local entry_count
17410
17411         # Create a user
17412         changelog_register || error "first changelog_register failed"
17413
17414         cl_users=(${CL_USERS[mds1]})
17415         cl_user1="${cl_users[0]}"
17416
17417         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17418         createmany -m $DIR/$tdir/$tfile 50 ||
17419                 error "create $DIR/$tdir/$tfile failed"
17420         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17421         rm -rf $DIR/$tdir
17422
17423         # check changelogs have been generated
17424         entry_count=$(changelog_dump | wc -l)
17425         ((entry_count != 0)) || error "no changelog entries found"
17426
17427         # remove changelog_users and check that orphan entries are removed
17428         stop mds1
17429         local dev=$(mdsdevname 1)
17430         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17431         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17432         entry_count=$(changelog_dump | wc -l)
17433         ((entry_count == 0)) ||
17434                 error "found $entry_count changelog entries, expected none"
17435 }
17436 run_test 160p "Changelog orphan cleanup with no users"
17437
17438 test_160q() {
17439         local mdt="$(facet_svc $SINGLEMDS)"
17440         local clu
17441
17442         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17443         remote_mds_nodsh && skip "remote MDS with nodsh"
17444         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17445                 skip "Need MDS version at least 2.14.54"
17446
17447         # set server mask to minimal value like server init does
17448         changelog_chmask "MARK"
17449         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17450                 error "changelog_register failed"
17451         # check effective mask again, should be treated as DEFMASK now
17452         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17453                                 mdd.$mdt.changelog_current_mask -n)
17454         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17455                 error "changelog_deregister failed"
17456         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17457 }
17458 run_test 160q "changelog effective mask is DEFMASK if not set"
17459
17460 test_160s() {
17461         remote_mds_nodsh && skip "remote MDS with nodsh"
17462         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17463                 skip "Need MDS version at least 2.14.55"
17464
17465         local mdts=$(comma_list $(mdts_nodes))
17466
17467         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17468         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17469                                        fail_val=$((24 * 3600 * 10))
17470
17471         # Create a user which is 10 days old
17472         changelog_register || error "first changelog_register failed"
17473         local cl_users
17474         declare -A cl_user1
17475         local i
17476
17477         # generate some changelog records to accumulate on each MDT
17478         # use all_char because created files should be evenly distributed
17479         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17480                 error "test_mkdir $tdir failed"
17481         for ((i = 0; i < MDSCOUNT; i++)); do
17482                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17483                         error "create $DIR/$tdir/d$i.1 failed"
17484         done
17485
17486         # check changelogs have been generated
17487         local nbcl=$(changelog_dump | wc -l)
17488         (( nbcl > 0 )) || error "no changelogs found"
17489
17490         # reduce the max_idle_indexes value to make sure we exceed it
17491         for param in "changelog_max_idle_indexes=2097446912" \
17492                      "changelog_max_idle_time=2592000" \
17493                      "changelog_gc=1" \
17494                      "changelog_min_gc_interval=2"; do
17495                 local MDT0=$(facet_svc $SINGLEMDS)
17496                 local var="${param%=*}"
17497                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17498
17499                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17500                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17501                         error "unable to set mdd.*.$param"
17502         done
17503
17504         local start=$SECONDS
17505         for i in $(seq $MDSCOUNT); do
17506                 cl_users=(${CL_USERS[mds$i]})
17507                 cl_user1[mds$i]="${cl_users[0]}"
17508
17509                 [[ -n "${cl_user1[mds$i]}" ]] ||
17510                         error "mds$i: no user registered"
17511         done
17512
17513         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17514         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17515
17516         # ensure we are past the previous changelog_min_gc_interval set above
17517         local sleep2=$((start + 2 - SECONDS))
17518         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17519
17520         # Generate one more changelog to trigger GC
17521         for ((i = 0; i < MDSCOUNT; i++)); do
17522                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17523                         error "create $DIR/$tdir/d$i.3 failed"
17524         done
17525
17526         # ensure gc thread is done
17527         for node in $(mdts_nodes); do
17528                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17529                         error "$node: GC-thread not done"
17530         done
17531
17532         do_nodes $mdts $LCTL set_param fail_loc=0
17533
17534         for (( i = 1; i <= MDSCOUNT; i++ )); do
17535                 # check cl_user1 is purged
17536                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17537                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17538         done
17539         return 0
17540 }
17541 run_test 160s "changelog garbage collect on idle records * time"
17542
17543 test_160t() {
17544         remote_mds_nodsh && skip "remote MDS with nodsh"
17545         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17546                 skip "Need MDS version at least 2.15.50"
17547
17548         local MDT0=$(facet_svc $SINGLEMDS)
17549         local cl_users
17550         local cl_user1
17551         local cl_user2
17552         local start
17553
17554         changelog_register --user user1 -m all ||
17555                 error "user1 failed to register"
17556
17557         mkdir_on_mdt0 $DIR/$tdir
17558         # create default overstripe to maximize changelog size
17559         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17560         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17561         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17562
17563         # user2 consumes less records so less space
17564         changelog_register --user user2 || error "user2 failed to register"
17565         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17566         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17567
17568         # check changelogs have been generated
17569         local nbcl=$(changelog_dump | wc -l)
17570         (( nbcl > 0 )) || error "no changelogs found"
17571
17572         # reduce the changelog_min_gc_interval to force check
17573         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17574                 local var="${param%=*}"
17575                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17576
17577                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17578                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17579                         error "unable to set mdd.*.$param"
17580         done
17581
17582         start=$SECONDS
17583         cl_users=(${CL_USERS[mds1]})
17584         cl_user1="${cl_users[0]}"
17585         cl_user2="${cl_users[1]}"
17586
17587         [[ -n $cl_user1 ]] ||
17588                 error "mds1: user #1 isn't registered"
17589         [[ -n $cl_user2 ]] ||
17590                 error "mds1: user #2 isn't registered"
17591
17592         # ensure we are past the previous changelog_min_gc_interval set above
17593         local sleep2=$((start + 2 - SECONDS))
17594         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17595
17596         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17597         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17598                         fail_val=$(((llog_size1 + llog_size2) / 2))
17599
17600         # Generate more changelog to trigger GC
17601         createmany -o $DIR/$tdir/u3_ 4 ||
17602                 error "create failed for more files"
17603
17604         # ensure gc thread is done
17605         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17606                 error "mds1: GC-thread not done"
17607
17608         do_facet mds1 $LCTL set_param fail_loc=0
17609
17610         # check cl_user1 is purged
17611         changelog_users mds1 | grep -q "$cl_user1" &&
17612                 error "User $cl_user1 is registered"
17613         # check cl_user2 is not purged
17614         changelog_users mds1 | grep -q "$cl_user2" ||
17615                 error "User $cl_user2 is not registered"
17616 }
17617 run_test 160t "changelog garbage collect on lack of space"
17618
17619 test_161a() {
17620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17621
17622         test_mkdir -c1 $DIR/$tdir
17623         cp /etc/hosts $DIR/$tdir/$tfile
17624         test_mkdir -c1 $DIR/$tdir/foo1
17625         test_mkdir -c1 $DIR/$tdir/foo2
17626         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17627         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17628         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17629         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17630         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17631         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17632                 $LFS fid2path $DIR $FID
17633                 error "bad link ea"
17634         fi
17635         # middle
17636         rm $DIR/$tdir/foo2/zachary
17637         # last
17638         rm $DIR/$tdir/foo2/thor
17639         # first
17640         rm $DIR/$tdir/$tfile
17641         # rename
17642         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17643         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17644                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17645         rm $DIR/$tdir/foo2/maggie
17646
17647         # overflow the EA
17648         local longname=$tfile.avg_len_is_thirty_two_
17649         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17650                 error_noexit 'failed to unlink many hardlinks'" EXIT
17651         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17652                 error "failed to hardlink many files"
17653         links=$($LFS fid2path $DIR $FID | wc -l)
17654         echo -n "${links}/1000 links in link EA"
17655         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17656 }
17657 run_test 161a "link ea sanity"
17658
17659 test_161b() {
17660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17661         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17662
17663         local MDTIDX=1
17664         local remote_dir=$DIR/$tdir/remote_dir
17665
17666         mkdir -p $DIR/$tdir
17667         $LFS mkdir -i $MDTIDX $remote_dir ||
17668                 error "create remote directory failed"
17669
17670         cp /etc/hosts $remote_dir/$tfile
17671         mkdir -p $remote_dir/foo1
17672         mkdir -p $remote_dir/foo2
17673         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17674         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17675         ln $remote_dir/$tfile $remote_dir/foo1/luna
17676         ln $remote_dir/$tfile $remote_dir/foo2/thor
17677
17678         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17679                      tr -d ']')
17680         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17681                 $LFS fid2path $DIR $FID
17682                 error "bad link ea"
17683         fi
17684         # middle
17685         rm $remote_dir/foo2/zachary
17686         # last
17687         rm $remote_dir/foo2/thor
17688         # first
17689         rm $remote_dir/$tfile
17690         # rename
17691         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17692         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17693         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17694                 $LFS fid2path $DIR $FID
17695                 error "bad link rename"
17696         fi
17697         rm $remote_dir/foo2/maggie
17698
17699         # overflow the EA
17700         local longname=filename_avg_len_is_thirty_two_
17701         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17702                 error "failed to hardlink many files"
17703         links=$($LFS fid2path $DIR $FID | wc -l)
17704         echo -n "${links}/1000 links in link EA"
17705         [[ ${links} -gt 60 ]] ||
17706                 error "expected at least 60 links in link EA"
17707         unlinkmany $remote_dir/foo2/$longname 1000 ||
17708         error "failed to unlink many hardlinks"
17709 }
17710 run_test 161b "link ea sanity under remote directory"
17711
17712 test_161c() {
17713         remote_mds_nodsh && skip "remote MDS with nodsh"
17714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17715         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17716                 skip "Need MDS version at least 2.1.5"
17717
17718         # define CLF_RENAME_LAST 0x0001
17719         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17720         changelog_register || error "changelog_register failed"
17721
17722         rm -rf $DIR/$tdir
17723         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17724         touch $DIR/$tdir/foo_161c
17725         touch $DIR/$tdir/bar_161c
17726         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17727         changelog_dump | grep RENME | tail -n 5
17728         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17729         changelog_clear 0 || error "changelog_clear failed"
17730         if [ x$flags != "x0x1" ]; then
17731                 error "flag $flags is not 0x1"
17732         fi
17733
17734         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17735         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17736         touch $DIR/$tdir/foo_161c
17737         touch $DIR/$tdir/bar_161c
17738         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17739         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17740         changelog_dump | grep RENME | tail -n 5
17741         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17742         changelog_clear 0 || error "changelog_clear failed"
17743         if [ x$flags != "x0x0" ]; then
17744                 error "flag $flags is not 0x0"
17745         fi
17746         echo "rename overwrite a target having nlink > 1," \
17747                 "changelog record has flags of $flags"
17748
17749         # rename doesn't overwrite a target (changelog flag 0x0)
17750         touch $DIR/$tdir/foo_161c
17751         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17752         changelog_dump | grep RENME | tail -n 5
17753         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17754         changelog_clear 0 || error "changelog_clear failed"
17755         if [ x$flags != "x0x0" ]; then
17756                 error "flag $flags is not 0x0"
17757         fi
17758         echo "rename doesn't overwrite a target," \
17759                 "changelog record has flags of $flags"
17760
17761         # define CLF_UNLINK_LAST 0x0001
17762         # unlink a file having nlink = 1 (changelog flag 0x1)
17763         rm -f $DIR/$tdir/foo2_161c
17764         changelog_dump | grep UNLNK | tail -n 5
17765         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17766         changelog_clear 0 || error "changelog_clear failed"
17767         if [ x$flags != "x0x1" ]; then
17768                 error "flag $flags is not 0x1"
17769         fi
17770         echo "unlink a file having nlink = 1," \
17771                 "changelog record has flags of $flags"
17772
17773         # unlink a file having nlink > 1 (changelog flag 0x0)
17774         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17775         rm -f $DIR/$tdir/foobar_161c
17776         changelog_dump | grep UNLNK | tail -n 5
17777         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17778         changelog_clear 0 || error "changelog_clear failed"
17779         if [ x$flags != "x0x0" ]; then
17780                 error "flag $flags is not 0x0"
17781         fi
17782         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17783 }
17784 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17785
17786 test_161d() {
17787         remote_mds_nodsh && skip "remote MDS with nodsh"
17788         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17789
17790         local pid
17791         local fid
17792
17793         changelog_register || error "changelog_register failed"
17794
17795         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17796         # interfer with $MOUNT/.lustre/fid/ access
17797         mkdir $DIR/$tdir
17798         [[ $? -eq 0 ]] || error "mkdir failed"
17799
17800         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17801         $LCTL set_param fail_loc=0x8000140c
17802         # 5s pause
17803         $LCTL set_param fail_val=5
17804
17805         # create file
17806         echo foofoo > $DIR/$tdir/$tfile &
17807         pid=$!
17808
17809         # wait for create to be delayed
17810         sleep 2
17811
17812         ps -p $pid
17813         [[ $? -eq 0 ]] || error "create should be blocked"
17814
17815         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17816         stack_trap "rm -f $tempfile"
17817         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17818         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17819         # some delay may occur during ChangeLog publishing and file read just
17820         # above, that could allow file write to happen finally
17821         [[ -s $tempfile ]] && echo "file should be empty"
17822
17823         $LCTL set_param fail_loc=0
17824
17825         wait $pid
17826         [[ $? -eq 0 ]] || error "create failed"
17827 }
17828 run_test 161d "create with concurrent .lustre/fid access"
17829
17830 check_path() {
17831         local expected="$1"
17832         shift
17833         local fid="$2"
17834
17835         local path
17836         path=$($LFS fid2path "$@")
17837         local rc=$?
17838
17839         if [ $rc -ne 0 ]; then
17840                 error "path looked up of '$expected' failed: rc=$rc"
17841         elif [ "$path" != "$expected" ]; then
17842                 error "path looked up '$path' instead of '$expected'"
17843         else
17844                 echo "FID '$fid' resolves to path '$path' as expected"
17845         fi
17846 }
17847
17848 test_162a() { # was test_162
17849         test_mkdir -p -c1 $DIR/$tdir/d2
17850         touch $DIR/$tdir/d2/$tfile
17851         touch $DIR/$tdir/d2/x1
17852         touch $DIR/$tdir/d2/x2
17853         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17854         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17855         # regular file
17856         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17857         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17858
17859         # softlink
17860         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17861         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17862         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17863
17864         # softlink to wrong file
17865         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17866         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17867         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17868
17869         # hardlink
17870         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17871         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17872         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17873         # fid2path dir/fsname should both work
17874         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17875         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17876
17877         # hardlink count: check that there are 2 links
17878         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17879         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17880
17881         # hardlink indexing: remove the first link
17882         rm $DIR/$tdir/d2/p/q/r/hlink
17883         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17884 }
17885 run_test 162a "path lookup sanity"
17886
17887 test_162b() {
17888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17889         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17890
17891         mkdir $DIR/$tdir
17892         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17893                                 error "create striped dir failed"
17894
17895         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17896                                         tail -n 1 | awk '{print $2}')
17897         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17898
17899         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17900         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17901
17902         # regular file
17903         for ((i=0;i<5;i++)); do
17904                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17905                         error "get fid for f$i failed"
17906                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17907
17908                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17909                         error "get fid for d$i failed"
17910                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17911         done
17912
17913         return 0
17914 }
17915 run_test 162b "striped directory path lookup sanity"
17916
17917 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17918 test_162c() {
17919         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17920                 skip "Need MDS version at least 2.7.51"
17921
17922         local lpath=$tdir.local
17923         local rpath=$tdir.remote
17924
17925         test_mkdir $DIR/$lpath
17926         test_mkdir $DIR/$rpath
17927
17928         for ((i = 0; i <= 101; i++)); do
17929                 lpath="$lpath/$i"
17930                 mkdir $DIR/$lpath
17931                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17932                         error "get fid for local directory $DIR/$lpath failed"
17933                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17934
17935                 rpath="$rpath/$i"
17936                 test_mkdir $DIR/$rpath
17937                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17938                         error "get fid for remote directory $DIR/$rpath failed"
17939                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17940         done
17941
17942         return 0
17943 }
17944 run_test 162c "fid2path works with paths 100 or more directories deep"
17945
17946 oalr_event_count() {
17947         local event="${1}"
17948         local trace="${2}"
17949
17950         awk -v name="${FSNAME}-OST0000" \
17951             -v event="${event}" \
17952             '$1 == "TRACE" && $2 == event && $3 == name' \
17953             "${trace}" |
17954         wc -l
17955 }
17956
17957 oalr_expect_event_count() {
17958         local event="${1}"
17959         local trace="${2}"
17960         local expect="${3}"
17961         local count
17962
17963         count=$(oalr_event_count "${event}" "${trace}")
17964         if ((count == expect)); then
17965                 return 0
17966         fi
17967
17968         error_noexit "${event} event count was '${count}', expected ${expect}"
17969         cat "${trace}" >&2
17970         exit 1
17971 }
17972
17973 cleanup_165() {
17974         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17975         stop ost1
17976         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17977 }
17978
17979 setup_165() {
17980         sync # Flush previous IOs so we can count log entries.
17981         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17982         stack_trap cleanup_165 EXIT
17983 }
17984
17985 test_165a() {
17986         local trace="/tmp/${tfile}.trace"
17987         local rc
17988         local count
17989
17990         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17991                 skip "OFD access log unsupported"
17992
17993         setup_165
17994         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17995         sleep 5
17996
17997         do_facet ost1 ofd_access_log_reader --list
17998         stop ost1
17999
18000         do_facet ost1 killall -TERM ofd_access_log_reader
18001         wait
18002         rc=$?
18003
18004         if ((rc != 0)); then
18005                 error "ofd_access_log_reader exited with rc = '${rc}'"
18006         fi
18007
18008         # Parse trace file for discovery events:
18009         oalr_expect_event_count alr_log_add "${trace}" 1
18010         oalr_expect_event_count alr_log_eof "${trace}" 1
18011         oalr_expect_event_count alr_log_free "${trace}" 1
18012 }
18013 run_test 165a "ofd access log discovery"
18014
18015 test_165b() {
18016         local trace="/tmp/${tfile}.trace"
18017         local file="${DIR}/${tfile}"
18018         local pfid1
18019         local pfid2
18020         local -a entry
18021         local rc
18022         local count
18023         local size
18024         local flags
18025
18026         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18027                 skip "OFD access log unsupported"
18028
18029         setup_165
18030         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18031         sleep 5
18032
18033         do_facet ost1 ofd_access_log_reader --list
18034
18035         lfs setstripe -c 1 -i 0 "${file}"
18036         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18037                 error "cannot create '${file}'"
18038
18039         sleep 5
18040         do_facet ost1 killall -TERM ofd_access_log_reader
18041         wait
18042         rc=$?
18043
18044         if ((rc != 0)); then
18045                 error "ofd_access_log_reader exited with rc = '${rc}'"
18046         fi
18047
18048         oalr_expect_event_count alr_log_entry "${trace}" 1
18049
18050         pfid1=$($LFS path2fid "${file}")
18051
18052         # 1     2             3   4    5     6   7    8    9     10
18053         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18054         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18055
18056         echo "entry = '${entry[*]}'" >&2
18057
18058         pfid2=${entry[4]}
18059         if [[ "${pfid1}" != "${pfid2}" ]]; then
18060                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18061         fi
18062
18063         size=${entry[8]}
18064         if ((size != 1048576)); then
18065                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18066         fi
18067
18068         flags=${entry[10]}
18069         if [[ "${flags}" != "w" ]]; then
18070                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18071         fi
18072
18073         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18074         sleep 5
18075
18076         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18077                 error "cannot read '${file}'"
18078         sleep 5
18079
18080         do_facet ost1 killall -TERM ofd_access_log_reader
18081         wait
18082         rc=$?
18083
18084         if ((rc != 0)); then
18085                 error "ofd_access_log_reader exited with rc = '${rc}'"
18086         fi
18087
18088         oalr_expect_event_count alr_log_entry "${trace}" 1
18089
18090         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18091         echo "entry = '${entry[*]}'" >&2
18092
18093         pfid2=${entry[4]}
18094         if [[ "${pfid1}" != "${pfid2}" ]]; then
18095                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18096         fi
18097
18098         size=${entry[8]}
18099         if ((size != 524288)); then
18100                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18101         fi
18102
18103         flags=${entry[10]}
18104         if [[ "${flags}" != "r" ]]; then
18105                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18106         fi
18107 }
18108 run_test 165b "ofd access log entries are produced and consumed"
18109
18110 test_165c() {
18111         local trace="/tmp/${tfile}.trace"
18112         local file="${DIR}/${tdir}/${tfile}"
18113
18114         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18115                 skip "OFD access log unsupported"
18116
18117         test_mkdir "${DIR}/${tdir}"
18118
18119         setup_165
18120         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18121         sleep 5
18122
18123         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18124
18125         # 4096 / 64 = 64. Create twice as many entries.
18126         for ((i = 0; i < 128; i++)); do
18127                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18128                         error "cannot create file"
18129         done
18130
18131         sync
18132
18133         do_facet ost1 killall -TERM ofd_access_log_reader
18134         wait
18135         rc=$?
18136         if ((rc != 0)); then
18137                 error "ofd_access_log_reader exited with rc = '${rc}'"
18138         fi
18139
18140         unlinkmany  "${file}-%d" 128
18141 }
18142 run_test 165c "full ofd access logs do not block IOs"
18143
18144 oal_get_read_count() {
18145         local stats="$1"
18146
18147         # STATS lustre-OST0001 alr_read_count 1
18148
18149         do_facet ost1 cat "${stats}" |
18150         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18151              END { print count; }'
18152 }
18153
18154 oal_expect_read_count() {
18155         local stats="$1"
18156         local count
18157         local expect="$2"
18158
18159         # Ask ofd_access_log_reader to write stats.
18160         do_facet ost1 killall -USR1 ofd_access_log_reader
18161
18162         # Allow some time for things to happen.
18163         sleep 1
18164
18165         count=$(oal_get_read_count "${stats}")
18166         if ((count == expect)); then
18167                 return 0
18168         fi
18169
18170         error_noexit "bad read count, got ${count}, expected ${expect}"
18171         do_facet ost1 cat "${stats}" >&2
18172         exit 1
18173 }
18174
18175 test_165d() {
18176         local stats="/tmp/${tfile}.stats"
18177         local file="${DIR}/${tdir}/${tfile}"
18178         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18179
18180         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18181                 skip "OFD access log unsupported"
18182
18183         test_mkdir "${DIR}/${tdir}"
18184
18185         setup_165
18186         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18187         sleep 5
18188
18189         lfs setstripe -c 1 -i 0 "${file}"
18190
18191         do_facet ost1 lctl set_param "${param}=rw"
18192         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18193                 error "cannot create '${file}'"
18194         oal_expect_read_count "${stats}" 1
18195
18196         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18197                 error "cannot read '${file}'"
18198         oal_expect_read_count "${stats}" 2
18199
18200         do_facet ost1 lctl set_param "${param}=r"
18201         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18202                 error "cannot create '${file}'"
18203         oal_expect_read_count "${stats}" 2
18204
18205         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18206                 error "cannot read '${file}'"
18207         oal_expect_read_count "${stats}" 3
18208
18209         do_facet ost1 lctl set_param "${param}=w"
18210         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18211                 error "cannot create '${file}'"
18212         oal_expect_read_count "${stats}" 4
18213
18214         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18215                 error "cannot read '${file}'"
18216         oal_expect_read_count "${stats}" 4
18217
18218         do_facet ost1 lctl set_param "${param}=0"
18219         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18220                 error "cannot create '${file}'"
18221         oal_expect_read_count "${stats}" 4
18222
18223         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18224                 error "cannot read '${file}'"
18225         oal_expect_read_count "${stats}" 4
18226
18227         do_facet ost1 killall -TERM ofd_access_log_reader
18228         wait
18229         rc=$?
18230         if ((rc != 0)); then
18231                 error "ofd_access_log_reader exited with rc = '${rc}'"
18232         fi
18233 }
18234 run_test 165d "ofd_access_log mask works"
18235
18236 test_165e() {
18237         local stats="/tmp/${tfile}.stats"
18238         local file0="${DIR}/${tdir}-0/${tfile}"
18239         local file1="${DIR}/${tdir}-1/${tfile}"
18240
18241         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18242                 skip "OFD access log unsupported"
18243
18244         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18245
18246         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18247         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18248
18249         lfs setstripe -c 1 -i 0 "${file0}"
18250         lfs setstripe -c 1 -i 0 "${file1}"
18251
18252         setup_165
18253         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18254         sleep 5
18255
18256         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18257                 error "cannot create '${file0}'"
18258         sync
18259         oal_expect_read_count "${stats}" 0
18260
18261         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18262                 error "cannot create '${file1}'"
18263         sync
18264         oal_expect_read_count "${stats}" 1
18265
18266         do_facet ost1 killall -TERM ofd_access_log_reader
18267         wait
18268         rc=$?
18269         if ((rc != 0)); then
18270                 error "ofd_access_log_reader exited with rc = '${rc}'"
18271         fi
18272 }
18273 run_test 165e "ofd_access_log MDT index filter works"
18274
18275 test_165f() {
18276         local trace="/tmp/${tfile}.trace"
18277         local rc
18278         local count
18279
18280         setup_165
18281         do_facet ost1 timeout 60 ofd_access_log_reader \
18282                 --exit-on-close --debug=- --trace=- > "${trace}" &
18283         sleep 5
18284         stop ost1
18285
18286         wait
18287         rc=$?
18288
18289         if ((rc != 0)); then
18290                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18291                 cat "${trace}"
18292                 exit 1
18293         fi
18294 }
18295 run_test 165f "ofd_access_log_reader --exit-on-close works"
18296
18297 test_169() {
18298         # do directio so as not to populate the page cache
18299         log "creating a 10 Mb file"
18300         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18301                 error "multiop failed while creating a file"
18302         log "starting reads"
18303         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18304         log "truncating the file"
18305         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18306                 error "multiop failed while truncating the file"
18307         log "killing dd"
18308         kill %+ || true # reads might have finished
18309         echo "wait until dd is finished"
18310         wait
18311         log "removing the temporary file"
18312         rm -rf $DIR/$tfile || error "tmp file removal failed"
18313 }
18314 run_test 169 "parallel read and truncate should not deadlock"
18315
18316 test_170() {
18317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18318
18319         $LCTL clear     # bug 18514
18320         $LCTL debug_daemon start $TMP/${tfile}_log_good
18321         touch $DIR/$tfile
18322         $LCTL debug_daemon stop
18323         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18324                 error "sed failed to read log_good"
18325
18326         $LCTL debug_daemon start $TMP/${tfile}_log_good
18327         rm -rf $DIR/$tfile
18328         $LCTL debug_daemon stop
18329
18330         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18331                error "lctl df log_bad failed"
18332
18333         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18334         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18335
18336         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18337         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18338
18339         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18340                 error "bad_line good_line1 good_line2 are empty"
18341
18342         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18343         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18344         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18345
18346         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18347         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18348         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18349
18350         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18351                 error "bad_line_new good_line_new are empty"
18352
18353         local expected_good=$((good_line1 + good_line2*2))
18354
18355         rm -f $TMP/${tfile}*
18356         # LU-231, short malformed line may not be counted into bad lines
18357         if [ $bad_line -ne $bad_line_new ] &&
18358                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18359                 error "expected $bad_line bad lines, but got $bad_line_new"
18360                 return 1
18361         fi
18362
18363         if [ $expected_good -ne $good_line_new ]; then
18364                 error "expected $expected_good good lines, but got $good_line_new"
18365                 return 2
18366         fi
18367         true
18368 }
18369 run_test 170 "test lctl df to handle corrupted log ====================="
18370
18371 test_171() { # bug20592
18372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18373
18374         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18375         $LCTL set_param fail_loc=0x50e
18376         $LCTL set_param fail_val=3000
18377         multiop_bg_pause $DIR/$tfile O_s || true
18378         local MULTIPID=$!
18379         kill -USR1 $MULTIPID
18380         # cause log dump
18381         sleep 3
18382         wait $MULTIPID
18383         if dmesg | grep "recursive fault"; then
18384                 error "caught a recursive fault"
18385         fi
18386         $LCTL set_param fail_loc=0
18387         true
18388 }
18389 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18390
18391 test_172() {
18392
18393         #define OBD_FAIL_OBD_CLEANUP  0x60e
18394         $LCTL set_param fail_loc=0x60e
18395         umount $MOUNT || error "umount $MOUNT failed"
18396         stack_trap "mount_client $MOUNT"
18397
18398         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18399                 error "no client OBDs are remained"
18400
18401         $LCTL dl | while read devno state type name foo; do
18402                 case $type in
18403                 lov|osc|lmv|mdc)
18404                         $LCTL --device $name cleanup
18405                         $LCTL --device $name detach
18406                         ;;
18407                 *)
18408                         # skip server devices
18409                         ;;
18410                 esac
18411         done
18412
18413         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18414                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18415                 error "some client OBDs are still remained"
18416         fi
18417
18418 }
18419 run_test 172 "manual device removal with lctl cleanup/detach ======"
18420
18421 # it would be good to share it with obdfilter-survey/iokit-libecho code
18422 setup_obdecho_osc () {
18423         local rc=0
18424         local ost_nid=$1
18425         local obdfilter_name=$2
18426         echo "Creating new osc for $obdfilter_name on $ost_nid"
18427         # make sure we can find loopback nid
18428         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18429
18430         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18431                            ${obdfilter_name}_osc_UUID || rc=2; }
18432         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18433                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18434         return $rc
18435 }
18436
18437 cleanup_obdecho_osc () {
18438         local obdfilter_name=$1
18439         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18440         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18441         return 0
18442 }
18443
18444 obdecho_test() {
18445         local OBD=$1
18446         local node=$2
18447         local pages=${3:-64}
18448         local rc=0
18449         local id
18450
18451         local count=10
18452         local obd_size=$(get_obd_size $node $OBD)
18453         local page_size=$(get_page_size $node)
18454         if [[ -n "$obd_size" ]]; then
18455                 local new_count=$((obd_size / (pages * page_size / 1024)))
18456                 [[ $new_count -ge $count ]] || count=$new_count
18457         fi
18458
18459         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18460         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18461                            rc=2; }
18462         if [ $rc -eq 0 ]; then
18463             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18464             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18465         fi
18466         echo "New object id is $id"
18467         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18468                            rc=4; }
18469         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18470                            "test_brw $count w v $pages $id" || rc=4; }
18471         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18472                            rc=4; }
18473         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18474                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18475         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18476                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18477         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18478         return $rc
18479 }
18480
18481 test_180a() {
18482         skip "obdecho on osc is no longer supported"
18483 }
18484 run_test 180a "test obdecho on osc"
18485
18486 test_180b() {
18487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18488         remote_ost_nodsh && skip "remote OST with nodsh"
18489
18490         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18491                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18492                 error "failed to load module obdecho"
18493
18494         local target=$(do_facet ost1 $LCTL dl |
18495                        awk '/obdfilter/ { print $4; exit; }')
18496
18497         if [ -n "$target" ]; then
18498                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18499         else
18500                 do_facet ost1 $LCTL dl
18501                 error "there is no obdfilter target on ost1"
18502         fi
18503 }
18504 run_test 180b "test obdecho directly on obdfilter"
18505
18506 test_180c() { # LU-2598
18507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18508         remote_ost_nodsh && skip "remote OST with nodsh"
18509         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18510                 skip "Need MDS version at least 2.4.0"
18511
18512         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18513                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18514                 error "failed to load module obdecho"
18515
18516         local target=$(do_facet ost1 $LCTL dl |
18517                        awk '/obdfilter/ { print $4; exit; }')
18518
18519         if [ -n "$target" ]; then
18520                 local pages=16384 # 64MB bulk I/O RPC size
18521
18522                 obdecho_test "$target" ost1 "$pages" ||
18523                         error "obdecho_test with pages=$pages failed with $?"
18524         else
18525                 do_facet ost1 $LCTL dl
18526                 error "there is no obdfilter target on ost1"
18527         fi
18528 }
18529 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18530
18531 test_181() { # bug 22177
18532         test_mkdir $DIR/$tdir
18533         # create enough files to index the directory
18534         createmany -o $DIR/$tdir/foobar 4000
18535         # print attributes for debug purpose
18536         lsattr -d .
18537         # open dir
18538         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18539         MULTIPID=$!
18540         # remove the files & current working dir
18541         unlinkmany $DIR/$tdir/foobar 4000
18542         rmdir $DIR/$tdir
18543         kill -USR1 $MULTIPID
18544         wait $MULTIPID
18545         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18546         return 0
18547 }
18548 run_test 181 "Test open-unlinked dir ========================"
18549
18550 test_182a() {
18551         local fcount=1000
18552         local tcount=10
18553
18554         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18555
18556         $LCTL set_param mdc.*.rpc_stats=clear
18557
18558         for (( i = 0; i < $tcount; i++ )) ; do
18559                 mkdir $DIR/$tdir/$i
18560         done
18561
18562         for (( i = 0; i < $tcount; i++ )) ; do
18563                 createmany -o $DIR/$tdir/$i/f- $fcount &
18564         done
18565         wait
18566
18567         for (( i = 0; i < $tcount; i++ )) ; do
18568                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18569         done
18570         wait
18571
18572         $LCTL get_param mdc.*.rpc_stats
18573
18574         rm -rf $DIR/$tdir
18575 }
18576 run_test 182a "Test parallel modify metadata operations from mdc"
18577
18578 test_182b() {
18579         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18580         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18581         local dcount=1000
18582         local tcount=10
18583         local stime
18584         local etime
18585         local delta
18586
18587         do_facet mds1 $LCTL list_param \
18588                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18589                 skip "MDS lacks parallel RPC handling"
18590
18591         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18592
18593         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18594                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18595
18596         stime=$(date +%s)
18597         createmany -i 0 -d $DIR/$tdir/t- $tcount
18598
18599         for (( i = 0; i < $tcount; i++ )) ; do
18600                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18601         done
18602         wait
18603         etime=$(date +%s)
18604         delta=$((etime - stime))
18605         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18606
18607         stime=$(date +%s)
18608         for (( i = 0; i < $tcount; i++ )) ; do
18609                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18610         done
18611         wait
18612         etime=$(date +%s)
18613         delta=$((etime - stime))
18614         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18615
18616         rm -rf $DIR/$tdir
18617
18618         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18619
18620         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18621
18622         stime=$(date +%s)
18623         createmany -i 0 -d $DIR/$tdir/t- $tcount
18624
18625         for (( i = 0; i < $tcount; i++ )) ; do
18626                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18627         done
18628         wait
18629         etime=$(date +%s)
18630         delta=$((etime - stime))
18631         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18632
18633         stime=$(date +%s)
18634         for (( i = 0; i < $tcount; i++ )) ; do
18635                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18636         done
18637         wait
18638         etime=$(date +%s)
18639         delta=$((etime - stime))
18640         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18641
18642         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18643 }
18644 run_test 182b "Test parallel modify metadata operations from osp"
18645
18646 test_183() { # LU-2275
18647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18648         remote_mds_nodsh && skip "remote MDS with nodsh"
18649         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18650                 skip "Need MDS version at least 2.3.56"
18651
18652         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18653         echo aaa > $DIR/$tdir/$tfile
18654
18655 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18656         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18657
18658         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18659         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18660
18661         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18662
18663         # Flush negative dentry cache
18664         touch $DIR/$tdir/$tfile
18665
18666         # We are not checking for any leaked references here, they'll
18667         # become evident next time we do cleanup with module unload.
18668         rm -rf $DIR/$tdir
18669 }
18670 run_test 183 "No crash or request leak in case of strange dispositions ========"
18671
18672 # test suite 184 is for LU-2016, LU-2017
18673 test_184a() {
18674         check_swap_layouts_support
18675
18676         dir0=$DIR/$tdir/$testnum
18677         test_mkdir -p -c1 $dir0
18678         ref1=/etc/passwd
18679         ref2=/etc/group
18680         file1=$dir0/f1
18681         file2=$dir0/f2
18682         $LFS setstripe -c1 $file1
18683         cp $ref1 $file1
18684         $LFS setstripe -c2 $file2
18685         cp $ref2 $file2
18686         gen1=$($LFS getstripe -g $file1)
18687         gen2=$($LFS getstripe -g $file2)
18688
18689         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18690         gen=$($LFS getstripe -g $file1)
18691         [[ $gen1 != $gen ]] ||
18692                 error "Layout generation on $file1 does not change"
18693         gen=$($LFS getstripe -g $file2)
18694         [[ $gen2 != $gen ]] ||
18695                 error "Layout generation on $file2 does not change"
18696
18697         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18698         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18699
18700         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18701 }
18702 run_test 184a "Basic layout swap"
18703
18704 test_184b() {
18705         check_swap_layouts_support
18706
18707         dir0=$DIR/$tdir/$testnum
18708         mkdir -p $dir0 || error "creating dir $dir0"
18709         file1=$dir0/f1
18710         file2=$dir0/f2
18711         file3=$dir0/f3
18712         dir1=$dir0/d1
18713         dir2=$dir0/d2
18714         mkdir $dir1 $dir2
18715         $LFS setstripe -c1 $file1
18716         $LFS setstripe -c2 $file2
18717         $LFS setstripe -c1 $file3
18718         chown $RUNAS_ID $file3
18719         gen1=$($LFS getstripe -g $file1)
18720         gen2=$($LFS getstripe -g $file2)
18721
18722         $LFS swap_layouts $dir1 $dir2 &&
18723                 error "swap of directories layouts should fail"
18724         $LFS swap_layouts $dir1 $file1 &&
18725                 error "swap of directory and file layouts should fail"
18726         $RUNAS $LFS swap_layouts $file1 $file2 &&
18727                 error "swap of file we cannot write should fail"
18728         $LFS swap_layouts $file1 $file3 &&
18729                 error "swap of file with different owner should fail"
18730         /bin/true # to clear error code
18731 }
18732 run_test 184b "Forbidden layout swap (will generate errors)"
18733
18734 test_184c() {
18735         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18736         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18737         check_swap_layouts_support
18738         check_swap_layout_no_dom $DIR
18739
18740         local dir0=$DIR/$tdir/$testnum
18741         mkdir -p $dir0 || error "creating dir $dir0"
18742
18743         local ref1=$dir0/ref1
18744         local ref2=$dir0/ref2
18745         local file1=$dir0/file1
18746         local file2=$dir0/file2
18747         # create a file large enough for the concurrent test
18748         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18749         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18750         echo "ref file size: ref1($(stat -c %s $ref1))," \
18751              "ref2($(stat -c %s $ref2))"
18752
18753         cp $ref2 $file2
18754         dd if=$ref1 of=$file1 bs=16k &
18755         local DD_PID=$!
18756
18757         # Make sure dd starts to copy file, but wait at most 5 seconds
18758         local loops=0
18759         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18760
18761         $LFS swap_layouts $file1 $file2
18762         local rc=$?
18763         wait $DD_PID
18764         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18765         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18766
18767         # how many bytes copied before swapping layout
18768         local copied=$(stat -c %s $file2)
18769         local remaining=$(stat -c %s $ref1)
18770         remaining=$((remaining - copied))
18771         echo "Copied $copied bytes before swapping layout..."
18772
18773         cmp -n $copied $file1 $ref2 | grep differ &&
18774                 error "Content mismatch [0, $copied) of ref2 and file1"
18775         cmp -n $copied $file2 $ref1 ||
18776                 error "Content mismatch [0, $copied) of ref1 and file2"
18777         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18778                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18779
18780         # clean up
18781         rm -f $ref1 $ref2 $file1 $file2
18782 }
18783 run_test 184c "Concurrent write and layout swap"
18784
18785 test_184d() {
18786         check_swap_layouts_support
18787         check_swap_layout_no_dom $DIR
18788         [ -z "$(which getfattr 2>/dev/null)" ] &&
18789                 skip_env "no getfattr command"
18790
18791         local file1=$DIR/$tdir/$tfile-1
18792         local file2=$DIR/$tdir/$tfile-2
18793         local file3=$DIR/$tdir/$tfile-3
18794         local lovea1
18795         local lovea2
18796
18797         mkdir -p $DIR/$tdir
18798         touch $file1 || error "create $file1 failed"
18799         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18800                 error "create $file2 failed"
18801         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18802                 error "create $file3 failed"
18803         lovea1=$(get_layout_param $file1)
18804
18805         $LFS swap_layouts $file2 $file3 ||
18806                 error "swap $file2 $file3 layouts failed"
18807         $LFS swap_layouts $file1 $file2 ||
18808                 error "swap $file1 $file2 layouts failed"
18809
18810         lovea2=$(get_layout_param $file2)
18811         echo "$lovea1"
18812         echo "$lovea2"
18813         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18814
18815         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18816         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18817 }
18818 run_test 184d "allow stripeless layouts swap"
18819
18820 test_184e() {
18821         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18822                 skip "Need MDS version at least 2.6.94"
18823         check_swap_layouts_support
18824         check_swap_layout_no_dom $DIR
18825         [ -z "$(which getfattr 2>/dev/null)" ] &&
18826                 skip_env "no getfattr command"
18827
18828         local file1=$DIR/$tdir/$tfile-1
18829         local file2=$DIR/$tdir/$tfile-2
18830         local file3=$DIR/$tdir/$tfile-3
18831         local lovea
18832
18833         mkdir -p $DIR/$tdir
18834         touch $file1 || error "create $file1 failed"
18835         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18836                 error "create $file2 failed"
18837         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18838                 error "create $file3 failed"
18839
18840         $LFS swap_layouts $file1 $file2 ||
18841                 error "swap $file1 $file2 layouts failed"
18842
18843         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18844         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18845
18846         echo 123 > $file1 || error "Should be able to write into $file1"
18847
18848         $LFS swap_layouts $file1 $file3 ||
18849                 error "swap $file1 $file3 layouts failed"
18850
18851         echo 123 > $file1 || error "Should be able to write into $file1"
18852
18853         rm -rf $file1 $file2 $file3
18854 }
18855 run_test 184e "Recreate layout after stripeless layout swaps"
18856
18857 test_184f() {
18858         # Create a file with name longer than sizeof(struct stat) ==
18859         # 144 to see if we can get chars from the file name to appear
18860         # in the returned striping. Note that 'f' == 0x66.
18861         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18862
18863         mkdir -p $DIR/$tdir
18864         mcreate $DIR/$tdir/$file
18865         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18866                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18867         fi
18868 }
18869 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18870
18871 test_185() { # LU-2441
18872         # LU-3553 - no volatile file support in old servers
18873         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18874                 skip "Need MDS version at least 2.3.60"
18875
18876         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18877         touch $DIR/$tdir/spoo
18878         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18879         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18880                 error "cannot create/write a volatile file"
18881         [ "$FILESET" == "" ] &&
18882         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18883                 error "FID is still valid after close"
18884
18885         multiop_bg_pause $DIR/$tdir vVw4096_c
18886         local multi_pid=$!
18887
18888         local OLD_IFS=$IFS
18889         IFS=":"
18890         local fidv=($fid)
18891         IFS=$OLD_IFS
18892         # assume that the next FID for this client is sequential, since stdout
18893         # is unfortunately eaten by multiop_bg_pause
18894         local n=$((${fidv[1]} + 1))
18895         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18896         if [ "$FILESET" == "" ]; then
18897                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18898                         error "FID is missing before close"
18899         fi
18900         kill -USR1 $multi_pid
18901         # 1 second delay, so if mtime change we will see it
18902         sleep 1
18903         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18904         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18905 }
18906 run_test 185 "Volatile file support"
18907
18908 function create_check_volatile() {
18909         local idx=$1
18910         local tgt
18911
18912         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18913         local PID=$!
18914         sleep 1
18915         local FID=$(cat /tmp/${tfile}.fid)
18916         [ "$FID" == "" ] && error "can't get FID for volatile"
18917         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18918         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18919         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18920         kill -USR1 $PID
18921         wait
18922         sleep 1
18923         cancel_lru_locks mdc # flush opencache
18924         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18925         return 0
18926 }
18927
18928 test_185a(){
18929         # LU-12516 - volatile creation via .lustre
18930         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18931                 skip "Need MDS version at least 2.3.55"
18932
18933         create_check_volatile 0
18934         [ $MDSCOUNT -lt 2 ] && return 0
18935
18936         # DNE case
18937         create_check_volatile 1
18938
18939         return 0
18940 }
18941 run_test 185a "Volatile file creation in .lustre/fid/"
18942
18943 test_187a() {
18944         remote_mds_nodsh && skip "remote MDS with nodsh"
18945         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18946                 skip "Need MDS version at least 2.3.0"
18947
18948         local dir0=$DIR/$tdir/$testnum
18949         mkdir -p $dir0 || error "creating dir $dir0"
18950
18951         local file=$dir0/file1
18952         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18953         local dv1=$($LFS data_version $file)
18954         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18955         local dv2=$($LFS data_version $file)
18956         [[ $dv1 != $dv2 ]] ||
18957                 error "data version did not change on write $dv1 == $dv2"
18958
18959         # clean up
18960         rm -f $file1
18961 }
18962 run_test 187a "Test data version change"
18963
18964 test_187b() {
18965         remote_mds_nodsh && skip "remote MDS with nodsh"
18966         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18967                 skip "Need MDS version at least 2.3.0"
18968
18969         local dir0=$DIR/$tdir/$testnum
18970         mkdir -p $dir0 || error "creating dir $dir0"
18971
18972         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18973         [[ ${DV[0]} != ${DV[1]} ]] ||
18974                 error "data version did not change on write"\
18975                       " ${DV[0]} == ${DV[1]}"
18976
18977         # clean up
18978         rm -f $file1
18979 }
18980 run_test 187b "Test data version change on volatile file"
18981
18982 test_200() {
18983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18984         remote_mgs_nodsh && skip "remote MGS with nodsh"
18985         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18986
18987         local POOL=${POOL:-cea1}
18988         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18989         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18990         # Pool OST targets
18991         local first_ost=0
18992         local last_ost=$(($OSTCOUNT - 1))
18993         local ost_step=2
18994         local ost_list=$(seq $first_ost $ost_step $last_ost)
18995         local ost_range="$first_ost $last_ost $ost_step"
18996         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18997         local file_dir=$POOL_ROOT/file_tst
18998         local subdir=$test_path/subdir
18999         local rc=0
19000
19001         while : ; do
19002                 # former test_200a test_200b
19003                 pool_add $POOL                          || { rc=$? ; break; }
19004                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19005                 # former test_200c test_200d
19006                 mkdir -p $test_path
19007                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19008                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19009                 mkdir -p $subdir
19010                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19011                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19012                                                         || { rc=$? ; break; }
19013                 # former test_200e test_200f
19014                 local files=$((OSTCOUNT*3))
19015                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19016                                                         || { rc=$? ; break; }
19017                 pool_create_files $POOL $file_dir $files "$ost_list" \
19018                                                         || { rc=$? ; break; }
19019                 # former test_200g test_200h
19020                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19021                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19022
19023                 # former test_201a test_201b test_201c
19024                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19025
19026                 local f=$test_path/$tfile
19027                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19028                 pool_remove $POOL $f                    || { rc=$? ; break; }
19029                 break
19030         done
19031
19032         destroy_test_pools
19033
19034         return $rc
19035 }
19036 run_test 200 "OST pools"
19037
19038 # usage: default_attr <count | size | offset>
19039 default_attr() {
19040         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19041 }
19042
19043 # usage: check_default_stripe_attr
19044 check_default_stripe_attr() {
19045         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19046         case $1 in
19047         --stripe-count|-c)
19048                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19049         --stripe-size|-S)
19050                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19051         --stripe-index|-i)
19052                 EXPECTED=-1;;
19053         *)
19054                 error "unknown getstripe attr '$1'"
19055         esac
19056
19057         [ $ACTUAL == $EXPECTED ] ||
19058                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19059 }
19060
19061 test_204a() {
19062         test_mkdir $DIR/$tdir
19063         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19064
19065         check_default_stripe_attr --stripe-count
19066         check_default_stripe_attr --stripe-size
19067         check_default_stripe_attr --stripe-index
19068 }
19069 run_test 204a "Print default stripe attributes"
19070
19071 test_204b() {
19072         test_mkdir $DIR/$tdir
19073         $LFS setstripe --stripe-count 1 $DIR/$tdir
19074
19075         check_default_stripe_attr --stripe-size
19076         check_default_stripe_attr --stripe-index
19077 }
19078 run_test 204b "Print default stripe size and offset"
19079
19080 test_204c() {
19081         test_mkdir $DIR/$tdir
19082         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19083
19084         check_default_stripe_attr --stripe-count
19085         check_default_stripe_attr --stripe-index
19086 }
19087 run_test 204c "Print default stripe count and offset"
19088
19089 test_204d() {
19090         test_mkdir $DIR/$tdir
19091         $LFS setstripe --stripe-index 0 $DIR/$tdir
19092
19093         check_default_stripe_attr --stripe-count
19094         check_default_stripe_attr --stripe-size
19095 }
19096 run_test 204d "Print default stripe count and size"
19097
19098 test_204e() {
19099         test_mkdir $DIR/$tdir
19100         $LFS setstripe -d $DIR/$tdir
19101
19102         check_default_stripe_attr --stripe-count --raw
19103         check_default_stripe_attr --stripe-size --raw
19104         check_default_stripe_attr --stripe-index --raw
19105 }
19106 run_test 204e "Print raw stripe attributes"
19107
19108 test_204f() {
19109         test_mkdir $DIR/$tdir
19110         $LFS setstripe --stripe-count 1 $DIR/$tdir
19111
19112         check_default_stripe_attr --stripe-size --raw
19113         check_default_stripe_attr --stripe-index --raw
19114 }
19115 run_test 204f "Print raw stripe size and offset"
19116
19117 test_204g() {
19118         test_mkdir $DIR/$tdir
19119         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19120
19121         check_default_stripe_attr --stripe-count --raw
19122         check_default_stripe_attr --stripe-index --raw
19123 }
19124 run_test 204g "Print raw stripe count and offset"
19125
19126 test_204h() {
19127         test_mkdir $DIR/$tdir
19128         $LFS setstripe --stripe-index 0 $DIR/$tdir
19129
19130         check_default_stripe_attr --stripe-count --raw
19131         check_default_stripe_attr --stripe-size --raw
19132 }
19133 run_test 204h "Print raw stripe count and size"
19134
19135 # Figure out which job scheduler is being used, if any,
19136 # or use a fake one
19137 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19138         JOBENV=SLURM_JOB_ID
19139 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19140         JOBENV=LSB_JOBID
19141 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19142         JOBENV=PBS_JOBID
19143 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19144         JOBENV=LOADL_STEP_ID
19145 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19146         JOBENV=JOB_ID
19147 else
19148         $LCTL list_param jobid_name > /dev/null 2>&1
19149         if [ $? -eq 0 ]; then
19150                 JOBENV=nodelocal
19151         else
19152                 JOBENV=FAKE_JOBID
19153         fi
19154 fi
19155 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19156
19157 verify_jobstats() {
19158         local cmd=($1)
19159         shift
19160         local facets="$@"
19161
19162 # we don't really need to clear the stats for this test to work, since each
19163 # command has a unique jobid, but it makes debugging easier if needed.
19164 #       for facet in $facets; do
19165 #               local dev=$(convert_facet2label $facet)
19166 #               # clear old jobstats
19167 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19168 #       done
19169
19170         # use a new JobID for each test, or we might see an old one
19171         [ "$JOBENV" = "FAKE_JOBID" ] &&
19172                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19173
19174         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19175
19176         [ "$JOBENV" = "nodelocal" ] && {
19177                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19178                 $LCTL set_param jobid_name=$FAKE_JOBID
19179                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19180         }
19181
19182         log "Test: ${cmd[*]}"
19183         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19184
19185         if [ $JOBENV = "FAKE_JOBID" ]; then
19186                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19187         else
19188                 ${cmd[*]}
19189         fi
19190
19191         # all files are created on OST0000
19192         for facet in $facets; do
19193                 local stats="*.$(convert_facet2label $facet).job_stats"
19194
19195                 # strip out libtool wrappers for in-tree executables
19196                 if (( $(do_facet $facet lctl get_param $stats |
19197                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19198                         do_facet $facet lctl get_param $stats
19199                         error "No jobstats for $JOBVAL found on $facet::$stats"
19200                 fi
19201         done
19202 }
19203
19204 jobstats_set() {
19205         local new_jobenv=$1
19206
19207         set_persistent_param_and_check client "jobid_var" \
19208                 "$FSNAME.sys.jobid_var" $new_jobenv
19209 }
19210
19211 test_205a() { # Job stats
19212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19213         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19214                 skip "Need MDS version with at least 2.7.1"
19215         remote_mgs_nodsh && skip "remote MGS with nodsh"
19216         remote_mds_nodsh && skip "remote MDS with nodsh"
19217         remote_ost_nodsh && skip "remote OST with nodsh"
19218         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19219                 skip "Server doesn't support jobstats"
19220         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19221
19222         local old_jobenv=$($LCTL get_param -n jobid_var)
19223         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19224
19225         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19226                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19227         else
19228                 stack_trap "do_facet mgs $PERM_CMD \
19229                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19230         fi
19231         changelog_register
19232
19233         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19234                                 mdt.*.job_cleanup_interval | head -n 1)
19235         local new_interval=5
19236         do_facet $SINGLEMDS \
19237                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19238         stack_trap "do_facet $SINGLEMDS \
19239                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19240         local start=$SECONDS
19241
19242         local cmd
19243         # mkdir
19244         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19245         verify_jobstats "$cmd" "$SINGLEMDS"
19246         # rmdir
19247         cmd="rmdir $DIR/$tdir"
19248         verify_jobstats "$cmd" "$SINGLEMDS"
19249         # mkdir on secondary MDT
19250         if [ $MDSCOUNT -gt 1 ]; then
19251                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19252                 verify_jobstats "$cmd" "mds2"
19253         fi
19254         # mknod
19255         cmd="mknod $DIR/$tfile c 1 3"
19256         verify_jobstats "$cmd" "$SINGLEMDS"
19257         # unlink
19258         cmd="rm -f $DIR/$tfile"
19259         verify_jobstats "$cmd" "$SINGLEMDS"
19260         # create all files on OST0000 so verify_jobstats can find OST stats
19261         # open & close
19262         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19263         verify_jobstats "$cmd" "$SINGLEMDS"
19264         # setattr
19265         cmd="touch $DIR/$tfile"
19266         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19267         # write
19268         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19269         verify_jobstats "$cmd" "ost1"
19270         # read
19271         cancel_lru_locks osc
19272         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19273         verify_jobstats "$cmd" "ost1"
19274         # truncate
19275         cmd="$TRUNCATE $DIR/$tfile 0"
19276         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19277         # rename
19278         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19279         verify_jobstats "$cmd" "$SINGLEMDS"
19280         # jobstats expiry - sleep until old stats should be expired
19281         local left=$((new_interval + 5 - (SECONDS - start)))
19282         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19283                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19284                         "0" $left
19285         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19286         verify_jobstats "$cmd" "$SINGLEMDS"
19287         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19288             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19289
19290         # Ensure that jobid are present in changelog (if supported by MDS)
19291         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19292                 changelog_dump | tail -10
19293                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19294                 [ $jobids -eq 9 ] ||
19295                         error "Wrong changelog jobid count $jobids != 9"
19296
19297                 # LU-5862
19298                 JOBENV="disable"
19299                 jobstats_set $JOBENV
19300                 touch $DIR/$tfile
19301                 changelog_dump | grep $tfile
19302                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19303                 [ $jobids -eq 0 ] ||
19304                         error "Unexpected jobids when jobid_var=$JOBENV"
19305         fi
19306
19307         # test '%j' access to environment variable - if supported
19308         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19309                 JOBENV="JOBCOMPLEX"
19310                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19311
19312                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19313         fi
19314
19315         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19316                 JOBENV="JOBCOMPLEX"
19317                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19318
19319                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19320         fi
19321
19322         # test '%j' access to per-session jobid - if supported
19323         if lctl list_param jobid_this_session > /dev/null 2>&1
19324         then
19325                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19326                 lctl set_param jobid_this_session=$USER
19327
19328                 JOBENV="JOBCOMPLEX"
19329                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19330
19331                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19332         fi
19333 }
19334 run_test 205a "Verify job stats"
19335
19336 # LU-13117, LU-13597
19337 test_205b() {
19338         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19339                 skip "Need MDS version at least 2.13.54.91"
19340
19341         local job_stats="mdt.*.job_stats"
19342         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19343
19344         do_facet mds1 $LCTL set_param $job_stats=clear
19345
19346         # Setting jobid_var to USER might not be supported
19347         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19348         $LCTL set_param jobid_var=USER || true
19349         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19350         $LCTL set_param jobid_name="%j.%e.%u"
19351
19352         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19353         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19354                 { do_facet mds1 $LCTL get_param $job_stats;
19355                   error "Unexpected jobid found"; }
19356         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19357                 { do_facet mds1 $LCTL get_param $job_stats;
19358                   error "wrong job_stats format found"; }
19359
19360         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19361                 echo "MDS does not yet escape jobid" && return 0
19362         $LCTL set_param jobid_var=TEST205b
19363         env -i TEST205b="has sp" touch $DIR/$tfile.2
19364         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19365                 { do_facet mds1 $LCTL get_param $job_stats;
19366                   error "jobid not escaped"; }
19367 }
19368 run_test 205b "Verify job stats jobid and output format"
19369
19370 # LU-13733
19371 test_205c() {
19372         $LCTL set_param llite.*.stats=0
19373         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19374         $LCTL get_param llite.*.stats
19375         $LCTL get_param llite.*.stats | grep \
19376                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19377                         error "wrong client stats format found"
19378 }
19379 run_test 205c "Verify client stats format"
19380
19381 test_205d() {
19382         local file=$DIR/$tdir/$tfile
19383
19384         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19385                 skip "need lustre >= 2.15.53 for lljobstat"
19386         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19387                 skip "need lustre >= 2.15.53 for lljobstat"
19388         verify_yaml_available || skip_env "YAML verification not installed"
19389
19390         test_mkdir -i 0 $DIR/$tdir
19391         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19392
19393         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19394                 error "failed to write data to $file"
19395         mv $file $file.2
19396
19397         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19398         echo -n 'verify rename_stats...'
19399         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19400                 verify_yaml || error "rename_stats is not valid YAML"
19401         echo " OK"
19402
19403         echo -n 'verify mdt job_stats...'
19404         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19405                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19406         echo " OK"
19407
19408         echo -n 'verify ost job_stats...'
19409         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19410                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19411         echo " OK"
19412 }
19413 run_test 205d "verify the format of some stats files"
19414
19415 test_205e() {
19416         local ops_comma
19417         local file=$DIR/$tdir/$tfile
19418
19419         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19420                 skip "need lustre >= 2.15.53 for lljobstat"
19421         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19422                 skip "need lustre >= 2.15.53 for lljobstat"
19423         verify_yaml_available || skip_env "YAML verification not installed"
19424
19425         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19426
19427         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19428                 error "failed to create $file on ost1"
19429         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19430                 error "failed to write data to $file"
19431
19432         do_facet mds1 "$LCTL get_param *.*.job_stats"
19433         do_facet ost1 "$LCTL get_param *.*.job_stats"
19434
19435         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19436         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19437                 error "The output of lljobstat is not an valid YAML"
19438
19439         # verify that job dd.0 does exist and has some ops on ost1
19440         # typically this line is like:
19441         # - dd.0:            {ops: 20, ...}
19442         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19443                     awk '$2=="dd.0:" {print $4}')
19444
19445         (( ${ops_comma%,} >= 10 )) ||
19446                 error "cannot find job dd.0 with ops >= 10"
19447 }
19448 run_test 205e "verify the output of lljobstat"
19449
19450 # LU-1480, LU-1773 and LU-1657
19451 test_206() {
19452         mkdir -p $DIR/$tdir
19453         $LFS setstripe -c -1 $DIR/$tdir
19454 #define OBD_FAIL_LOV_INIT 0x1403
19455         $LCTL set_param fail_loc=0xa0001403
19456         $LCTL set_param fail_val=1
19457         touch $DIR/$tdir/$tfile || true
19458 }
19459 run_test 206 "fail lov_init_raid0() doesn't lbug"
19460
19461 test_207a() {
19462         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19463         local fsz=`stat -c %s $DIR/$tfile`
19464         cancel_lru_locks mdc
19465
19466         # do not return layout in getattr intent
19467 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19468         $LCTL set_param fail_loc=0x170
19469         local sz=`stat -c %s $DIR/$tfile`
19470
19471         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19472
19473         rm -rf $DIR/$tfile
19474 }
19475 run_test 207a "can refresh layout at glimpse"
19476
19477 test_207b() {
19478         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19479         local cksum=`md5sum $DIR/$tfile`
19480         local fsz=`stat -c %s $DIR/$tfile`
19481         cancel_lru_locks mdc
19482         cancel_lru_locks osc
19483
19484         # do not return layout in getattr intent
19485 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19486         $LCTL set_param fail_loc=0x171
19487
19488         # it will refresh layout after the file is opened but before read issues
19489         echo checksum is "$cksum"
19490         echo "$cksum" |md5sum -c --quiet || error "file differs"
19491
19492         rm -rf $DIR/$tfile
19493 }
19494 run_test 207b "can refresh layout at open"
19495
19496 test_208() {
19497         # FIXME: in this test suite, only RD lease is used. This is okay
19498         # for now as only exclusive open is supported. After generic lease
19499         # is done, this test suite should be revised. - Jinshan
19500
19501         remote_mds_nodsh && skip "remote MDS with nodsh"
19502         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19503                 skip "Need MDS version at least 2.4.52"
19504
19505         echo "==== test 1: verify get lease work"
19506         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19507
19508         echo "==== test 2: verify lease can be broken by upcoming open"
19509         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19510         local PID=$!
19511         sleep 2
19512
19513         $MULTIOP $DIR/$tfile oO_RDWR:c
19514         kill -USR1 $PID && wait $PID || error "break lease error"
19515
19516         echo "==== test 3: verify lease can't be granted if an open already exists"
19517         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19518         local PID=$!
19519         sleep 2
19520
19521         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19522         kill -USR1 $PID && wait $PID || error "open file error"
19523
19524         echo "==== test 4: lease can sustain over recovery"
19525         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19526         PID=$!
19527         sleep 2
19528
19529         fail mds1
19530
19531         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19532
19533         echo "==== test 5: lease broken can't be regained by replay"
19534         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19535         PID=$!
19536         sleep 2
19537
19538         # open file to break lease and then recovery
19539         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19540         fail mds1
19541
19542         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19543
19544         rm -f $DIR/$tfile
19545 }
19546 run_test 208 "Exclusive open"
19547
19548 test_209() {
19549         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19550                 skip_env "must have disp_stripe"
19551
19552         touch $DIR/$tfile
19553         sync; sleep 5; sync;
19554
19555         echo 3 > /proc/sys/vm/drop_caches
19556         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19557                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19558         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19559
19560         # open/close 500 times
19561         for i in $(seq 500); do
19562                 cat $DIR/$tfile
19563         done
19564
19565         echo 3 > /proc/sys/vm/drop_caches
19566         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19567                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19568         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19569
19570         echo "before: $req_before, after: $req_after"
19571         [ $((req_after - req_before)) -ge 300 ] &&
19572                 error "open/close requests are not freed"
19573         return 0
19574 }
19575 run_test 209 "read-only open/close requests should be freed promptly"
19576
19577 test_210() {
19578         local pid
19579
19580         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19581         pid=$!
19582         sleep 1
19583
19584         $LFS getstripe $DIR/$tfile
19585         kill -USR1 $pid
19586         wait $pid || error "multiop failed"
19587
19588         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19589         pid=$!
19590         sleep 1
19591
19592         $LFS getstripe $DIR/$tfile
19593         kill -USR1 $pid
19594         wait $pid || error "multiop failed"
19595 }
19596 run_test 210 "lfs getstripe does not break leases"
19597
19598 test_212() {
19599         size=`date +%s`
19600         size=$((size % 8192 + 1))
19601         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19602         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19603         rm -f $DIR/f212 $DIR/f212.xyz
19604 }
19605 run_test 212 "Sendfile test ============================================"
19606
19607 test_213() {
19608         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19609         cancel_lru_locks osc
19610         lctl set_param fail_loc=0x8000040f
19611         # generate a read lock
19612         cat $DIR/$tfile > /dev/null
19613         # write to the file, it will try to cancel the above read lock.
19614         cat /etc/hosts >> $DIR/$tfile
19615 }
19616 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19617
19618 test_214() { # for bug 20133
19619         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19620         for (( i=0; i < 340; i++ )) ; do
19621                 touch $DIR/$tdir/d214c/a$i
19622         done
19623
19624         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19625         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19626         ls $DIR/d214c || error "ls $DIR/d214c failed"
19627         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19628         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19629 }
19630 run_test 214 "hash-indexed directory test - bug 20133"
19631
19632 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19633 create_lnet_proc_files() {
19634         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19635 }
19636
19637 # counterpart of create_lnet_proc_files
19638 remove_lnet_proc_files() {
19639         rm -f $TMP/lnet_$1.sys
19640 }
19641
19642 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19643 # 3rd arg as regexp for body
19644 check_lnet_proc_stats() {
19645         local l=$(cat "$TMP/lnet_$1" |wc -l)
19646         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19647
19648         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19649 }
19650
19651 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19652 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19653 # optional and can be regexp for 2nd line (lnet.routes case)
19654 check_lnet_proc_entry() {
19655         local blp=2          # blp stands for 'position of 1st line of body'
19656         [ -z "$5" ] || blp=3 # lnet.routes case
19657
19658         local l=$(cat "$TMP/lnet_$1" |wc -l)
19659         # subtracting one from $blp because the body can be empty
19660         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19661
19662         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19663                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19664
19665         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19666                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19667
19668         # bail out if any unexpected line happened
19669         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19670         [ "$?" != 0 ] || error "$2 misformatted"
19671 }
19672
19673 test_215() { # for bugs 18102, 21079, 21517
19674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19675
19676         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19677         local P='[1-9][0-9]*'           # positive numeric
19678         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19679         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19680         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19681         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19682
19683         local L1 # regexp for 1st line
19684         local L2 # regexp for 2nd line (optional)
19685         local BR # regexp for the rest (body)
19686
19687         # lnet.stats should look as 11 space-separated non-negative numerics
19688         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19689         create_lnet_proc_files "stats"
19690         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19691         remove_lnet_proc_files "stats"
19692
19693         # lnet.routes should look like this:
19694         # Routing disabled/enabled
19695         # net hops priority state router
19696         # where net is a string like tcp0, hops > 0, priority >= 0,
19697         # state is up/down,
19698         # router is a string like 192.168.1.1@tcp2
19699         L1="^Routing (disabled|enabled)$"
19700         L2="^net +hops +priority +state +router$"
19701         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19702         create_lnet_proc_files "routes"
19703         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19704         remove_lnet_proc_files "routes"
19705
19706         # lnet.routers should look like this:
19707         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19708         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19709         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19710         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19711         L1="^ref +rtr_ref +alive +router$"
19712         BR="^$P +$P +(up|down) +$NID$"
19713         create_lnet_proc_files "routers"
19714         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19715         remove_lnet_proc_files "routers"
19716
19717         # lnet.peers should look like this:
19718         # nid refs state last max rtr min tx min queue
19719         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19720         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19721         # numeric (0 or >0 or <0), queue >= 0.
19722         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19723         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19724         create_lnet_proc_files "peers"
19725         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19726         remove_lnet_proc_files "peers"
19727
19728         # lnet.buffers  should look like this:
19729         # pages count credits min
19730         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19731         L1="^pages +count +credits +min$"
19732         BR="^ +$N +$N +$I +$I$"
19733         create_lnet_proc_files "buffers"
19734         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19735         remove_lnet_proc_files "buffers"
19736
19737         # lnet.nis should look like this:
19738         # nid status alive refs peer rtr max tx min
19739         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19740         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19741         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19742         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19743         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19744         create_lnet_proc_files "nis"
19745         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19746         remove_lnet_proc_files "nis"
19747
19748         # can we successfully write to lnet.stats?
19749         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19750 }
19751 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19752
19753 test_216() { # bug 20317
19754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19755         remote_ost_nodsh && skip "remote OST with nodsh"
19756
19757         local node
19758         local facets=$(get_facets OST)
19759         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19760
19761         save_lustre_params client "osc.*.contention_seconds" > $p
19762         save_lustre_params $facets \
19763                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19764         save_lustre_params $facets \
19765                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19766         save_lustre_params $facets \
19767                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19768         clear_stats osc.*.osc_stats
19769
19770         # agressive lockless i/o settings
19771         do_nodes $(comma_list $(osts_nodes)) \
19772                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19773                         ldlm.namespaces.filter-*.contended_locks=0 \
19774                         ldlm.namespaces.filter-*.contention_seconds=60"
19775         lctl set_param -n osc.*.contention_seconds=60
19776
19777         $DIRECTIO write $DIR/$tfile 0 10 4096
19778         $CHECKSTAT -s 40960 $DIR/$tfile
19779
19780         # disable lockless i/o
19781         do_nodes $(comma_list $(osts_nodes)) \
19782                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19783                         ldlm.namespaces.filter-*.contended_locks=32 \
19784                         ldlm.namespaces.filter-*.contention_seconds=0"
19785         lctl set_param -n osc.*.contention_seconds=0
19786         clear_stats osc.*.osc_stats
19787
19788         dd if=/dev/zero of=$DIR/$tfile count=0
19789         $CHECKSTAT -s 0 $DIR/$tfile
19790
19791         restore_lustre_params <$p
19792         rm -f $p
19793         rm $DIR/$tfile
19794 }
19795 run_test 216 "check lockless direct write updates file size and kms correctly"
19796
19797 test_217() { # bug 22430
19798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19799
19800         local node
19801         local nid
19802
19803         for node in $(nodes_list); do
19804                 nid=$(host_nids_address $node $NETTYPE)
19805                 if [[ $nid = *-* ]] ; then
19806                         echo "lctl ping $(h2nettype $nid)"
19807                         lctl ping $(h2nettype $nid)
19808                 else
19809                         echo "skipping $node (no hyphen detected)"
19810                 fi
19811         done
19812 }
19813 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19814
19815 test_218() {
19816        # do directio so as not to populate the page cache
19817        log "creating a 10 Mb file"
19818        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19819        log "starting reads"
19820        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19821        log "truncating the file"
19822        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19823        log "killing dd"
19824        kill %+ || true # reads might have finished
19825        echo "wait until dd is finished"
19826        wait
19827        log "removing the temporary file"
19828        rm -rf $DIR/$tfile || error "tmp file removal failed"
19829 }
19830 run_test 218 "parallel read and truncate should not deadlock"
19831
19832 test_219() {
19833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19834
19835         # write one partial page
19836         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19837         # set no grant so vvp_io_commit_write will do sync write
19838         $LCTL set_param fail_loc=0x411
19839         # write a full page at the end of file
19840         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19841
19842         $LCTL set_param fail_loc=0
19843         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19844         $LCTL set_param fail_loc=0x411
19845         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19846
19847         # LU-4201
19848         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19849         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19850 }
19851 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19852
19853 test_220() { #LU-325
19854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19855         remote_ost_nodsh && skip "remote OST with nodsh"
19856         remote_mds_nodsh && skip "remote MDS with nodsh"
19857         remote_mgs_nodsh && skip "remote MGS with nodsh"
19858
19859         local OSTIDX=0
19860
19861         # create on MDT0000 so the last_id and next_id are correct
19862         mkdir_on_mdt0 $DIR/$tdir
19863         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19864         OST=${OST%_UUID}
19865
19866         # on the mdt's osc
19867         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19868         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19869                         osp.$mdtosc_proc1.prealloc_last_id)
19870         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19871                         osp.$mdtosc_proc1.prealloc_next_id)
19872
19873         $LFS df -i
19874
19875         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19876         #define OBD_FAIL_OST_ENOINO              0x229
19877         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19878         create_pool $FSNAME.$TESTNAME || return 1
19879         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19880
19881         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19882
19883         MDSOBJS=$((last_id - next_id))
19884         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19885
19886         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19887         echo "OST still has $count kbytes free"
19888
19889         echo "create $MDSOBJS files @next_id..."
19890         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19891
19892         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19893                         osp.$mdtosc_proc1.prealloc_last_id)
19894         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19895                         osp.$mdtosc_proc1.prealloc_next_id)
19896
19897         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19898         $LFS df -i
19899
19900         echo "cleanup..."
19901
19902         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19903         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19904
19905         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19906                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19907         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19908                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19909         echo "unlink $MDSOBJS files @$next_id..."
19910         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19911 }
19912 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19913
19914 test_221() {
19915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19916
19917         dd if=`which date` of=$MOUNT/date oflag=sync
19918         chmod +x $MOUNT/date
19919
19920         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19921         $LCTL set_param fail_loc=0x80001401
19922
19923         $MOUNT/date > /dev/null
19924         rm -f $MOUNT/date
19925 }
19926 run_test 221 "make sure fault and truncate race to not cause OOM"
19927
19928 test_222a () {
19929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19930
19931         rm -rf $DIR/$tdir
19932         test_mkdir $DIR/$tdir
19933         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19934         createmany -o $DIR/$tdir/$tfile 10
19935         cancel_lru_locks mdc
19936         cancel_lru_locks osc
19937         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19938         $LCTL set_param fail_loc=0x31a
19939         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19940         $LCTL set_param fail_loc=0
19941         rm -r $DIR/$tdir
19942 }
19943 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19944
19945 test_222b () {
19946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19947
19948         rm -rf $DIR/$tdir
19949         test_mkdir $DIR/$tdir
19950         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19951         createmany -o $DIR/$tdir/$tfile 10
19952         cancel_lru_locks mdc
19953         cancel_lru_locks osc
19954         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19955         $LCTL set_param fail_loc=0x31a
19956         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19957         $LCTL set_param fail_loc=0
19958 }
19959 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19960
19961 test_223 () {
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_NOLOCK          0x31b
19971         $LCTL set_param fail_loc=0x31b
19972         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19973         $LCTL set_param fail_loc=0
19974         rm -r $DIR/$tdir
19975 }
19976 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19977
19978 test_224a() { # LU-1039, MRP-303
19979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19980         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19981         $LCTL set_param fail_loc=0x508
19982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19983         $LCTL set_param fail_loc=0
19984         df $DIR
19985 }
19986 run_test 224a "Don't panic on bulk IO failure"
19987
19988 test_224bd_sub() { # LU-1039, MRP-303
19989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19990         local timeout=$1
19991
19992         shift
19993         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19994
19995         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19996
19997         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19998         cancel_lru_locks osc
19999         set_checksums 0
20000         stack_trap "set_checksums $ORIG_CSUM" EXIT
20001         local at_max_saved=0
20002
20003         # adaptive timeouts may prevent seeing the issue
20004         if at_is_enabled; then
20005                 at_max_saved=$(at_max_get mds)
20006                 at_max_set 0 mds client
20007                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20008         fi
20009
20010         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20011         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20012         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20013
20014         do_facet ost1 $LCTL set_param fail_loc=0
20015         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20016         df $DIR
20017 }
20018
20019 test_224b() {
20020         test_224bd_sub 3 error "dd failed"
20021 }
20022 run_test 224b "Don't panic on bulk IO failure"
20023
20024 test_224c() { # LU-6441
20025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20026         remote_mds_nodsh && skip "remote MDS with nodsh"
20027
20028         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20029         save_writethrough $p
20030         set_cache writethrough on
20031
20032         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20033         local at_max=$($LCTL get_param -n at_max)
20034         local timeout=$($LCTL get_param -n timeout)
20035         local test_at="at_max"
20036         local param_at="$FSNAME.sys.at_max"
20037         local test_timeout="timeout"
20038         local param_timeout="$FSNAME.sys.timeout"
20039
20040         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20041
20042         set_persistent_param_and_check client "$test_at" "$param_at" 0
20043         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20044
20045         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20046         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20047         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20048         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20049         sync
20050         do_facet ost1 "$LCTL set_param fail_loc=0"
20051
20052         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20053         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20054                 $timeout
20055
20056         $LCTL set_param -n $pages_per_rpc
20057         restore_lustre_params < $p
20058         rm -f $p
20059 }
20060 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20061
20062 test_224d() { # LU-11169
20063         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20064 }
20065 run_test 224d "Don't corrupt data on bulk IO timeout"
20066
20067 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20068 test_225a () {
20069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20070         if [ -z ${MDSSURVEY} ]; then
20071                 skip_env "mds-survey not found"
20072         fi
20073         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20074                 skip "Need MDS version at least 2.2.51"
20075
20076         local mds=$(facet_host $SINGLEMDS)
20077         local target=$(do_nodes $mds 'lctl dl' |
20078                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20079
20080         local cmd1="file_count=1000 thrhi=4"
20081         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20082         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20083         local cmd="$cmd1 $cmd2 $cmd3"
20084
20085         rm -f ${TMP}/mds_survey*
20086         echo + $cmd
20087         eval $cmd || error "mds-survey with zero-stripe failed"
20088         cat ${TMP}/mds_survey*
20089         rm -f ${TMP}/mds_survey*
20090 }
20091 run_test 225a "Metadata survey sanity with zero-stripe"
20092
20093 test_225b () {
20094         if [ -z ${MDSSURVEY} ]; then
20095                 skip_env "mds-survey not found"
20096         fi
20097         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20098                 skip "Need MDS version at least 2.2.51"
20099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20100         remote_mds_nodsh && skip "remote MDS with nodsh"
20101         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20102                 skip_env "Need to mount OST to test"
20103         fi
20104
20105         local mds=$(facet_host $SINGLEMDS)
20106         local target=$(do_nodes $mds 'lctl dl' |
20107                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20108
20109         local cmd1="file_count=1000 thrhi=4"
20110         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20111         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20112         local cmd="$cmd1 $cmd2 $cmd3"
20113
20114         rm -f ${TMP}/mds_survey*
20115         echo + $cmd
20116         eval $cmd || error "mds-survey with stripe_count failed"
20117         cat ${TMP}/mds_survey*
20118         rm -f ${TMP}/mds_survey*
20119 }
20120 run_test 225b "Metadata survey sanity with stripe_count = 1"
20121
20122 mcreate_path2fid () {
20123         local mode=$1
20124         local major=$2
20125         local minor=$3
20126         local name=$4
20127         local desc=$5
20128         local path=$DIR/$tdir/$name
20129         local fid
20130         local rc
20131         local fid_path
20132
20133         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20134                 error "cannot create $desc"
20135
20136         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20137         rc=$?
20138         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20139
20140         fid_path=$($LFS fid2path $MOUNT $fid)
20141         rc=$?
20142         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20143
20144         [ "$path" == "$fid_path" ] ||
20145                 error "fid2path returned $fid_path, expected $path"
20146
20147         echo "pass with $path and $fid"
20148 }
20149
20150 test_226a () {
20151         rm -rf $DIR/$tdir
20152         mkdir -p $DIR/$tdir
20153
20154         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20155         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20156         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20157         mcreate_path2fid 0040666 0 0 dir "directory"
20158         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20159         mcreate_path2fid 0100666 0 0 file "regular file"
20160         mcreate_path2fid 0120666 0 0 link "symbolic link"
20161         mcreate_path2fid 0140666 0 0 sock "socket"
20162 }
20163 run_test 226a "call path2fid and fid2path on files of all type"
20164
20165 test_226b () {
20166         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20167
20168         local MDTIDX=1
20169
20170         rm -rf $DIR/$tdir
20171         mkdir -p $DIR/$tdir
20172         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20173                 error "create remote directory failed"
20174         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20175         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20176                                 "character special file (null)"
20177         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20178                                 "character special file (no device)"
20179         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20180         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20181                                 "block special file (loop)"
20182         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20183         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20184         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20185 }
20186 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20187
20188 test_226c () {
20189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20190         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20191                 skip "Need MDS version at least 2.13.55"
20192
20193         local submnt=/mnt/submnt
20194         local srcfile=/etc/passwd
20195         local dstfile=$submnt/passwd
20196         local path
20197         local fid
20198
20199         rm -rf $DIR/$tdir
20200         rm -rf $submnt
20201         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20202                 error "create remote directory failed"
20203         mkdir -p $submnt || error "create $submnt failed"
20204         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20205                 error "mount $submnt failed"
20206         stack_trap "umount $submnt" EXIT
20207
20208         cp $srcfile $dstfile
20209         fid=$($LFS path2fid $dstfile)
20210         path=$($LFS fid2path $submnt "$fid")
20211         [ "$path" = "$dstfile" ] ||
20212                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20213 }
20214 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20215
20216 # LU-1299 Executing or running ldd on a truncated executable does not
20217 # cause an out-of-memory condition.
20218 test_227() {
20219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20220         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20221
20222         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20223         chmod +x $MOUNT/date
20224
20225         $MOUNT/date > /dev/null
20226         ldd $MOUNT/date > /dev/null
20227         rm -f $MOUNT/date
20228 }
20229 run_test 227 "running truncated executable does not cause OOM"
20230
20231 # LU-1512 try to reuse idle OI blocks
20232 test_228a() {
20233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20234         remote_mds_nodsh && skip "remote MDS with nodsh"
20235         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20236
20237         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20238         local myDIR=$DIR/$tdir
20239
20240         mkdir -p $myDIR
20241         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20242         $LCTL set_param fail_loc=0x80001002
20243         createmany -o $myDIR/t- 10000
20244         $LCTL set_param fail_loc=0
20245         # The guard is current the largest FID holder
20246         touch $myDIR/guard
20247         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20248                     tr -d '[')
20249         local IDX=$(($SEQ % 64))
20250
20251         do_facet $SINGLEMDS sync
20252         # Make sure journal flushed.
20253         sleep 6
20254         local blk1=$(do_facet $SINGLEMDS \
20255                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20256                      grep Blockcount | awk '{print $4}')
20257
20258         # Remove old files, some OI blocks will become idle.
20259         unlinkmany $myDIR/t- 10000
20260         # Create new files, idle OI blocks should be reused.
20261         createmany -o $myDIR/t- 2000
20262         do_facet $SINGLEMDS sync
20263         # Make sure journal flushed.
20264         sleep 6
20265         local blk2=$(do_facet $SINGLEMDS \
20266                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20267                      grep Blockcount | awk '{print $4}')
20268
20269         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20270 }
20271 run_test 228a "try to reuse idle OI blocks"
20272
20273 test_228b() {
20274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20275         remote_mds_nodsh && skip "remote MDS with nodsh"
20276         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20277
20278         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20279         local myDIR=$DIR/$tdir
20280
20281         mkdir -p $myDIR
20282         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20283         $LCTL set_param fail_loc=0x80001002
20284         createmany -o $myDIR/t- 10000
20285         $LCTL set_param fail_loc=0
20286         # The guard is current the largest FID holder
20287         touch $myDIR/guard
20288         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20289                     tr -d '[')
20290         local IDX=$(($SEQ % 64))
20291
20292         do_facet $SINGLEMDS sync
20293         # Make sure journal flushed.
20294         sleep 6
20295         local blk1=$(do_facet $SINGLEMDS \
20296                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20297                      grep Blockcount | awk '{print $4}')
20298
20299         # Remove old files, some OI blocks will become idle.
20300         unlinkmany $myDIR/t- 10000
20301
20302         # stop the MDT
20303         stop $SINGLEMDS || error "Fail to stop MDT."
20304         # remount the MDT
20305         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20306                 error "Fail to start MDT."
20307
20308         client_up || error "Fail to df."
20309         # Create new files, idle OI blocks should be reused.
20310         createmany -o $myDIR/t- 2000
20311         do_facet $SINGLEMDS sync
20312         # Make sure journal flushed.
20313         sleep 6
20314         local blk2=$(do_facet $SINGLEMDS \
20315                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20316                      grep Blockcount | awk '{print $4}')
20317
20318         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20319 }
20320 run_test 228b "idle OI blocks can be reused after MDT restart"
20321
20322 #LU-1881
20323 test_228c() {
20324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20325         remote_mds_nodsh && skip "remote MDS with nodsh"
20326         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20327
20328         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20329         local myDIR=$DIR/$tdir
20330
20331         mkdir -p $myDIR
20332         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20333         $LCTL set_param fail_loc=0x80001002
20334         # 20000 files can guarantee there are index nodes in the OI file
20335         createmany -o $myDIR/t- 20000
20336         $LCTL set_param fail_loc=0
20337         # The guard is current the largest FID holder
20338         touch $myDIR/guard
20339         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20340                     tr -d '[')
20341         local IDX=$(($SEQ % 64))
20342
20343         do_facet $SINGLEMDS sync
20344         # Make sure journal flushed.
20345         sleep 6
20346         local blk1=$(do_facet $SINGLEMDS \
20347                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20348                      grep Blockcount | awk '{print $4}')
20349
20350         # Remove old files, some OI blocks will become idle.
20351         unlinkmany $myDIR/t- 20000
20352         rm -f $myDIR/guard
20353         # The OI file should become empty now
20354
20355         # Create new files, idle OI blocks should be reused.
20356         createmany -o $myDIR/t- 2000
20357         do_facet $SINGLEMDS sync
20358         # Make sure journal flushed.
20359         sleep 6
20360         local blk2=$(do_facet $SINGLEMDS \
20361                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20362                      grep Blockcount | awk '{print $4}')
20363
20364         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20365 }
20366 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20367
20368 test_229() { # LU-2482, LU-3448
20369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20370         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20371         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20372                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20373
20374         rm -f $DIR/$tfile
20375
20376         # Create a file with a released layout and stripe count 2.
20377         $MULTIOP $DIR/$tfile H2c ||
20378                 error "failed to create file with released layout"
20379
20380         $LFS getstripe -v $DIR/$tfile
20381
20382         local pattern=$($LFS getstripe -L $DIR/$tfile)
20383         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20384
20385         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20386                 error "getstripe"
20387         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20388         stat $DIR/$tfile || error "failed to stat released file"
20389
20390         chown $RUNAS_ID $DIR/$tfile ||
20391                 error "chown $RUNAS_ID $DIR/$tfile failed"
20392
20393         chgrp $RUNAS_ID $DIR/$tfile ||
20394                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20395
20396         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20397         rm $DIR/$tfile || error "failed to remove released file"
20398 }
20399 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20400
20401 test_230a() {
20402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20404         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20405                 skip "Need MDS version at least 2.11.52"
20406
20407         local MDTIDX=1
20408
20409         test_mkdir $DIR/$tdir
20410         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20411         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20412         [ $mdt_idx -ne 0 ] &&
20413                 error "create local directory on wrong MDT $mdt_idx"
20414
20415         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20416                         error "create remote directory failed"
20417         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20418         [ $mdt_idx -ne $MDTIDX ] &&
20419                 error "create remote directory on wrong MDT $mdt_idx"
20420
20421         createmany -o $DIR/$tdir/test_230/t- 10 ||
20422                 error "create files on remote directory failed"
20423         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20424         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20425         rm -r $DIR/$tdir || error "unlink remote directory failed"
20426 }
20427 run_test 230a "Create remote directory and files under the remote directory"
20428
20429 test_230b() {
20430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20432         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20433                 skip "Need MDS version at least 2.11.52"
20434
20435         local MDTIDX=1
20436         local mdt_index
20437         local i
20438         local file
20439         local pid
20440         local stripe_count
20441         local migrate_dir=$DIR/$tdir/migrate_dir
20442         local other_dir=$DIR/$tdir/other_dir
20443
20444         test_mkdir $DIR/$tdir
20445         test_mkdir -i0 -c1 $migrate_dir
20446         test_mkdir -i0 -c1 $other_dir
20447         for ((i=0; i<10; i++)); do
20448                 mkdir -p $migrate_dir/dir_${i}
20449                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20450                         error "create files under remote dir failed $i"
20451         done
20452
20453         cp /etc/passwd $migrate_dir/$tfile
20454         cp /etc/passwd $other_dir/$tfile
20455         chattr +SAD $migrate_dir
20456         chattr +SAD $migrate_dir/$tfile
20457
20458         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20459         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20460         local old_dir_mode=$(stat -c%f $migrate_dir)
20461         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20462
20463         mkdir -p $migrate_dir/dir_default_stripe2
20464         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20465         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20466
20467         mkdir -p $other_dir
20468         ln $migrate_dir/$tfile $other_dir/luna
20469         ln $migrate_dir/$tfile $migrate_dir/sofia
20470         ln $other_dir/$tfile $migrate_dir/david
20471         ln -s $migrate_dir/$tfile $other_dir/zachary
20472         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20473         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20474
20475         local len
20476         local lnktgt
20477
20478         # inline symlink
20479         for len in 58 59 60; do
20480                 lnktgt=$(str_repeat 'l' $len)
20481                 touch $migrate_dir/$lnktgt
20482                 ln -s $lnktgt $migrate_dir/${len}char_ln
20483         done
20484
20485         # PATH_MAX
20486         for len in 4094 4095; do
20487                 lnktgt=$(str_repeat 'l' $len)
20488                 ln -s $lnktgt $migrate_dir/${len}char_ln
20489         done
20490
20491         # NAME_MAX
20492         for len in 254 255; do
20493                 touch $migrate_dir/$(str_repeat 'l' $len)
20494         done
20495
20496         $LFS migrate -m $MDTIDX $migrate_dir ||
20497                 error "fails on migrating remote dir to MDT1"
20498
20499         echo "migratate to MDT1, then checking.."
20500         for ((i = 0; i < 10; i++)); do
20501                 for file in $(find $migrate_dir/dir_${i}); do
20502                         mdt_index=$($LFS getstripe -m $file)
20503                         # broken symlink getstripe will fail
20504                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20505                                 error "$file is not on MDT${MDTIDX}"
20506                 done
20507         done
20508
20509         # the multiple link file should still in MDT0
20510         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20511         [ $mdt_index == 0 ] ||
20512                 error "$file is not on MDT${MDTIDX}"
20513
20514         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20515         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20516                 error " expect $old_dir_flag get $new_dir_flag"
20517
20518         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20519         [ "$old_file_flag" = "$new_file_flag" ] ||
20520                 error " expect $old_file_flag get $new_file_flag"
20521
20522         local new_dir_mode=$(stat -c%f $migrate_dir)
20523         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20524                 error "expect mode $old_dir_mode get $new_dir_mode"
20525
20526         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20527         [ "$old_file_mode" = "$new_file_mode" ] ||
20528                 error "expect mode $old_file_mode get $new_file_mode"
20529
20530         diff /etc/passwd $migrate_dir/$tfile ||
20531                 error "$tfile different after migration"
20532
20533         diff /etc/passwd $other_dir/luna ||
20534                 error "luna different after migration"
20535
20536         diff /etc/passwd $migrate_dir/sofia ||
20537                 error "sofia different after migration"
20538
20539         diff /etc/passwd $migrate_dir/david ||
20540                 error "david different after migration"
20541
20542         diff /etc/passwd $other_dir/zachary ||
20543                 error "zachary different after migration"
20544
20545         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20546                 error "${tfile}_ln different after migration"
20547
20548         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20549                 error "${tfile}_ln_other different after migration"
20550
20551         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20552         [ $stripe_count = 2 ] ||
20553                 error "dir strpe_count $d != 2 after migration."
20554
20555         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20556         [ $stripe_count = 2 ] ||
20557                 error "file strpe_count $d != 2 after migration."
20558
20559         #migrate back to MDT0
20560         MDTIDX=0
20561
20562         $LFS migrate -m $MDTIDX $migrate_dir ||
20563                 error "fails on migrating remote dir to MDT0"
20564
20565         echo "migrate back to MDT0, checking.."
20566         for file in $(find $migrate_dir); do
20567                 mdt_index=$($LFS getstripe -m $file)
20568                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20569                         error "$file is not on MDT${MDTIDX}"
20570         done
20571
20572         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20573         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20574                 error " expect $old_dir_flag get $new_dir_flag"
20575
20576         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20577         [ "$old_file_flag" = "$new_file_flag" ] ||
20578                 error " expect $old_file_flag get $new_file_flag"
20579
20580         local new_dir_mode=$(stat -c%f $migrate_dir)
20581         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20582                 error "expect mode $old_dir_mode get $new_dir_mode"
20583
20584         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20585         [ "$old_file_mode" = "$new_file_mode" ] ||
20586                 error "expect mode $old_file_mode get $new_file_mode"
20587
20588         diff /etc/passwd ${migrate_dir}/$tfile ||
20589                 error "$tfile different after migration"
20590
20591         diff /etc/passwd ${other_dir}/luna ||
20592                 error "luna different after migration"
20593
20594         diff /etc/passwd ${migrate_dir}/sofia ||
20595                 error "sofia different after migration"
20596
20597         diff /etc/passwd ${other_dir}/zachary ||
20598                 error "zachary different after migration"
20599
20600         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20601                 error "${tfile}_ln different after migration"
20602
20603         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20604                 error "${tfile}_ln_other different after migration"
20605
20606         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20607         [ $stripe_count = 2 ] ||
20608                 error "dir strpe_count $d != 2 after migration."
20609
20610         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20611         [ $stripe_count = 2 ] ||
20612                 error "file strpe_count $d != 2 after migration."
20613
20614         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20615 }
20616 run_test 230b "migrate directory"
20617
20618 test_230c() {
20619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20621         remote_mds_nodsh && skip "remote MDS with nodsh"
20622         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20623                 skip "Need MDS version at least 2.11.52"
20624
20625         local MDTIDX=1
20626         local total=3
20627         local mdt_index
20628         local file
20629         local migrate_dir=$DIR/$tdir/migrate_dir
20630
20631         #If migrating directory fails in the middle, all entries of
20632         #the directory is still accessiable.
20633         test_mkdir $DIR/$tdir
20634         test_mkdir -i0 -c1 $migrate_dir
20635         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20636         stat $migrate_dir
20637         createmany -o $migrate_dir/f $total ||
20638                 error "create files under ${migrate_dir} failed"
20639
20640         # fail after migrating top dir, and this will fail only once, so the
20641         # first sub file migration will fail (currently f3), others succeed.
20642         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20643         do_facet mds1 lctl set_param fail_loc=0x1801
20644         local t=$(ls $migrate_dir | wc -l)
20645         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20646                 error "migrate should fail"
20647         local u=$(ls $migrate_dir | wc -l)
20648         [ "$u" == "$t" ] || error "$u != $t during migration"
20649
20650         # add new dir/file should succeed
20651         mkdir $migrate_dir/dir ||
20652                 error "mkdir failed under migrating directory"
20653         touch $migrate_dir/file ||
20654                 error "create file failed under migrating directory"
20655
20656         # add file with existing name should fail
20657         for file in $migrate_dir/f*; do
20658                 stat $file > /dev/null || error "stat $file failed"
20659                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20660                         error "open(O_CREAT|O_EXCL) $file should fail"
20661                 $MULTIOP $file m && error "create $file should fail"
20662                 touch $DIR/$tdir/remote_dir/$tfile ||
20663                         error "touch $tfile failed"
20664                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20665                         error "link $file should fail"
20666                 mdt_index=$($LFS getstripe -m $file)
20667                 if [ $mdt_index == 0 ]; then
20668                         # file failed to migrate is not allowed to rename to
20669                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20670                                 error "rename to $file should fail"
20671                 else
20672                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20673                                 error "rename to $file failed"
20674                 fi
20675                 echo hello >> $file || error "write $file failed"
20676         done
20677
20678         # resume migration with different options should fail
20679         $LFS migrate -m 0 $migrate_dir &&
20680                 error "migrate -m 0 $migrate_dir should fail"
20681
20682         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20683                 error "migrate -c 2 $migrate_dir should fail"
20684
20685         # resume migration should succeed
20686         $LFS migrate -m $MDTIDX $migrate_dir ||
20687                 error "migrate $migrate_dir failed"
20688
20689         echo "Finish migration, then checking.."
20690         for file in $(find $migrate_dir); do
20691                 mdt_index=$($LFS getstripe -m $file)
20692                 [ $mdt_index == $MDTIDX ] ||
20693                         error "$file is not on MDT${MDTIDX}"
20694         done
20695
20696         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20697 }
20698 run_test 230c "check directory accessiblity if migration failed"
20699
20700 test_230d() {
20701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20703         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20704                 skip "Need MDS version at least 2.11.52"
20705         # LU-11235
20706         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20707
20708         local migrate_dir=$DIR/$tdir/migrate_dir
20709         local old_index
20710         local new_index
20711         local old_count
20712         local new_count
20713         local new_hash
20714         local mdt_index
20715         local i
20716         local j
20717
20718         old_index=$((RANDOM % MDSCOUNT))
20719         old_count=$((MDSCOUNT - old_index))
20720         new_index=$((RANDOM % MDSCOUNT))
20721         new_count=$((MDSCOUNT - new_index))
20722         new_hash=1 # for all_char
20723
20724         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20725         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20726
20727         test_mkdir $DIR/$tdir
20728         test_mkdir -i $old_index -c $old_count $migrate_dir
20729
20730         for ((i=0; i<100; i++)); do
20731                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20732                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20733                         error "create files under remote dir failed $i"
20734         done
20735
20736         echo -n "Migrate from MDT$old_index "
20737         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20738         echo -n "to MDT$new_index"
20739         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20740         echo
20741
20742         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20743         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20744                 error "migrate remote dir error"
20745
20746         echo "Finish migration, then checking.."
20747         for file in $(find $migrate_dir -maxdepth 1); do
20748                 mdt_index=$($LFS getstripe -m $file)
20749                 if [ $mdt_index -lt $new_index ] ||
20750                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20751                         error "$file is on MDT$mdt_index"
20752                 fi
20753         done
20754
20755         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20756 }
20757 run_test 230d "check migrate big directory"
20758
20759 test_230e() {
20760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20762         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20763                 skip "Need MDS version at least 2.11.52"
20764
20765         local i
20766         local j
20767         local a_fid
20768         local b_fid
20769
20770         mkdir_on_mdt0 $DIR/$tdir
20771         mkdir $DIR/$tdir/migrate_dir
20772         mkdir $DIR/$tdir/other_dir
20773         touch $DIR/$tdir/migrate_dir/a
20774         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20775         ls $DIR/$tdir/other_dir
20776
20777         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20778                 error "migrate dir fails"
20779
20780         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20781         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20782
20783         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20784         [ $mdt_index == 0 ] || error "a is not on MDT0"
20785
20786         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20787                 error "migrate dir fails"
20788
20789         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20790         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20791
20792         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20793         [ $mdt_index == 1 ] || error "a is not on MDT1"
20794
20795         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20796         [ $mdt_index == 1 ] || error "b is not on MDT1"
20797
20798         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20799         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20800
20801         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20802
20803         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20804 }
20805 run_test 230e "migrate mulitple local link files"
20806
20807 test_230f() {
20808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20811                 skip "Need MDS version at least 2.11.52"
20812
20813         local a_fid
20814         local ln_fid
20815
20816         mkdir -p $DIR/$tdir
20817         mkdir $DIR/$tdir/migrate_dir
20818         $LFS mkdir -i1 $DIR/$tdir/other_dir
20819         touch $DIR/$tdir/migrate_dir/a
20820         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20821         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20822         ls $DIR/$tdir/other_dir
20823
20824         # a should be migrated to MDT1, since no other links on MDT0
20825         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20826                 error "#1 migrate dir fails"
20827         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20828         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20829         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20830         [ $mdt_index == 1 ] || error "a is not on MDT1"
20831
20832         # a should stay on MDT1, because it is a mulitple link file
20833         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20834                 error "#2 migrate dir fails"
20835         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20836         [ $mdt_index == 1 ] || error "a is not on MDT1"
20837
20838         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20839                 error "#3 migrate dir fails"
20840
20841         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20842         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20843         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20844
20845         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20846         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20847
20848         # a should be migrated to MDT0, since no other links on MDT1
20849         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20850                 error "#4 migrate dir fails"
20851         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20852         [ $mdt_index == 0 ] || error "a is not on MDT0"
20853
20854         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20855 }
20856 run_test 230f "migrate mulitple remote link files"
20857
20858 test_230g() {
20859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20862                 skip "Need MDS version at least 2.11.52"
20863
20864         mkdir -p $DIR/$tdir/migrate_dir
20865
20866         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20867                 error "migrating dir to non-exist MDT succeeds"
20868         true
20869 }
20870 run_test 230g "migrate dir to non-exist MDT"
20871
20872 test_230h() {
20873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20874         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20875         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20876                 skip "Need MDS version at least 2.11.52"
20877
20878         local mdt_index
20879
20880         mkdir -p $DIR/$tdir/migrate_dir
20881
20882         $LFS migrate -m1 $DIR &&
20883                 error "migrating mountpoint1 should fail"
20884
20885         $LFS migrate -m1 $DIR/$tdir/.. &&
20886                 error "migrating mountpoint2 should fail"
20887
20888         # same as mv
20889         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20890                 error "migrating $tdir/migrate_dir/.. should fail"
20891
20892         true
20893 }
20894 run_test 230h "migrate .. and root"
20895
20896 test_230i() {
20897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20899         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20900                 skip "Need MDS version at least 2.11.52"
20901
20902         mkdir -p $DIR/$tdir/migrate_dir
20903
20904         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20905                 error "migration fails with a tailing slash"
20906
20907         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20908                 error "migration fails with two tailing slashes"
20909 }
20910 run_test 230i "lfs migrate -m tolerates trailing slashes"
20911
20912 test_230j() {
20913         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20914         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20915                 skip "Need MDS version at least 2.11.52"
20916
20917         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20918         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20919                 error "create $tfile failed"
20920         cat /etc/passwd > $DIR/$tdir/$tfile
20921
20922         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20923
20924         cmp /etc/passwd $DIR/$tdir/$tfile ||
20925                 error "DoM file mismatch after migration"
20926 }
20927 run_test 230j "DoM file data not changed after dir migration"
20928
20929 test_230k() {
20930         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20931         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20932                 skip "Need MDS version at least 2.11.56"
20933
20934         local total=20
20935         local files_on_starting_mdt=0
20936
20937         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20938         $LFS getdirstripe $DIR/$tdir
20939         for i in $(seq $total); do
20940                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20941                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20942                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20943         done
20944
20945         echo "$files_on_starting_mdt files on MDT0"
20946
20947         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20948         $LFS getdirstripe $DIR/$tdir
20949
20950         files_on_starting_mdt=0
20951         for i in $(seq $total); do
20952                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20953                         error "file $tfile.$i mismatch after migration"
20954                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20955                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20956         done
20957
20958         echo "$files_on_starting_mdt files on MDT1 after migration"
20959         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20960
20961         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20962         $LFS getdirstripe $DIR/$tdir
20963
20964         files_on_starting_mdt=0
20965         for i in $(seq $total); do
20966                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20967                         error "file $tfile.$i mismatch after 2nd migration"
20968                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20969                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20970         done
20971
20972         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20973         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20974
20975         true
20976 }
20977 run_test 230k "file data not changed after dir migration"
20978
20979 test_230l() {
20980         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20981         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20982                 skip "Need MDS version at least 2.11.56"
20983
20984         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20985         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20986                 error "create files under remote dir failed $i"
20987         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20988 }
20989 run_test 230l "readdir between MDTs won't crash"
20990
20991 test_230m() {
20992         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20993         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20994                 skip "Need MDS version at least 2.11.56"
20995
20996         local MDTIDX=1
20997         local mig_dir=$DIR/$tdir/migrate_dir
20998         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20999         local shortstr="b"
21000         local val
21001
21002         echo "Creating files and dirs with xattrs"
21003         test_mkdir $DIR/$tdir
21004         test_mkdir -i0 -c1 $mig_dir
21005         mkdir $mig_dir/dir
21006         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21007                 error "cannot set xattr attr1 on dir"
21008         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21009                 error "cannot set xattr attr2 on dir"
21010         touch $mig_dir/dir/f0
21011         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21012                 error "cannot set xattr attr1 on file"
21013         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21014                 error "cannot set xattr attr2 on file"
21015         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21016         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21017         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21018         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21019         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21020         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21021         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21022         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21023         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21024
21025         echo "Migrating to MDT1"
21026         $LFS migrate -m $MDTIDX $mig_dir ||
21027                 error "fails on migrating dir to MDT1"
21028
21029         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21030         echo "Checking xattrs"
21031         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21032         [ "$val" = $longstr ] ||
21033                 error "expecting xattr1 $longstr on dir, found $val"
21034         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21035         [ "$val" = $shortstr ] ||
21036                 error "expecting xattr2 $shortstr on dir, found $val"
21037         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21038         [ "$val" = $longstr ] ||
21039                 error "expecting xattr1 $longstr on file, found $val"
21040         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21041         [ "$val" = $shortstr ] ||
21042                 error "expecting xattr2 $shortstr on file, found $val"
21043 }
21044 run_test 230m "xattrs not changed after dir migration"
21045
21046 test_230n() {
21047         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21048         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21049                 skip "Need MDS version at least 2.13.53"
21050
21051         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21052         cat /etc/hosts > $DIR/$tdir/$tfile
21053         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21054         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21055
21056         cmp /etc/hosts $DIR/$tdir/$tfile ||
21057                 error "File data mismatch after migration"
21058 }
21059 run_test 230n "Dir migration with mirrored file"
21060
21061 test_230o() {
21062         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21063         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21064                 skip "Need MDS version at least 2.13.52"
21065
21066         local mdts=$(comma_list $(mdts_nodes))
21067         local timeout=100
21068         local restripe_status
21069         local delta
21070         local i
21071
21072         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21073
21074         # in case "crush" hash type is not set
21075         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21076
21077         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21078                            mdt.*MDT0000.enable_dir_restripe)
21079         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21080         stack_trap "do_nodes $mdts $LCTL set_param \
21081                     mdt.*.enable_dir_restripe=$restripe_status"
21082
21083         mkdir $DIR/$tdir
21084         createmany -m $DIR/$tdir/f 100 ||
21085                 error "create files under remote dir failed $i"
21086         createmany -d $DIR/$tdir/d 100 ||
21087                 error "create dirs under remote dir failed $i"
21088
21089         for i in $(seq 2 $MDSCOUNT); do
21090                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21091                 $LFS setdirstripe -c $i $DIR/$tdir ||
21092                         error "split -c $i $tdir failed"
21093                 wait_update $HOSTNAME \
21094                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21095                         error "dir split not finished"
21096                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21097                         awk '/migrate/ {sum += $2} END { print sum }')
21098                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21099                 # delta is around total_files/stripe_count
21100                 (( $delta < 200 / (i - 1) + 4 )) ||
21101                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21102         done
21103 }
21104 run_test 230o "dir split"
21105
21106 test_230p() {
21107         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21108         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21109                 skip "Need MDS version at least 2.13.52"
21110
21111         local mdts=$(comma_list $(mdts_nodes))
21112         local timeout=100
21113         local restripe_status
21114         local delta
21115         local c
21116
21117         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21118
21119         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21120
21121         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21122                            mdt.*MDT0000.enable_dir_restripe)
21123         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21124         stack_trap "do_nodes $mdts $LCTL set_param \
21125                     mdt.*.enable_dir_restripe=$restripe_status"
21126
21127         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21128         createmany -m $DIR/$tdir/f 100 ||
21129                 error "create files under remote dir failed"
21130         createmany -d $DIR/$tdir/d 100 ||
21131                 error "create dirs under remote dir failed"
21132
21133         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21134                 local mdt_hash="crush"
21135
21136                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21137                 $LFS setdirstripe -c $c $DIR/$tdir ||
21138                         error "split -c $c $tdir failed"
21139                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21140                         mdt_hash="$mdt_hash,fixed"
21141                 elif [ $c -eq 1 ]; then
21142                         mdt_hash="none"
21143                 fi
21144                 wait_update $HOSTNAME \
21145                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21146                         error "dir merge not finished"
21147                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21148                         awk '/migrate/ {sum += $2} END { print sum }')
21149                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21150                 # delta is around total_files/stripe_count
21151                 (( delta < 200 / c + 4 )) ||
21152                         error "$delta files migrated >= $((200 / c + 4))"
21153         done
21154 }
21155 run_test 230p "dir merge"
21156
21157 test_230q() {
21158         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21159         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21160                 skip "Need MDS version at least 2.13.52"
21161
21162         local mdts=$(comma_list $(mdts_nodes))
21163         local saved_threshold=$(do_facet mds1 \
21164                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21165         local saved_delta=$(do_facet mds1 \
21166                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21167         local threshold=100
21168         local delta=2
21169         local total=0
21170         local stripe_count=0
21171         local stripe_index
21172         local nr_files
21173         local create
21174
21175         # test with fewer files on ZFS
21176         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21177
21178         stack_trap "do_nodes $mdts $LCTL set_param \
21179                     mdt.*.dir_split_count=$saved_threshold"
21180         stack_trap "do_nodes $mdts $LCTL set_param \
21181                     mdt.*.dir_split_delta=$saved_delta"
21182         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21183         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21184         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21185         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21186         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21187         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21188
21189         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21190         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21191
21192         create=$((threshold * 3 / 2))
21193         while [ $stripe_count -lt $MDSCOUNT ]; do
21194                 createmany -m $DIR/$tdir/f $total $create ||
21195                         error "create sub files failed"
21196                 stat $DIR/$tdir > /dev/null
21197                 total=$((total + create))
21198                 stripe_count=$((stripe_count + delta))
21199                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21200
21201                 wait_update $HOSTNAME \
21202                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21203                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21204
21205                 wait_update $HOSTNAME \
21206                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21207                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21208
21209                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21210                 echo "$nr_files/$total files on MDT$stripe_index after split"
21211                 # allow 10% margin of imbalance with crush hash
21212                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21213                         error "$nr_files files on MDT$stripe_index after split"
21214
21215                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21216                 [ $nr_files -eq $total ] ||
21217                         error "total sub files $nr_files != $total"
21218         done
21219
21220         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21221
21222         echo "fixed layout directory won't auto split"
21223         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21224         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21225                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21226         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21227                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21228 }
21229 run_test 230q "dir auto split"
21230
21231 test_230r() {
21232         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21233         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21234         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21235                 skip "Need MDS version at least 2.13.54"
21236
21237         # maximum amount of local locks:
21238         # parent striped dir - 2 locks
21239         # new stripe in parent to migrate to - 1 lock
21240         # source and target - 2 locks
21241         # Total 5 locks for regular file
21242         mkdir -p $DIR/$tdir
21243         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21244         touch $DIR/$tdir/dir1/eee
21245
21246         # create 4 hardlink for 4 more locks
21247         # Total: 9 locks > RS_MAX_LOCKS (8)
21248         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21249         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21250         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21251         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21252         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21253         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21254         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21255         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21256
21257         cancel_lru_locks mdc
21258
21259         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21260                 error "migrate dir fails"
21261
21262         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21263 }
21264 run_test 230r "migrate with too many local locks"
21265
21266 test_230s() {
21267         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21268                 skip "Need MDS version at least 2.14.52"
21269
21270         local mdts=$(comma_list $(mdts_nodes))
21271         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21272                                 mdt.*MDT0000.enable_dir_restripe)
21273
21274         stack_trap "do_nodes $mdts $LCTL set_param \
21275                     mdt.*.enable_dir_restripe=$restripe_status"
21276
21277         local st
21278         for st in 0 1; do
21279                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21280                 test_mkdir $DIR/$tdir
21281                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21282                         error "$LFS mkdir should return EEXIST if target exists"
21283                 rmdir $DIR/$tdir
21284         done
21285 }
21286 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21287
21288 test_230t()
21289 {
21290         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21291         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21292                 skip "Need MDS version at least 2.14.50"
21293
21294         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21295         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21296         $LFS project -p 1 -s $DIR/$tdir ||
21297                 error "set $tdir project id failed"
21298         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21299                 error "set subdir project id failed"
21300         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21301 }
21302 run_test 230t "migrate directory with project ID set"
21303
21304 test_230u()
21305 {
21306         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21307         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21308                 skip "Need MDS version at least 2.14.53"
21309
21310         local count
21311
21312         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21313         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21314         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21315         for i in $(seq 0 $((MDSCOUNT - 1))); do
21316                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21317                 echo "$count dirs migrated to MDT$i"
21318         done
21319         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21320         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21321 }
21322 run_test 230u "migrate directory by QOS"
21323
21324 test_230v()
21325 {
21326         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21327         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21328                 skip "Need MDS version at least 2.14.53"
21329
21330         local count
21331
21332         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21333         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21334         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21335         for i in $(seq 0 $((MDSCOUNT - 1))); do
21336                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21337                 echo "$count subdirs migrated to MDT$i"
21338                 (( i == 3 )) && (( count > 0 )) &&
21339                         error "subdir shouldn't be migrated to MDT3"
21340         done
21341         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21342         (( count == 3 )) || error "dirs migrated to $count MDTs"
21343 }
21344 run_test 230v "subdir migrated to the MDT where its parent is located"
21345
21346 test_230w() {
21347         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21348         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21349                 skip "Need MDS version at least 2.15.0"
21350
21351         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21352         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21353         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21354
21355         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21356                 error "migrate failed"
21357
21358         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21359                 error "$tdir stripe count mismatch"
21360
21361         for i in $(seq 0 9); do
21362                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21363                         error "d$i is striped"
21364         done
21365 }
21366 run_test 230w "non-recursive mode dir migration"
21367
21368 test_230x() {
21369         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21370         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21371                 skip "Need MDS version at least 2.15.0"
21372
21373         mkdir -p $DIR/$tdir || error "mkdir failed"
21374         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21375
21376         local mdt_name=$(mdtname_from_index 0)
21377         local low=$(do_facet mds2 $LCTL get_param -n \
21378                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21379         local high=$(do_facet mds2 $LCTL get_param -n \
21380                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21381         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21382         local maxage=$(do_facet mds2 $LCTL get_param -n \
21383                 osp.*$mdt_name-osp-MDT0001.maxage)
21384
21385         stack_trap "do_facet mds2 $LCTL set_param -n \
21386                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21387                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21388         stack_trap "do_facet mds2 $LCTL set_param -n \
21389                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21390
21391         do_facet mds2 $LCTL set_param -n \
21392                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21393         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21394         sleep 4
21395         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21396                 error "migrate $tdir should fail"
21397
21398         do_facet mds2 $LCTL set_param -n \
21399                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21400         do_facet mds2 $LCTL set_param -n \
21401                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21402         sleep 4
21403         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21404                 error "migrate failed"
21405         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21406                 error "$tdir stripe count mismatch"
21407 }
21408 run_test 230x "dir migration check space"
21409
21410 test_231a()
21411 {
21412         # For simplicity this test assumes that max_pages_per_rpc
21413         # is the same across all OSCs
21414         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21415         local bulk_size=$((max_pages * PAGE_SIZE))
21416         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21417                                        head -n 1)
21418
21419         mkdir -p $DIR/$tdir
21420         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21421                 error "failed to set stripe with -S ${brw_size}M option"
21422
21423         # clear the OSC stats
21424         $LCTL set_param osc.*.stats=0 &>/dev/null
21425         stop_writeback
21426
21427         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21428         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21429                 oflag=direct &>/dev/null || error "dd failed"
21430
21431         sync; sleep 1; sync # just to be safe
21432         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21433         if [ x$nrpcs != "x1" ]; then
21434                 $LCTL get_param osc.*.stats
21435                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21436         fi
21437
21438         start_writeback
21439         # Drop the OSC cache, otherwise we will read from it
21440         cancel_lru_locks osc
21441
21442         # clear the OSC stats
21443         $LCTL set_param osc.*.stats=0 &>/dev/null
21444
21445         # Client reads $bulk_size.
21446         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21447                 iflag=direct &>/dev/null || error "dd failed"
21448
21449         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21450         if [ x$nrpcs != "x1" ]; then
21451                 $LCTL get_param osc.*.stats
21452                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21453         fi
21454 }
21455 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21456
21457 test_231b() {
21458         mkdir -p $DIR/$tdir
21459         local i
21460         for i in {0..1023}; do
21461                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21462                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21463                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21464         done
21465         sync
21466 }
21467 run_test 231b "must not assert on fully utilized OST request buffer"
21468
21469 test_232a() {
21470         mkdir -p $DIR/$tdir
21471         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21472
21473         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21474         do_facet ost1 $LCTL set_param fail_loc=0x31c
21475
21476         # ignore dd failure
21477         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21478
21479         do_facet ost1 $LCTL set_param fail_loc=0
21480         umount_client $MOUNT || error "umount failed"
21481         mount_client $MOUNT || error "mount failed"
21482         stop ost1 || error "cannot stop ost1"
21483         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21484 }
21485 run_test 232a "failed lock should not block umount"
21486
21487 test_232b() {
21488         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21489                 skip "Need MDS version at least 2.10.58"
21490
21491         mkdir -p $DIR/$tdir
21492         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21493         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21494         sync
21495         cancel_lru_locks osc
21496
21497         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21498         do_facet ost1 $LCTL set_param fail_loc=0x31c
21499
21500         # ignore failure
21501         $LFS data_version $DIR/$tdir/$tfile || true
21502
21503         do_facet ost1 $LCTL set_param fail_loc=0
21504         umount_client $MOUNT || error "umount failed"
21505         mount_client $MOUNT || error "mount failed"
21506         stop ost1 || error "cannot stop ost1"
21507         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21508 }
21509 run_test 232b "failed data version lock should not block umount"
21510
21511 test_233a() {
21512         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21513                 skip "Need MDS version at least 2.3.64"
21514         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21515
21516         local fid=$($LFS path2fid $MOUNT)
21517
21518         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21519                 error "cannot access $MOUNT using its FID '$fid'"
21520 }
21521 run_test 233a "checking that OBF of the FS root succeeds"
21522
21523 test_233b() {
21524         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21525                 skip "Need MDS version at least 2.5.90"
21526         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21527
21528         local fid=$($LFS path2fid $MOUNT/.lustre)
21529
21530         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21531                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21532
21533         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21534         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21535                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21536 }
21537 run_test 233b "checking that OBF of the FS .lustre succeeds"
21538
21539 test_234() {
21540         local p="$TMP/sanityN-$TESTNAME.parameters"
21541         save_lustre_params client "llite.*.xattr_cache" > $p
21542         lctl set_param llite.*.xattr_cache 1 ||
21543                 skip_env "xattr cache is not supported"
21544
21545         mkdir -p $DIR/$tdir || error "mkdir failed"
21546         touch $DIR/$tdir/$tfile || error "touch failed"
21547         # OBD_FAIL_LLITE_XATTR_ENOMEM
21548         $LCTL set_param fail_loc=0x1405
21549         getfattr -n user.attr $DIR/$tdir/$tfile &&
21550                 error "getfattr should have failed with ENOMEM"
21551         $LCTL set_param fail_loc=0x0
21552         rm -rf $DIR/$tdir
21553
21554         restore_lustre_params < $p
21555         rm -f $p
21556 }
21557 run_test 234 "xattr cache should not crash on ENOMEM"
21558
21559 test_235() {
21560         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21561                 skip "Need MDS version at least 2.4.52"
21562
21563         flock_deadlock $DIR/$tfile
21564         local RC=$?
21565         case $RC in
21566                 0)
21567                 ;;
21568                 124) error "process hangs on a deadlock"
21569                 ;;
21570                 *) error "error executing flock_deadlock $DIR/$tfile"
21571                 ;;
21572         esac
21573 }
21574 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21575
21576 #LU-2935
21577 test_236() {
21578         check_swap_layouts_support
21579
21580         local ref1=/etc/passwd
21581         local ref2=/etc/group
21582         local file1=$DIR/$tdir/f1
21583         local file2=$DIR/$tdir/f2
21584
21585         test_mkdir -c1 $DIR/$tdir
21586         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21587         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21588         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21589         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21590         local fd=$(free_fd)
21591         local cmd="exec $fd<>$file2"
21592         eval $cmd
21593         rm $file2
21594         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21595                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21596         cmd="exec $fd>&-"
21597         eval $cmd
21598         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21599
21600         #cleanup
21601         rm -rf $DIR/$tdir
21602 }
21603 run_test 236 "Layout swap on open unlinked file"
21604
21605 # LU-4659 linkea consistency
21606 test_238() {
21607         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21608                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21609                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21610                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21611
21612         touch $DIR/$tfile
21613         ln $DIR/$tfile $DIR/$tfile.lnk
21614         touch $DIR/$tfile.new
21615         mv $DIR/$tfile.new $DIR/$tfile
21616         local fid1=$($LFS path2fid $DIR/$tfile)
21617         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21618         local path1=$($LFS fid2path $FSNAME "$fid1")
21619         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21620         local path2=$($LFS fid2path $FSNAME "$fid2")
21621         [ $tfile.lnk == $path2 ] ||
21622                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21623         rm -f $DIR/$tfile*
21624 }
21625 run_test 238 "Verify linkea consistency"
21626
21627 test_239A() { # was test_239
21628         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21629                 skip "Need MDS version at least 2.5.60"
21630
21631         local list=$(comma_list $(mdts_nodes))
21632
21633         mkdir -p $DIR/$tdir
21634         createmany -o $DIR/$tdir/f- 5000
21635         unlinkmany $DIR/$tdir/f- 5000
21636         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21637                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21638         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21639                         osp.*MDT*.sync_in_flight" | calc_sum)
21640         [ "$changes" -eq 0 ] || error "$changes not synced"
21641 }
21642 run_test 239A "osp_sync test"
21643
21644 test_239a() { #LU-5297
21645         remote_mds_nodsh && skip "remote MDS with nodsh"
21646
21647         touch $DIR/$tfile
21648         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21649         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21650         chgrp $RUNAS_GID $DIR/$tfile
21651         wait_delete_completed
21652 }
21653 run_test 239a "process invalid osp sync record correctly"
21654
21655 test_239b() { #LU-5297
21656         remote_mds_nodsh && skip "remote MDS with nodsh"
21657
21658         touch $DIR/$tfile1
21659         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21660         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21661         chgrp $RUNAS_GID $DIR/$tfile1
21662         wait_delete_completed
21663         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21664         touch $DIR/$tfile2
21665         chgrp $RUNAS_GID $DIR/$tfile2
21666         wait_delete_completed
21667 }
21668 run_test 239b "process osp sync record with ENOMEM error correctly"
21669
21670 test_240() {
21671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21672         remote_mds_nodsh && skip "remote MDS with nodsh"
21673
21674         mkdir -p $DIR/$tdir
21675
21676         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21677                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21678         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21679                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21680
21681         umount_client $MOUNT || error "umount failed"
21682         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21683         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21684         mount_client $MOUNT || error "failed to mount client"
21685
21686         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21687         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21688 }
21689 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21690
21691 test_241_bio() {
21692         local count=$1
21693         local bsize=$2
21694
21695         for LOOP in $(seq $count); do
21696                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21697                 cancel_lru_locks $OSC || true
21698         done
21699 }
21700
21701 test_241_dio() {
21702         local count=$1
21703         local bsize=$2
21704
21705         for LOOP in $(seq $1); do
21706                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21707                         2>/dev/null
21708         done
21709 }
21710
21711 test_241a() { # was test_241
21712         local bsize=$PAGE_SIZE
21713
21714         (( bsize < 40960 )) && bsize=40960
21715         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21716         ls -la $DIR/$tfile
21717         cancel_lru_locks $OSC
21718         test_241_bio 1000 $bsize &
21719         PID=$!
21720         test_241_dio 1000 $bsize
21721         wait $PID
21722 }
21723 run_test 241a "bio vs dio"
21724
21725 test_241b() {
21726         local bsize=$PAGE_SIZE
21727
21728         (( bsize < 40960 )) && bsize=40960
21729         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21730         ls -la $DIR/$tfile
21731         test_241_dio 1000 $bsize &
21732         PID=$!
21733         test_241_dio 1000 $bsize
21734         wait $PID
21735 }
21736 run_test 241b "dio vs dio"
21737
21738 test_242() {
21739         remote_mds_nodsh && skip "remote MDS with nodsh"
21740
21741         mkdir_on_mdt0 $DIR/$tdir
21742         touch $DIR/$tdir/$tfile
21743
21744         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21745         do_facet mds1 lctl set_param fail_loc=0x105
21746         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21747
21748         do_facet mds1 lctl set_param fail_loc=0
21749         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21750 }
21751 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21752
21753 test_243()
21754 {
21755         test_mkdir $DIR/$tdir
21756         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21757 }
21758 run_test 243 "various group lock tests"
21759
21760 test_244a()
21761 {
21762         test_mkdir $DIR/$tdir
21763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21764         sendfile_grouplock $DIR/$tdir/$tfile || \
21765                 error "sendfile+grouplock failed"
21766         rm -rf $DIR/$tdir
21767 }
21768 run_test 244a "sendfile with group lock tests"
21769
21770 test_244b()
21771 {
21772         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21773
21774         local threads=50
21775         local size=$((1024*1024))
21776
21777         test_mkdir $DIR/$tdir
21778         for i in $(seq 1 $threads); do
21779                 local file=$DIR/$tdir/file_$((i / 10))
21780                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21781                 local pids[$i]=$!
21782         done
21783         for i in $(seq 1 $threads); do
21784                 wait ${pids[$i]}
21785         done
21786 }
21787 run_test 244b "multi-threaded write with group lock"
21788
21789 test_245a() {
21790         local flagname="multi_mod_rpcs"
21791         local connect_data_name="max_mod_rpcs"
21792         local out
21793
21794         # check if multiple modify RPCs flag is set
21795         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21796                 grep "connect_flags:")
21797         echo "$out"
21798
21799         echo "$out" | grep -qw $flagname
21800         if [ $? -ne 0 ]; then
21801                 echo "connect flag $flagname is not set"
21802                 return
21803         fi
21804
21805         # check if multiple modify RPCs data is set
21806         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21807         echo "$out"
21808
21809         echo "$out" | grep -qw $connect_data_name ||
21810                 error "import should have connect data $connect_data_name"
21811 }
21812 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21813
21814 test_245b() {
21815         local flagname="multi_mod_rpcs"
21816         local connect_data_name="max_mod_rpcs"
21817         local out
21818
21819         remote_mds_nodsh && skip "remote MDS with nodsh"
21820         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21821
21822         # check if multiple modify RPCs flag is set
21823         out=$(do_facet mds1 \
21824               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21825               grep "connect_flags:")
21826         echo "$out"
21827
21828         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21829
21830         # check if multiple modify RPCs data is set
21831         out=$(do_facet mds1 \
21832               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21833
21834         [[ "$out" =~ $connect_data_name ]] ||
21835                 {
21836                         echo "$out"
21837                         error "missing connect data $connect_data_name"
21838                 }
21839 }
21840 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21841
21842 cleanup_247() {
21843         local submount=$1
21844
21845         trap 0
21846         umount_client $submount
21847         rmdir $submount
21848 }
21849
21850 test_247a() {
21851         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21852                 grep -q subtree ||
21853                 skip_env "Fileset feature is not supported"
21854
21855         local submount=${MOUNT}_$tdir
21856
21857         mkdir $MOUNT/$tdir
21858         mkdir -p $submount || error "mkdir $submount failed"
21859         FILESET="$FILESET/$tdir" mount_client $submount ||
21860                 error "mount $submount failed"
21861         trap "cleanup_247 $submount" EXIT
21862         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21863         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21864                 error "read $MOUNT/$tdir/$tfile failed"
21865         cleanup_247 $submount
21866 }
21867 run_test 247a "mount subdir as fileset"
21868
21869 test_247b() {
21870         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21871                 skip_env "Fileset feature is not supported"
21872
21873         local submount=${MOUNT}_$tdir
21874
21875         rm -rf $MOUNT/$tdir
21876         mkdir -p $submount || error "mkdir $submount failed"
21877         SKIP_FILESET=1
21878         FILESET="$FILESET/$tdir" mount_client $submount &&
21879                 error "mount $submount should fail"
21880         rmdir $submount
21881 }
21882 run_test 247b "mount subdir that dose not exist"
21883
21884 test_247c() {
21885         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21886                 skip_env "Fileset feature is not supported"
21887
21888         local submount=${MOUNT}_$tdir
21889
21890         mkdir -p $MOUNT/$tdir/dir1
21891         mkdir -p $submount || error "mkdir $submount failed"
21892         trap "cleanup_247 $submount" EXIT
21893         FILESET="$FILESET/$tdir" mount_client $submount ||
21894                 error "mount $submount failed"
21895         local fid=$($LFS path2fid $MOUNT/)
21896         $LFS fid2path $submount $fid && error "fid2path should fail"
21897         cleanup_247 $submount
21898 }
21899 run_test 247c "running fid2path outside subdirectory root"
21900
21901 test_247d() {
21902         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21903                 skip "Fileset feature is not supported"
21904
21905         local submount=${MOUNT}_$tdir
21906
21907         mkdir -p $MOUNT/$tdir/dir1
21908         mkdir -p $submount || error "mkdir $submount failed"
21909         FILESET="$FILESET/$tdir" mount_client $submount ||
21910                 error "mount $submount failed"
21911         trap "cleanup_247 $submount" EXIT
21912
21913         local td=$submount/dir1
21914         local fid=$($LFS path2fid $td)
21915         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21916
21917         # check that we get the same pathname back
21918         local rootpath
21919         local found
21920         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21921                 echo "$rootpath $fid"
21922                 found=$($LFS fid2path $rootpath "$fid")
21923                 [ -n "$found" ] || error "fid2path should succeed"
21924                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21925         done
21926         # check wrong root path format
21927         rootpath=$submount"_wrong"
21928         found=$($LFS fid2path $rootpath "$fid")
21929         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21930
21931         cleanup_247 $submount
21932 }
21933 run_test 247d "running fid2path inside subdirectory root"
21934
21935 # LU-8037
21936 test_247e() {
21937         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21938                 grep -q subtree ||
21939                 skip "Fileset feature is not supported"
21940
21941         local submount=${MOUNT}_$tdir
21942
21943         mkdir $MOUNT/$tdir
21944         mkdir -p $submount || error "mkdir $submount failed"
21945         FILESET="$FILESET/.." mount_client $submount &&
21946                 error "mount $submount should fail"
21947         rmdir $submount
21948 }
21949 run_test 247e "mount .. as fileset"
21950
21951 test_247f() {
21952         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21953         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21954                 skip "Need at least version 2.14.50.162"
21955         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21956                 skip "Fileset feature is not supported"
21957
21958         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21959         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21960                 error "mkdir remote failed"
21961         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21962                 error "mkdir remote/subdir failed"
21963         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21964                 error "mkdir striped failed"
21965         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21966
21967         local submount=${MOUNT}_$tdir
21968
21969         mkdir -p $submount || error "mkdir $submount failed"
21970         stack_trap "rmdir $submount"
21971
21972         local dir
21973         local fileset=$FILESET
21974         local mdts=$(comma_list $(mdts_nodes))
21975
21976         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21977         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
21978                 $tdir/striped/subdir $tdir/striped/.; do
21979                 FILESET="$fileset/$dir" mount_client $submount ||
21980                         error "mount $dir failed"
21981                 umount_client $submount
21982         done
21983 }
21984 run_test 247f "mount striped or remote directory as fileset"
21985
21986 test_subdir_mount_lock()
21987 {
21988         local testdir=$1
21989         local submount=${MOUNT}_$(basename $testdir)
21990
21991         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
21992
21993         mkdir -p $submount || error "mkdir $submount failed"
21994         stack_trap "rmdir $submount"
21995
21996         FILESET="$fileset/$testdir" mount_client $submount ||
21997                 error "mount $FILESET failed"
21998         stack_trap "umount $submount"
21999
22000         local mdts=$(comma_list $(mdts_nodes))
22001
22002         local nrpcs
22003
22004         stat $submount > /dev/null || error "stat $submount failed"
22005         cancel_lru_locks $MDC
22006         stat $submount > /dev/null || error "stat $submount failed"
22007         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22008         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22009         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22010         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22011                 awk '/getattr/ {sum += $2} END {print sum}')
22012
22013         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22014 }
22015
22016 test_247g() {
22017         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22018
22019         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22020                 error "mkdir $tdir failed"
22021         test_subdir_mount_lock $tdir
22022 }
22023 run_test 247g "striped directory submount revalidate ROOT from cache"
22024
22025 test_247h() {
22026         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22027         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22028                 skip "Need MDS version at least 2.15.51"
22029
22030         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22031         test_subdir_mount_lock $tdir
22032         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22033         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22034                 error "mkdir $tdir.1 failed"
22035         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22036 }
22037 run_test 247h "remote directory submount revalidate ROOT from cache"
22038
22039 test_248a() {
22040         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22041         [ -z "$fast_read_sav" ] && skip "no fast read support"
22042
22043         # create a large file for fast read verification
22044         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22045
22046         # make sure the file is created correctly
22047         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22048                 { rm -f $DIR/$tfile; skip "file creation error"; }
22049
22050         echo "Test 1: verify that fast read is 4 times faster on cache read"
22051
22052         # small read with fast read enabled
22053         $LCTL set_param -n llite.*.fast_read=1
22054         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22055                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22056                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22057         # small read with fast read disabled
22058         $LCTL set_param -n llite.*.fast_read=0
22059         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22060                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22061                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22062
22063         # verify that fast read is 4 times faster for cache read
22064         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22065                 error_not_in_vm "fast read was not 4 times faster: " \
22066                            "$t_fast vs $t_slow"
22067
22068         echo "Test 2: verify the performance between big and small read"
22069         $LCTL set_param -n llite.*.fast_read=1
22070
22071         # 1k non-cache read
22072         cancel_lru_locks osc
22073         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22074                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22075                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22076
22077         # 1M non-cache read
22078         cancel_lru_locks osc
22079         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22080                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22081                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22082
22083         # verify that big IO is not 4 times faster than small IO
22084         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22085                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22086
22087         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22088         rm -f $DIR/$tfile
22089 }
22090 run_test 248a "fast read verification"
22091
22092 test_248b() {
22093         # Default short_io_bytes=16384, try both smaller and larger sizes.
22094         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22095         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22096         echo "bs=53248 count=113 normal buffered write"
22097         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22098                 error "dd of initial data file failed"
22099         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22100
22101         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22102         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22103                 error "dd with sync normal writes failed"
22104         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22105
22106         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22107         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22108                 error "dd with sync small writes failed"
22109         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22110
22111         cancel_lru_locks osc
22112
22113         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22114         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22115         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22116         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22117                 iflag=direct || error "dd with O_DIRECT small read failed"
22118         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22119         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22120                 error "compare $TMP/$tfile.1 failed"
22121
22122         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22123         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22124
22125         # just to see what the maximum tunable value is, and test parsing
22126         echo "test invalid parameter 2MB"
22127         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22128                 error "too-large short_io_bytes allowed"
22129         echo "test maximum parameter 512KB"
22130         # if we can set a larger short_io_bytes, run test regardless of version
22131         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22132                 # older clients may not allow setting it this large, that's OK
22133                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22134                         skip "Need at least client version 2.13.50"
22135                 error "medium short_io_bytes failed"
22136         fi
22137         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22138         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22139
22140         echo "test large parameter 64KB"
22141         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22142         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22143
22144         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22145         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22146                 error "dd with sync large writes failed"
22147         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22148
22149         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22150         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22151         num=$((113 * 4096 / PAGE_SIZE))
22152         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22153         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22154                 error "dd with O_DIRECT large writes failed"
22155         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22156                 error "compare $DIR/$tfile.3 failed"
22157
22158         cancel_lru_locks osc
22159
22160         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22161         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22162                 error "dd with O_DIRECT large read failed"
22163         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22164                 error "compare $TMP/$tfile.2 failed"
22165
22166         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22167         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22168                 error "dd with O_DIRECT large read failed"
22169         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22170                 error "compare $TMP/$tfile.3 failed"
22171 }
22172 run_test 248b "test short_io read and write for both small and large sizes"
22173
22174 test_249() { # LU-7890
22175         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22176                 skip "Need at least version 2.8.54"
22177
22178         rm -f $DIR/$tfile
22179         $LFS setstripe -c 1 $DIR/$tfile
22180         # Offset 2T == 4k * 512M
22181         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22182                 error "dd to 2T offset failed"
22183 }
22184 run_test 249 "Write above 2T file size"
22185
22186 test_250() {
22187         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22188          && skip "no 16TB file size limit on ZFS"
22189
22190         $LFS setstripe -c 1 $DIR/$tfile
22191         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22192         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22193         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22194         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22195                 conv=notrunc,fsync && error "append succeeded"
22196         return 0
22197 }
22198 run_test 250 "Write above 16T limit"
22199
22200 test_251() {
22201         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22202
22203         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22204         #Skip once - writing the first stripe will succeed
22205         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22206         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22207                 error "short write happened"
22208
22209         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22210         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22211                 error "short read happened"
22212
22213         rm -f $DIR/$tfile
22214 }
22215 run_test 251 "Handling short read and write correctly"
22216
22217 test_252() {
22218         remote_mds_nodsh && skip "remote MDS with nodsh"
22219         remote_ost_nodsh && skip "remote OST with nodsh"
22220         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22221                 skip_env "ldiskfs only test"
22222         fi
22223
22224         local tgt
22225         local dev
22226         local out
22227         local uuid
22228         local num
22229         local gen
22230
22231         # check lr_reader on OST0000
22232         tgt=ost1
22233         dev=$(facet_device $tgt)
22234         out=$(do_facet $tgt $LR_READER $dev)
22235         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22236         echo "$out"
22237         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22238         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22239                 error "Invalid uuid returned by $LR_READER on target $tgt"
22240         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22241
22242         # check lr_reader -c on MDT0000
22243         tgt=mds1
22244         dev=$(facet_device $tgt)
22245         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22246                 skip "$LR_READER does not support additional options"
22247         fi
22248         out=$(do_facet $tgt $LR_READER -c $dev)
22249         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22250         echo "$out"
22251         num=$(echo "$out" | grep -c "mdtlov")
22252         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22253                 error "Invalid number of mdtlov clients returned by $LR_READER"
22254         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22255
22256         # check lr_reader -cr on MDT0000
22257         out=$(do_facet $tgt $LR_READER -cr $dev)
22258         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22259         echo "$out"
22260         echo "$out" | grep -q "^reply_data:$" ||
22261                 error "$LR_READER should have returned 'reply_data' section"
22262         num=$(echo "$out" | grep -c "client_generation")
22263         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22264 }
22265 run_test 252 "check lr_reader tool"
22266
22267 test_253() {
22268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22269         remote_mds_nodsh && skip "remote MDS with nodsh"
22270         remote_mgs_nodsh && skip "remote MGS with nodsh"
22271
22272         local ostidx=0
22273         local rc=0
22274         local ost_name=$(ostname_from_index $ostidx)
22275
22276         # on the mdt's osc
22277         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22278         do_facet $SINGLEMDS $LCTL get_param -n \
22279                 osp.$mdtosc_proc1.reserved_mb_high ||
22280                 skip  "remote MDS does not support reserved_mb_high"
22281
22282         rm -rf $DIR/$tdir
22283         wait_mds_ost_sync
22284         wait_delete_completed
22285         mkdir $DIR/$tdir
22286
22287         pool_add $TESTNAME || error "Pool creation failed"
22288         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22289
22290         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22291                 error "Setstripe failed"
22292
22293         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22294
22295         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22296                     grep "watermarks")
22297         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22298
22299         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22300                         osp.$mdtosc_proc1.prealloc_status)
22301         echo "prealloc_status $oa_status"
22302
22303         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22304                 error "File creation should fail"
22305
22306         #object allocation was stopped, but we still able to append files
22307         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22308                 oflag=append || error "Append failed"
22309
22310         rm -f $DIR/$tdir/$tfile.0
22311
22312         # For this test, we want to delete the files we created to go out of
22313         # space but leave the watermark, so we remain nearly out of space
22314         ost_watermarks_enospc_delete_files $tfile $ostidx
22315
22316         wait_delete_completed
22317
22318         sleep_maxage
22319
22320         for i in $(seq 10 12); do
22321                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22322                         2>/dev/null || error "File creation failed after rm"
22323         done
22324
22325         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22326                         osp.$mdtosc_proc1.prealloc_status)
22327         echo "prealloc_status $oa_status"
22328
22329         if (( oa_status != 0 )); then
22330                 error "Object allocation still disable after rm"
22331         fi
22332 }
22333 run_test 253 "Check object allocation limit"
22334
22335 test_254() {
22336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22337         remote_mds_nodsh && skip "remote MDS with nodsh"
22338
22339         local mdt=$(facet_svc $SINGLEMDS)
22340
22341         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22342                 skip "MDS does not support changelog_size"
22343
22344         local cl_user
22345
22346         changelog_register || error "changelog_register failed"
22347
22348         changelog_clear 0 || error "changelog_clear failed"
22349
22350         local size1=$(do_facet $SINGLEMDS \
22351                       $LCTL get_param -n mdd.$mdt.changelog_size)
22352         echo "Changelog size $size1"
22353
22354         rm -rf $DIR/$tdir
22355         $LFS mkdir -i 0 $DIR/$tdir
22356         # change something
22357         mkdir -p $DIR/$tdir/pics/2008/zachy
22358         touch $DIR/$tdir/pics/2008/zachy/timestamp
22359         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22360         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22361         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22362         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22363         rm $DIR/$tdir/pics/desktop.jpg
22364
22365         local size2=$(do_facet $SINGLEMDS \
22366                       $LCTL get_param -n mdd.$mdt.changelog_size)
22367         echo "Changelog size after work $size2"
22368
22369         (( $size2 > $size1 )) ||
22370                 error "new Changelog size=$size2 less than old size=$size1"
22371 }
22372 run_test 254 "Check changelog size"
22373
22374 ladvise_no_type()
22375 {
22376         local type=$1
22377         local file=$2
22378
22379         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22380                 awk -F: '{print $2}' | grep $type > /dev/null
22381         if [ $? -ne 0 ]; then
22382                 return 0
22383         fi
22384         return 1
22385 }
22386
22387 ladvise_no_ioctl()
22388 {
22389         local file=$1
22390
22391         lfs ladvise -a willread $file > /dev/null 2>&1
22392         if [ $? -eq 0 ]; then
22393                 return 1
22394         fi
22395
22396         lfs ladvise -a willread $file 2>&1 |
22397                 grep "Inappropriate ioctl for device" > /dev/null
22398         if [ $? -eq 0 ]; then
22399                 return 0
22400         fi
22401         return 1
22402 }
22403
22404 percent() {
22405         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22406 }
22407
22408 # run a random read IO workload
22409 # usage: random_read_iops <filename> <filesize> <iosize>
22410 random_read_iops() {
22411         local file=$1
22412         local fsize=$2
22413         local iosize=${3:-4096}
22414
22415         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22416                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22417 }
22418
22419 drop_file_oss_cache() {
22420         local file="$1"
22421         local nodes="$2"
22422
22423         $LFS ladvise -a dontneed $file 2>/dev/null ||
22424                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22425 }
22426
22427 ladvise_willread_performance()
22428 {
22429         local repeat=10
22430         local average_origin=0
22431         local average_cache=0
22432         local average_ladvise=0
22433
22434         for ((i = 1; i <= $repeat; i++)); do
22435                 echo "Iter $i/$repeat: reading without willread hint"
22436                 cancel_lru_locks osc
22437                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22438                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22439                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22440                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22441
22442                 cancel_lru_locks osc
22443                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22444                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22445                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22446
22447                 cancel_lru_locks osc
22448                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22449                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22450                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22451                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22452                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22453         done
22454         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22455         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22456         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22457
22458         speedup_cache=$(percent $average_cache $average_origin)
22459         speedup_ladvise=$(percent $average_ladvise $average_origin)
22460
22461         echo "Average uncached read: $average_origin"
22462         echo "Average speedup with OSS cached read: " \
22463                 "$average_cache = +$speedup_cache%"
22464         echo "Average speedup with ladvise willread: " \
22465                 "$average_ladvise = +$speedup_ladvise%"
22466
22467         local lowest_speedup=20
22468         if (( ${average_cache%.*} < $lowest_speedup )); then
22469                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22470                      " got $average_cache%. Skipping ladvise willread check."
22471                 return 0
22472         fi
22473
22474         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22475         # it is still good to run until then to exercise 'ladvise willread'
22476         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22477                 [ "$ost1_FSTYPE" = "zfs" ] &&
22478                 echo "osd-zfs does not support dontneed or drop_caches" &&
22479                 return 0
22480
22481         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22482         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22483                 error_not_in_vm "Speedup with willread is less than " \
22484                         "$lowest_speedup%, got $average_ladvise%"
22485 }
22486
22487 test_255a() {
22488         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22489                 skip "lustre < 2.8.54 does not support ladvise "
22490         remote_ost_nodsh && skip "remote OST with nodsh"
22491
22492         stack_trap "rm -f $DIR/$tfile"
22493         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22494
22495         ladvise_no_type willread $DIR/$tfile &&
22496                 skip "willread ladvise is not supported"
22497
22498         ladvise_no_ioctl $DIR/$tfile &&
22499                 skip "ladvise ioctl is not supported"
22500
22501         local size_mb=100
22502         local size=$((size_mb * 1048576))
22503         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22504                 error "dd to $DIR/$tfile failed"
22505
22506         lfs ladvise -a willread $DIR/$tfile ||
22507                 error "Ladvise failed with no range argument"
22508
22509         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22510                 error "Ladvise failed with no -l or -e argument"
22511
22512         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22513                 error "Ladvise failed with only -e argument"
22514
22515         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22516                 error "Ladvise failed with only -l argument"
22517
22518         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22519                 error "End offset should not be smaller than start offset"
22520
22521         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22522                 error "End offset should not be equal to start offset"
22523
22524         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22525                 error "Ladvise failed with overflowing -s argument"
22526
22527         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22528                 error "Ladvise failed with overflowing -e argument"
22529
22530         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22531                 error "Ladvise failed with overflowing -l argument"
22532
22533         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22534                 error "Ladvise succeeded with conflicting -l and -e arguments"
22535
22536         echo "Synchronous ladvise should wait"
22537         local delay=4
22538 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22539         do_nodes $(comma_list $(osts_nodes)) \
22540                 $LCTL set_param fail_val=$delay fail_loc=0x237
22541
22542         local start_ts=$SECONDS
22543         lfs ladvise -a willread $DIR/$tfile ||
22544                 error "Ladvise failed with no range argument"
22545         local end_ts=$SECONDS
22546         local inteval_ts=$((end_ts - start_ts))
22547
22548         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22549                 error "Synchronous advice didn't wait reply"
22550         fi
22551
22552         echo "Asynchronous ladvise shouldn't wait"
22553         local start_ts=$SECONDS
22554         lfs ladvise -a willread -b $DIR/$tfile ||
22555                 error "Ladvise failed with no range argument"
22556         local end_ts=$SECONDS
22557         local inteval_ts=$((end_ts - start_ts))
22558
22559         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22560                 error "Asynchronous advice blocked"
22561         fi
22562
22563         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22564         ladvise_willread_performance
22565 }
22566 run_test 255a "check 'lfs ladvise -a willread'"
22567
22568 facet_meminfo() {
22569         local facet=$1
22570         local info=$2
22571
22572         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22573 }
22574
22575 test_255b() {
22576         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22577                 skip "lustre < 2.8.54 does not support ladvise "
22578         remote_ost_nodsh && skip "remote OST with nodsh"
22579
22580         stack_trap "rm -f $DIR/$tfile"
22581         lfs setstripe -c 1 -i 0 $DIR/$tfile
22582
22583         ladvise_no_type dontneed $DIR/$tfile &&
22584                 skip "dontneed ladvise is not supported"
22585
22586         ladvise_no_ioctl $DIR/$tfile &&
22587                 skip "ladvise ioctl is not supported"
22588
22589         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22590                 [ "$ost1_FSTYPE" = "zfs" ] &&
22591                 skip "zfs-osd does not support 'ladvise dontneed'"
22592
22593         local size_mb=100
22594         local size=$((size_mb * 1048576))
22595         # In order to prevent disturbance of other processes, only check 3/4
22596         # of the memory usage
22597         local kibibytes=$((size_mb * 1024 * 3 / 4))
22598
22599         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22600                 error "dd to $DIR/$tfile failed"
22601
22602         #force write to complete before dropping OST cache & checking memory
22603         sync
22604
22605         local total=$(facet_meminfo ost1 MemTotal)
22606         echo "Total memory: $total KiB"
22607
22608         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22609         local before_read=$(facet_meminfo ost1 Cached)
22610         echo "Cache used before read: $before_read KiB"
22611
22612         lfs ladvise -a willread $DIR/$tfile ||
22613                 error "Ladvise willread failed"
22614         local after_read=$(facet_meminfo ost1 Cached)
22615         echo "Cache used after read: $after_read KiB"
22616
22617         lfs ladvise -a dontneed $DIR/$tfile ||
22618                 error "Ladvise dontneed again failed"
22619         local no_read=$(facet_meminfo ost1 Cached)
22620         echo "Cache used after dontneed ladvise: $no_read KiB"
22621
22622         if [ $total -lt $((before_read + kibibytes)) ]; then
22623                 echo "Memory is too small, abort checking"
22624                 return 0
22625         fi
22626
22627         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22628                 error "Ladvise willread should use more memory" \
22629                         "than $kibibytes KiB"
22630         fi
22631
22632         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22633                 error "Ladvise dontneed should release more memory" \
22634                         "than $kibibytes KiB"
22635         fi
22636 }
22637 run_test 255b "check 'lfs ladvise -a dontneed'"
22638
22639 test_255c() {
22640         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22641                 skip "lustre < 2.10.50 does not support lockahead"
22642
22643         local ost1_imp=$(get_osc_import_name client ost1)
22644         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22645                          cut -d'.' -f2)
22646         local count
22647         local new_count
22648         local difference
22649         local i
22650         local rc
22651
22652         test_mkdir -p $DIR/$tdir
22653         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22654
22655         #test 10 returns only success/failure
22656         i=10
22657         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22658         rc=$?
22659         if [ $rc -eq 255 ]; then
22660                 error "Ladvise test${i} failed, ${rc}"
22661         fi
22662
22663         #test 11 counts lock enqueue requests, all others count new locks
22664         i=11
22665         count=$(do_facet ost1 \
22666                 $LCTL get_param -n ost.OSS.ost.stats)
22667         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22668
22669         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22670         rc=$?
22671         if [ $rc -eq 255 ]; then
22672                 error "Ladvise test${i} failed, ${rc}"
22673         fi
22674
22675         new_count=$(do_facet ost1 \
22676                 $LCTL get_param -n ost.OSS.ost.stats)
22677         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22678                    awk '{ print $2 }')
22679
22680         difference="$((new_count - count))"
22681         if [ $difference -ne $rc ]; then
22682                 error "Ladvise test${i}, bad enqueue count, returned " \
22683                       "${rc}, actual ${difference}"
22684         fi
22685
22686         for i in $(seq 12 21); do
22687                 # If we do not do this, we run the risk of having too many
22688                 # locks and starting lock cancellation while we are checking
22689                 # lock counts.
22690                 cancel_lru_locks osc
22691
22692                 count=$($LCTL get_param -n \
22693                        ldlm.namespaces.$imp_name.lock_unused_count)
22694
22695                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22696                 rc=$?
22697                 if [ $rc -eq 255 ]; then
22698                         error "Ladvise test ${i} failed, ${rc}"
22699                 fi
22700
22701                 new_count=$($LCTL get_param -n \
22702                        ldlm.namespaces.$imp_name.lock_unused_count)
22703                 difference="$((new_count - count))"
22704
22705                 # Test 15 output is divided by 100 to map down to valid return
22706                 if [ $i -eq 15 ]; then
22707                         rc="$((rc * 100))"
22708                 fi
22709
22710                 if [ $difference -ne $rc ]; then
22711                         error "Ladvise test ${i}, bad lock count, returned " \
22712                               "${rc}, actual ${difference}"
22713                 fi
22714         done
22715
22716         #test 22 returns only success/failure
22717         i=22
22718         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22719         rc=$?
22720         if [ $rc -eq 255 ]; then
22721                 error "Ladvise test${i} failed, ${rc}"
22722         fi
22723 }
22724 run_test 255c "suite of ladvise lockahead tests"
22725
22726 test_256() {
22727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22728         remote_mds_nodsh && skip "remote MDS with nodsh"
22729         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22730         changelog_users $SINGLEMDS | grep "^cl" &&
22731                 skip "active changelog user"
22732
22733         local cl_user
22734         local cat_sl
22735         local mdt_dev
22736
22737         mdt_dev=$(facet_device $SINGLEMDS)
22738         echo $mdt_dev
22739
22740         changelog_register || error "changelog_register failed"
22741
22742         rm -rf $DIR/$tdir
22743         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22744
22745         changelog_clear 0 || error "changelog_clear failed"
22746
22747         # change something
22748         touch $DIR/$tdir/{1..10}
22749
22750         # stop the MDT
22751         stop $SINGLEMDS || error "Fail to stop MDT"
22752
22753         # remount the MDT
22754         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22755                 error "Fail to start MDT"
22756
22757         #after mount new plainllog is used
22758         touch $DIR/$tdir/{11..19}
22759         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22760         stack_trap "rm -f $tmpfile"
22761         cat_sl=$(do_facet $SINGLEMDS "sync; \
22762                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22763                  llog_reader $tmpfile | grep -c type=1064553b")
22764         do_facet $SINGLEMDS llog_reader $tmpfile
22765
22766         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22767
22768         changelog_clear 0 || error "changelog_clear failed"
22769
22770         cat_sl=$(do_facet $SINGLEMDS "sync; \
22771                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22772                  llog_reader $tmpfile | grep -c type=1064553b")
22773
22774         if (( cat_sl == 2 )); then
22775                 error "Empty plain llog was not deleted from changelog catalog"
22776         elif (( cat_sl != 1 )); then
22777                 error "Active plain llog shouldn't be deleted from catalog"
22778         fi
22779 }
22780 run_test 256 "Check llog delete for empty and not full state"
22781
22782 test_257() {
22783         remote_mds_nodsh && skip "remote MDS with nodsh"
22784         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22785                 skip "Need MDS version at least 2.8.55"
22786
22787         test_mkdir $DIR/$tdir
22788
22789         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22790                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22791         stat $DIR/$tdir
22792
22793 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22794         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22795         local facet=mds$((mdtidx + 1))
22796         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22797         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22798
22799         stop $facet || error "stop MDS failed"
22800         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22801                 error "start MDS fail"
22802         wait_recovery_complete $facet
22803 }
22804 run_test 257 "xattr locks are not lost"
22805
22806 # Verify we take the i_mutex when security requires it
22807 test_258a() {
22808 #define OBD_FAIL_IMUTEX_SEC 0x141c
22809         $LCTL set_param fail_loc=0x141c
22810         touch $DIR/$tfile
22811         chmod u+s $DIR/$tfile
22812         chmod a+rwx $DIR/$tfile
22813         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22814         RC=$?
22815         if [ $RC -ne 0 ]; then
22816                 error "error, failed to take i_mutex, rc=$?"
22817         fi
22818         rm -f $DIR/$tfile
22819 }
22820 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22821
22822 # Verify we do NOT take the i_mutex in the normal case
22823 test_258b() {
22824 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22825         $LCTL set_param fail_loc=0x141d
22826         touch $DIR/$tfile
22827         chmod a+rwx $DIR
22828         chmod a+rw $DIR/$tfile
22829         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22830         RC=$?
22831         if [ $RC -ne 0 ]; then
22832                 error "error, took i_mutex unnecessarily, rc=$?"
22833         fi
22834         rm -f $DIR/$tfile
22835
22836 }
22837 run_test 258b "verify i_mutex security behavior"
22838
22839 test_259() {
22840         local file=$DIR/$tfile
22841         local before
22842         local after
22843
22844         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22845
22846         stack_trap "rm -f $file" EXIT
22847
22848         wait_delete_completed
22849         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22850         echo "before: $before"
22851
22852         $LFS setstripe -i 0 -c 1 $file
22853         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22854         sync_all_data
22855         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22856         echo "after write: $after"
22857
22858 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22859         do_facet ost1 $LCTL set_param fail_loc=0x2301
22860         $TRUNCATE $file 0
22861         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22862         echo "after truncate: $after"
22863
22864         stop ost1
22865         do_facet ost1 $LCTL set_param fail_loc=0
22866         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22867         sleep 2
22868         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22869         echo "after restart: $after"
22870         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22871                 error "missing truncate?"
22872
22873         return 0
22874 }
22875 run_test 259 "crash at delayed truncate"
22876
22877 test_260() {
22878 #define OBD_FAIL_MDC_CLOSE               0x806
22879         $LCTL set_param fail_loc=0x80000806
22880         touch $DIR/$tfile
22881
22882 }
22883 run_test 260 "Check mdc_close fail"
22884
22885 ### Data-on-MDT sanity tests ###
22886 test_270a() {
22887         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22888                 skip "Need MDS version at least 2.10.55 for DoM"
22889
22890         # create DoM file
22891         local dom=$DIR/$tdir/dom_file
22892         local tmp=$DIR/$tdir/tmp_file
22893
22894         mkdir_on_mdt0 $DIR/$tdir
22895
22896         # basic checks for DoM component creation
22897         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22898                 error "Can set MDT layout to non-first entry"
22899
22900         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22901                 error "Can define multiple entries as MDT layout"
22902
22903         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22904
22905         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22906         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22907         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22908
22909         local mdtidx=$($LFS getstripe -m $dom)
22910         local mdtname=MDT$(printf %04x $mdtidx)
22911         local facet=mds$((mdtidx + 1))
22912         local space_check=1
22913
22914         # Skip free space checks with ZFS
22915         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22916
22917         # write
22918         sync
22919         local size_tmp=$((65536 * 3))
22920         local mdtfree1=$(do_facet $facet \
22921                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22922
22923         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22924         # check also direct IO along write
22925         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22926         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22927         sync
22928         cmp $tmp $dom || error "file data is different"
22929         [ $(stat -c%s $dom) == $size_tmp ] ||
22930                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22931         if [ $space_check == 1 ]; then
22932                 local mdtfree2=$(do_facet $facet \
22933                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22934
22935                 # increase in usage from by $size_tmp
22936                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22937                         error "MDT free space wrong after write: " \
22938                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22939         fi
22940
22941         # truncate
22942         local size_dom=10000
22943
22944         $TRUNCATE $dom $size_dom
22945         [ $(stat -c%s $dom) == $size_dom ] ||
22946                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22947         if [ $space_check == 1 ]; then
22948                 mdtfree1=$(do_facet $facet \
22949                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22950                 # decrease in usage from $size_tmp to new $size_dom
22951                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22952                   $(((size_tmp - size_dom) / 1024)) ] ||
22953                         error "MDT free space is wrong after truncate: " \
22954                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22955         fi
22956
22957         # append
22958         cat $tmp >> $dom
22959         sync
22960         size_dom=$((size_dom + size_tmp))
22961         [ $(stat -c%s $dom) == $size_dom ] ||
22962                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22963         if [ $space_check == 1 ]; then
22964                 mdtfree2=$(do_facet $facet \
22965                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22966                 # increase in usage by $size_tmp from previous
22967                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22968                         error "MDT free space is wrong after append: " \
22969                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22970         fi
22971
22972         # delete
22973         rm $dom
22974         if [ $space_check == 1 ]; then
22975                 mdtfree1=$(do_facet $facet \
22976                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22977                 # decrease in usage by $size_dom from previous
22978                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22979                         error "MDT free space is wrong after removal: " \
22980                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22981         fi
22982
22983         # combined striping
22984         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22985                 error "Can't create DoM + OST striping"
22986
22987         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22988         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22989         # check also direct IO along write
22990         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22991         sync
22992         cmp $tmp $dom || error "file data is different"
22993         [ $(stat -c%s $dom) == $size_tmp ] ||
22994                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22995         rm $dom $tmp
22996
22997         return 0
22998 }
22999 run_test 270a "DoM: basic functionality tests"
23000
23001 test_270b() {
23002         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23003                 skip "Need MDS version at least 2.10.55"
23004
23005         local dom=$DIR/$tdir/dom_file
23006         local max_size=1048576
23007
23008         mkdir -p $DIR/$tdir
23009         $LFS setstripe -E $max_size -L mdt $dom
23010
23011         # truncate over the limit
23012         $TRUNCATE $dom $(($max_size + 1)) &&
23013                 error "successful truncate over the maximum size"
23014         # write over the limit
23015         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23016                 error "successful write over the maximum size"
23017         # append over the limit
23018         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23019         echo "12345" >> $dom && error "successful append over the maximum size"
23020         rm $dom
23021
23022         return 0
23023 }
23024 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23025
23026 test_270c() {
23027         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23028                 skip "Need MDS version at least 2.10.55"
23029
23030         mkdir -p $DIR/$tdir
23031         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23032
23033         # check files inherit DoM EA
23034         touch $DIR/$tdir/first
23035         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23036                 error "bad pattern"
23037         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23038                 error "bad stripe count"
23039         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23040                 error "bad stripe size"
23041
23042         # check directory inherits DoM EA and uses it as default
23043         mkdir $DIR/$tdir/subdir
23044         touch $DIR/$tdir/subdir/second
23045         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23046                 error "bad pattern in sub-directory"
23047         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23048                 error "bad stripe count in sub-directory"
23049         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23050                 error "bad stripe size in sub-directory"
23051         return 0
23052 }
23053 run_test 270c "DoM: DoM EA inheritance tests"
23054
23055 test_270d() {
23056         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23057                 skip "Need MDS version at least 2.10.55"
23058
23059         mkdir -p $DIR/$tdir
23060         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23061
23062         # inherit default DoM striping
23063         mkdir $DIR/$tdir/subdir
23064         touch $DIR/$tdir/subdir/f1
23065
23066         # change default directory striping
23067         $LFS setstripe -c 1 $DIR/$tdir/subdir
23068         touch $DIR/$tdir/subdir/f2
23069         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23070                 error "wrong default striping in file 2"
23071         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23072                 error "bad pattern in file 2"
23073         return 0
23074 }
23075 run_test 270d "DoM: change striping from DoM to RAID0"
23076
23077 test_270e() {
23078         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23079                 skip "Need MDS version at least 2.10.55"
23080
23081         mkdir -p $DIR/$tdir/dom
23082         mkdir -p $DIR/$tdir/norm
23083         DOMFILES=20
23084         NORMFILES=10
23085         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23086         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23087
23088         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23089         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23090
23091         # find DoM files by layout
23092         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23093         [ $NUM -eq  $DOMFILES ] ||
23094                 error "lfs find -L: found $NUM, expected $DOMFILES"
23095         echo "Test 1: lfs find 20 DOM files by layout: OK"
23096
23097         # there should be 1 dir with default DOM striping
23098         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23099         [ $NUM -eq  1 ] ||
23100                 error "lfs find -L: found $NUM, expected 1 dir"
23101         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23102
23103         # find DoM files by stripe size
23104         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23105         [ $NUM -eq  $DOMFILES ] ||
23106                 error "lfs find -S: found $NUM, expected $DOMFILES"
23107         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23108
23109         # find files by stripe offset except DoM files
23110         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23111         [ $NUM -eq  $NORMFILES ] ||
23112                 error "lfs find -i: found $NUM, expected $NORMFILES"
23113         echo "Test 5: lfs find no DOM files by stripe index: OK"
23114         return 0
23115 }
23116 run_test 270e "DoM: lfs find with DoM files test"
23117
23118 test_270f() {
23119         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23120                 skip "Need MDS version at least 2.10.55"
23121
23122         local mdtname=${FSNAME}-MDT0000-mdtlov
23123         local dom=$DIR/$tdir/dom_file
23124         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23125                                                 lod.$mdtname.dom_stripesize)
23126         local dom_limit=131072
23127
23128         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23129         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23130                                                 lod.$mdtname.dom_stripesize)
23131         [ ${dom_limit} -eq ${dom_current} ] ||
23132                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23133
23134         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23135         $LFS setstripe -d $DIR/$tdir
23136         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23137                 error "Can't set directory default striping"
23138
23139         # exceed maximum stripe size
23140         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23141                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23142         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23143                 error "Able to create DoM component size more than LOD limit"
23144
23145         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23146         dom_current=$(do_facet mds1 $LCTL get_param -n \
23147                                                 lod.$mdtname.dom_stripesize)
23148         [ 0 -eq ${dom_current} ] ||
23149                 error "Can't set zero DoM stripe limit"
23150         rm $dom
23151
23152         # attempt to create DoM file on server with disabled DoM should
23153         # remove DoM entry from layout and be succeed
23154         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23155                 error "Can't create DoM file (DoM is disabled)"
23156         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23157                 error "File has DoM component while DoM is disabled"
23158         rm $dom
23159
23160         # attempt to create DoM file with only DoM stripe should return error
23161         $LFS setstripe -E $dom_limit -L mdt $dom &&
23162                 error "Able to create DoM-only file while DoM is disabled"
23163
23164         # too low values to be aligned with smallest stripe size 64K
23165         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23166         dom_current=$(do_facet mds1 $LCTL get_param -n \
23167                                                 lod.$mdtname.dom_stripesize)
23168         [ 30000 -eq ${dom_current} ] &&
23169                 error "Can set too small DoM stripe limit"
23170
23171         # 64K is a minimal stripe size in Lustre, expect limit of that size
23172         [ 65536 -eq ${dom_current} ] ||
23173                 error "Limit is not set to 64K but ${dom_current}"
23174
23175         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23176         dom_current=$(do_facet mds1 $LCTL get_param -n \
23177                                                 lod.$mdtname.dom_stripesize)
23178         echo $dom_current
23179         [ 2147483648 -eq ${dom_current} ] &&
23180                 error "Can set too large DoM stripe limit"
23181
23182         do_facet mds1 $LCTL set_param -n \
23183                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23184         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23185                 error "Can't create DoM component size after limit change"
23186         do_facet mds1 $LCTL set_param -n \
23187                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23188         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23189                 error "Can't create DoM file after limit decrease"
23190         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23191                 error "Can create big DoM component after limit decrease"
23192         touch ${dom}_def ||
23193                 error "Can't create file with old default layout"
23194
23195         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23196         return 0
23197 }
23198 run_test 270f "DoM: maximum DoM stripe size checks"
23199
23200 test_270g() {
23201         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23202                 skip "Need MDS version at least 2.13.52"
23203         local dom=$DIR/$tdir/$tfile
23204
23205         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23206         local lodname=${FSNAME}-MDT0000-mdtlov
23207
23208         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23209         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23210         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23211         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23212
23213         local dom_limit=1024
23214         local dom_threshold="50%"
23215
23216         $LFS setstripe -d $DIR/$tdir
23217         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23218                 error "Can't set directory default striping"
23219
23220         do_facet mds1 $LCTL set_param -n \
23221                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23222         # set 0 threshold and create DOM file to change tunable stripesize
23223         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23224         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23225                 error "Failed to create $dom file"
23226         # now tunable dom_cur_stripesize should reach maximum
23227         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23228                                         lod.${lodname}.dom_stripesize_cur_kb)
23229         [[ $dom_current == $dom_limit ]] ||
23230                 error "Current DOM stripesize is not maximum"
23231         rm $dom
23232
23233         # set threshold for further tests
23234         do_facet mds1 $LCTL set_param -n \
23235                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23236         echo "DOM threshold is $dom_threshold free space"
23237         local dom_def
23238         local dom_set
23239         # Spoof bfree to exceed threshold
23240         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23241         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23242         for spfree in 40 20 0 15 30 55; do
23243                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23244                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23245                         error "Failed to create $dom file"
23246                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23247                                         lod.${lodname}.dom_stripesize_cur_kb)
23248                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23249                 [[ $dom_def != $dom_current ]] ||
23250                         error "Default stripe size was not changed"
23251                 if (( spfree > 0 )) ; then
23252                         dom_set=$($LFS getstripe -S $dom)
23253                         (( dom_set == dom_def * 1024 )) ||
23254                                 error "DOM component size is still old"
23255                 else
23256                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23257                                 error "DoM component is set with no free space"
23258                 fi
23259                 rm $dom
23260                 dom_current=$dom_def
23261         done
23262 }
23263 run_test 270g "DoM: default DoM stripe size depends on free space"
23264
23265 test_270h() {
23266         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23267                 skip "Need MDS version at least 2.13.53"
23268
23269         local mdtname=${FSNAME}-MDT0000-mdtlov
23270         local dom=$DIR/$tdir/$tfile
23271         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23272
23273         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23274         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23275
23276         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23277         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23278                 error "can't create OST file"
23279         # mirrored file with DOM entry in the second mirror
23280         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23281                 error "can't create mirror with DoM component"
23282
23283         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23284
23285         # DOM component in the middle and has other enries in the same mirror,
23286         # should succeed but lost DoM component
23287         $LFS setstripe --copy=${dom}_1 $dom ||
23288                 error "Can't create file from OST|DOM mirror layout"
23289         # check new file has no DoM layout after all
23290         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23291                 error "File has DoM component while DoM is disabled"
23292 }
23293 run_test 270h "DoM: DoM stripe removal when disabled on server"
23294
23295 test_270i() {
23296         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23297                 skip "Need MDS version at least 2.14.54"
23298
23299         mkdir $DIR/$tdir
23300         # DoM with plain layout
23301         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23302                 error "default plain layout with DoM must fail"
23303         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23304                 error "setstripe plain file layout with DoM must fail"
23305         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23306                 error "default DoM layout with bad striping must fail"
23307         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23308                 error "setstripe to DoM layout with bad striping must fail"
23309         return 0
23310 }
23311 run_test 270i "DoM: setting invalid DoM striping should fail"
23312
23313 test_271a() {
23314         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23315                 skip "Need MDS version at least 2.10.55"
23316
23317         local dom=$DIR/$tdir/dom
23318
23319         mkdir -p $DIR/$tdir
23320
23321         $LFS setstripe -E 1024K -L mdt $dom
23322
23323         lctl set_param -n mdc.*.stats=clear
23324         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23325         cat $dom > /dev/null
23326         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23327         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23328         ls $dom
23329         rm -f $dom
23330 }
23331 run_test 271a "DoM: data is cached for read after write"
23332
23333 test_271b() {
23334         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23335                 skip "Need MDS version at least 2.10.55"
23336
23337         local dom=$DIR/$tdir/dom
23338
23339         mkdir -p $DIR/$tdir
23340
23341         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23342
23343         lctl set_param -n mdc.*.stats=clear
23344         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23345         cancel_lru_locks mdc
23346         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23347         # second stat to check size is cached on client
23348         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23349         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23350         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23351         rm -f $dom
23352 }
23353 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23354
23355 test_271ba() {
23356         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23357                 skip "Need MDS version at least 2.10.55"
23358
23359         local dom=$DIR/$tdir/dom
23360
23361         mkdir -p $DIR/$tdir
23362
23363         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23364
23365         lctl set_param -n mdc.*.stats=clear
23366         lctl set_param -n osc.*.stats=clear
23367         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23368         cancel_lru_locks mdc
23369         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23370         # second stat to check size is cached on client
23371         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23372         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23373         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23374         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23375         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23376         rm -f $dom
23377 }
23378 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23379
23380
23381 get_mdc_stats() {
23382         local mdtidx=$1
23383         local param=$2
23384         local mdt=MDT$(printf %04x $mdtidx)
23385
23386         if [ -z $param ]; then
23387                 lctl get_param -n mdc.*$mdt*.stats
23388         else
23389                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23390         fi
23391 }
23392
23393 test_271c() {
23394         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23395                 skip "Need MDS version at least 2.10.55"
23396
23397         local dom=$DIR/$tdir/dom
23398
23399         mkdir -p $DIR/$tdir
23400
23401         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23402
23403         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23404         local facet=mds$((mdtidx + 1))
23405
23406         cancel_lru_locks mdc
23407         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23408         createmany -o $dom 1000
23409         lctl set_param -n mdc.*.stats=clear
23410         smalliomany -w $dom 1000 200
23411         get_mdc_stats $mdtidx
23412         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23413         # Each file has 1 open, 1 IO enqueues, total 2000
23414         # but now we have also +1 getxattr for security.capability, total 3000
23415         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23416         unlinkmany $dom 1000
23417
23418         cancel_lru_locks mdc
23419         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23420         createmany -o $dom 1000
23421         lctl set_param -n mdc.*.stats=clear
23422         smalliomany -w $dom 1000 200
23423         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23424         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23425         # for OPEN and IO lock.
23426         [ $((enq - enq_2)) -ge 1000 ] ||
23427                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23428         unlinkmany $dom 1000
23429         return 0
23430 }
23431 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23432
23433 cleanup_271def_tests() {
23434         trap 0
23435         rm -f $1
23436 }
23437
23438 test_271d() {
23439         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23440                 skip "Need MDS version at least 2.10.57"
23441
23442         local dom=$DIR/$tdir/dom
23443         local tmp=$TMP/$tfile
23444         trap "cleanup_271def_tests $tmp" EXIT
23445
23446         mkdir -p $DIR/$tdir
23447
23448         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23449
23450         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23451
23452         cancel_lru_locks mdc
23453         dd if=/dev/urandom of=$tmp bs=1000 count=1
23454         dd if=$tmp of=$dom bs=1000 count=1
23455         cancel_lru_locks mdc
23456
23457         cat /etc/hosts >> $tmp
23458         lctl set_param -n mdc.*.stats=clear
23459
23460         # append data to the same file it should update local page
23461         echo "Append to the same page"
23462         cat /etc/hosts >> $dom
23463         local num=$(get_mdc_stats $mdtidx ost_read)
23464         local ra=$(get_mdc_stats $mdtidx req_active)
23465         local rw=$(get_mdc_stats $mdtidx req_waittime)
23466
23467         [ -z $num ] || error "$num READ RPC occured"
23468         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23469         echo "... DONE"
23470
23471         # compare content
23472         cmp $tmp $dom || error "file miscompare"
23473
23474         cancel_lru_locks mdc
23475         lctl set_param -n mdc.*.stats=clear
23476
23477         echo "Open and read file"
23478         cat $dom > /dev/null
23479         local num=$(get_mdc_stats $mdtidx ost_read)
23480         local ra=$(get_mdc_stats $mdtidx req_active)
23481         local rw=$(get_mdc_stats $mdtidx req_waittime)
23482
23483         [ -z $num ] || error "$num READ RPC occured"
23484         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23485         echo "... DONE"
23486
23487         # compare content
23488         cmp $tmp $dom || error "file miscompare"
23489
23490         return 0
23491 }
23492 run_test 271d "DoM: read on open (1K file in reply buffer)"
23493
23494 test_271f() {
23495         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23496                 skip "Need MDS version at least 2.10.57"
23497
23498         local dom=$DIR/$tdir/dom
23499         local tmp=$TMP/$tfile
23500         trap "cleanup_271def_tests $tmp" EXIT
23501
23502         mkdir -p $DIR/$tdir
23503
23504         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23505
23506         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23507
23508         cancel_lru_locks mdc
23509         dd if=/dev/urandom of=$tmp bs=265000 count=1
23510         dd if=$tmp of=$dom bs=265000 count=1
23511         cancel_lru_locks mdc
23512         cat /etc/hosts >> $tmp
23513         lctl set_param -n mdc.*.stats=clear
23514
23515         echo "Append to the same page"
23516         cat /etc/hosts >> $dom
23517         local num=$(get_mdc_stats $mdtidx ost_read)
23518         local ra=$(get_mdc_stats $mdtidx req_active)
23519         local rw=$(get_mdc_stats $mdtidx req_waittime)
23520
23521         [ -z $num ] || error "$num READ RPC occured"
23522         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23523         echo "... DONE"
23524
23525         # compare content
23526         cmp $tmp $dom || error "file miscompare"
23527
23528         cancel_lru_locks mdc
23529         lctl set_param -n mdc.*.stats=clear
23530
23531         echo "Open and read file"
23532         cat $dom > /dev/null
23533         local num=$(get_mdc_stats $mdtidx ost_read)
23534         local ra=$(get_mdc_stats $mdtidx req_active)
23535         local rw=$(get_mdc_stats $mdtidx req_waittime)
23536
23537         [ -z $num ] && num=0
23538         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23539         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23540         echo "... DONE"
23541
23542         # compare content
23543         cmp $tmp $dom || error "file miscompare"
23544
23545         return 0
23546 }
23547 run_test 271f "DoM: read on open (200K file and read tail)"
23548
23549 test_271g() {
23550         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23551                 skip "Skipping due to old client or server version"
23552
23553         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23554         # to get layout
23555         $CHECKSTAT -t file $DIR1/$tfile
23556
23557         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23558         MULTIOP_PID=$!
23559         sleep 1
23560         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23561         $LCTL set_param fail_loc=0x80000314
23562         rm $DIR1/$tfile || error "Unlink fails"
23563         RC=$?
23564         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23565         [ $RC -eq 0 ] || error "Failed write to stale object"
23566 }
23567 run_test 271g "Discard DoM data vs client flush race"
23568
23569 test_272a() {
23570         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23571                 skip "Need MDS version at least 2.11.50"
23572
23573         local dom=$DIR/$tdir/dom
23574         mkdir -p $DIR/$tdir
23575
23576         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23577         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23578                 error "failed to write data into $dom"
23579         local old_md5=$(md5sum $dom)
23580
23581         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23582                 error "failed to migrate to the same DoM component"
23583
23584         local new_md5=$(md5sum $dom)
23585
23586         [ "$old_md5" == "$new_md5" ] ||
23587                 error "md5sum differ: $old_md5, $new_md5"
23588
23589         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23590                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23591 }
23592 run_test 272a "DoM migration: new layout with the same DOM component"
23593
23594 test_272b() {
23595         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23596                 skip "Need MDS version at least 2.11.50"
23597
23598         local dom=$DIR/$tdir/dom
23599         mkdir -p $DIR/$tdir
23600         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23601
23602         local mdtidx=$($LFS getstripe -m $dom)
23603         local mdtname=MDT$(printf %04x $mdtidx)
23604         local facet=mds$((mdtidx + 1))
23605
23606         local mdtfree1=$(do_facet $facet \
23607                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23608         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23609                 error "failed to write data into $dom"
23610         local old_md5=$(md5sum $dom)
23611         cancel_lru_locks mdc
23612         local mdtfree1=$(do_facet $facet \
23613                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23614
23615         $LFS migrate -c2 $dom ||
23616                 error "failed to migrate to the new composite layout"
23617         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23618                 error "MDT stripe was not removed"
23619
23620         cancel_lru_locks mdc
23621         local new_md5=$(md5sum $dom)
23622         [ "$old_md5" == "$new_md5" ] ||
23623                 error "$old_md5 != $new_md5"
23624
23625         # Skip free space checks with ZFS
23626         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23627                 local mdtfree2=$(do_facet $facet \
23628                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23629                 [ $mdtfree2 -gt $mdtfree1 ] ||
23630                         error "MDT space is not freed after migration"
23631         fi
23632         return 0
23633 }
23634 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23635
23636 test_272c() {
23637         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23638                 skip "Need MDS version at least 2.11.50"
23639
23640         local dom=$DIR/$tdir/$tfile
23641         mkdir -p $DIR/$tdir
23642         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23643
23644         local mdtidx=$($LFS getstripe -m $dom)
23645         local mdtname=MDT$(printf %04x $mdtidx)
23646         local facet=mds$((mdtidx + 1))
23647
23648         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23649                 error "failed to write data into $dom"
23650         local old_md5=$(md5sum $dom)
23651         cancel_lru_locks mdc
23652         local mdtfree1=$(do_facet $facet \
23653                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23654
23655         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23656                 error "failed to migrate to the new composite layout"
23657         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23658                 error "MDT stripe was not removed"
23659
23660         cancel_lru_locks mdc
23661         local new_md5=$(md5sum $dom)
23662         [ "$old_md5" == "$new_md5" ] ||
23663                 error "$old_md5 != $new_md5"
23664
23665         # Skip free space checks with ZFS
23666         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23667                 local mdtfree2=$(do_facet $facet \
23668                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23669                 [ $mdtfree2 -gt $mdtfree1 ] ||
23670                         error "MDS space is not freed after migration"
23671         fi
23672         return 0
23673 }
23674 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23675
23676 test_272d() {
23677         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23678                 skip "Need MDS version at least 2.12.55"
23679
23680         local dom=$DIR/$tdir/$tfile
23681         mkdir -p $DIR/$tdir
23682         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23683
23684         local mdtidx=$($LFS getstripe -m $dom)
23685         local mdtname=MDT$(printf %04x $mdtidx)
23686         local facet=mds$((mdtidx + 1))
23687
23688         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23689                 error "failed to write data into $dom"
23690         local old_md5=$(md5sum $dom)
23691         cancel_lru_locks mdc
23692         local mdtfree1=$(do_facet $facet \
23693                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23694
23695         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23696                 error "failed mirroring to the new composite layout"
23697         $LFS mirror resync $dom ||
23698                 error "failed mirror resync"
23699         $LFS mirror split --mirror-id 1 -d $dom ||
23700                 error "failed mirror split"
23701
23702         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23703                 error "MDT stripe was not removed"
23704
23705         cancel_lru_locks mdc
23706         local new_md5=$(md5sum $dom)
23707         [ "$old_md5" == "$new_md5" ] ||
23708                 error "$old_md5 != $new_md5"
23709
23710         # Skip free space checks with ZFS
23711         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23712                 local mdtfree2=$(do_facet $facet \
23713                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23714                 [ $mdtfree2 -gt $mdtfree1 ] ||
23715                         error "MDS space is not freed after DOM mirror deletion"
23716         fi
23717         return 0
23718 }
23719 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23720
23721 test_272e() {
23722         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23723                 skip "Need MDS version at least 2.12.55"
23724
23725         local dom=$DIR/$tdir/$tfile
23726         mkdir -p $DIR/$tdir
23727         $LFS setstripe -c 2 $dom
23728
23729         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23730                 error "failed to write data into $dom"
23731         local old_md5=$(md5sum $dom)
23732         cancel_lru_locks
23733
23734         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23735                 error "failed mirroring to the DOM layout"
23736         $LFS mirror resync $dom ||
23737                 error "failed mirror resync"
23738         $LFS mirror split --mirror-id 1 -d $dom ||
23739                 error "failed mirror split"
23740
23741         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23742                 error "MDT stripe wasn't set"
23743
23744         cancel_lru_locks
23745         local new_md5=$(md5sum $dom)
23746         [ "$old_md5" == "$new_md5" ] ||
23747                 error "$old_md5 != $new_md5"
23748
23749         return 0
23750 }
23751 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23752
23753 test_272f() {
23754         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23755                 skip "Need MDS version at least 2.12.55"
23756
23757         local dom=$DIR/$tdir/$tfile
23758         mkdir -p $DIR/$tdir
23759         $LFS setstripe -c 2 $dom
23760
23761         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23762                 error "failed to write data into $dom"
23763         local old_md5=$(md5sum $dom)
23764         cancel_lru_locks
23765
23766         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23767                 error "failed migrating to the DOM file"
23768
23769         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23770                 error "MDT stripe wasn't set"
23771
23772         cancel_lru_locks
23773         local new_md5=$(md5sum $dom)
23774         [ "$old_md5" != "$new_md5" ] &&
23775                 error "$old_md5 != $new_md5"
23776
23777         return 0
23778 }
23779 run_test 272f "DoM migration: OST-striped file to DOM file"
23780
23781 test_273a() {
23782         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23783                 skip "Need MDS version at least 2.11.50"
23784
23785         # Layout swap cannot be done if either file has DOM component,
23786         # this will never be supported, migration should be used instead
23787
23788         local dom=$DIR/$tdir/$tfile
23789         mkdir -p $DIR/$tdir
23790
23791         $LFS setstripe -c2 ${dom}_plain
23792         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23793         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23794                 error "can swap layout with DoM component"
23795         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23796                 error "can swap layout with DoM component"
23797
23798         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23799         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23800                 error "can swap layout with DoM component"
23801         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23802                 error "can swap layout with DoM component"
23803         return 0
23804 }
23805 run_test 273a "DoM: layout swapping should fail with DOM"
23806
23807 test_273b() {
23808         mkdir -p $DIR/$tdir
23809         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23810
23811 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23812         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23813
23814         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23815 }
23816 run_test 273b "DoM: race writeback and object destroy"
23817
23818 test_275() {
23819         remote_ost_nodsh && skip "remote OST with nodsh"
23820         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23821                 skip "Need OST version >= 2.10.57"
23822
23823         local file=$DIR/$tfile
23824         local oss
23825
23826         oss=$(comma_list $(osts_nodes))
23827
23828         dd if=/dev/urandom of=$file bs=1M count=2 ||
23829                 error "failed to create a file"
23830         cancel_lru_locks osc
23831
23832         #lock 1
23833         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23834                 error "failed to read a file"
23835
23836 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23837         $LCTL set_param fail_loc=0x8000031f
23838
23839         cancel_lru_locks osc &
23840         sleep 1
23841
23842 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23843         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23844         #IO takes another lock, but matches the PENDING one
23845         #and places it to the IO RPC
23846         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23847                 error "failed to read a file with PENDING lock"
23848 }
23849 run_test 275 "Read on a canceled duplicate lock"
23850
23851 test_276() {
23852         remote_ost_nodsh && skip "remote OST with nodsh"
23853         local pid
23854
23855         do_facet ost1 "(while true; do \
23856                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23857                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23858         pid=$!
23859
23860         for LOOP in $(seq 20); do
23861                 stop ost1
23862                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23863         done
23864         kill -9 $pid
23865         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23866                 rm $TMP/sanity_276_pid"
23867 }
23868 run_test 276 "Race between mount and obd_statfs"
23869
23870 test_277() {
23871         $LCTL set_param ldlm.namespaces.*.lru_size=0
23872         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23873         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23874                         grep ^used_mb | awk '{print $2}')
23875         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23876         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23877                 oflag=direct conv=notrunc
23878         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23879                         grep ^used_mb | awk '{print $2}')
23880         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23881 }
23882 run_test 277 "Direct IO shall drop page cache"
23883
23884 test_278() {
23885         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23886         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23887         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23888                 skip "needs the same host for mdt1 mdt2" && return
23889
23890         local pid1
23891         local pid2
23892
23893 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23894         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23895         stop mds2 &
23896         pid2=$!
23897
23898         stop mds1
23899
23900         echo "Starting MDTs"
23901         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23902         wait $pid2
23903 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23904 #will return NULL
23905         do_facet mds2 $LCTL set_param fail_loc=0
23906
23907         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23908         wait_recovery_complete mds2
23909 }
23910 run_test 278 "Race starting MDS between MDTs stop/start"
23911
23912 test_280() {
23913         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23914                 skip "Need MGS version at least 2.13.52"
23915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23916         combined_mgs_mds || skip "needs combined MGS/MDT"
23917
23918         umount_client $MOUNT
23919 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23920         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23921
23922         mount_client $MOUNT &
23923         sleep 1
23924         stop mgs || error "stop mgs failed"
23925         #for a race mgs would crash
23926         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23927         # make sure we unmount client before remounting
23928         wait
23929         umount_client $MOUNT
23930         mount_client $MOUNT || error "mount client failed"
23931 }
23932 run_test 280 "Race between MGS umount and client llog processing"
23933
23934 cleanup_test_300() {
23935         trap 0
23936         umask $SAVE_UMASK
23937 }
23938 test_striped_dir() {
23939         local mdt_index=$1
23940         local stripe_count
23941         local stripe_index
23942
23943         mkdir -p $DIR/$tdir
23944
23945         SAVE_UMASK=$(umask)
23946         trap cleanup_test_300 RETURN EXIT
23947
23948         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23949                                                 $DIR/$tdir/striped_dir ||
23950                 error "set striped dir error"
23951
23952         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23953         [ "$mode" = "755" ] || error "expect 755 got $mode"
23954
23955         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23956                 error "getdirstripe failed"
23957         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23958         if [ "$stripe_count" != "2" ]; then
23959                 error "1:stripe_count is $stripe_count, expect 2"
23960         fi
23961         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23962         if [ "$stripe_count" != "2" ]; then
23963                 error "2:stripe_count is $stripe_count, expect 2"
23964         fi
23965
23966         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23967         if [ "$stripe_index" != "$mdt_index" ]; then
23968                 error "stripe_index is $stripe_index, expect $mdt_index"
23969         fi
23970
23971         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23972                 error "nlink error after create striped dir"
23973
23974         mkdir $DIR/$tdir/striped_dir/a
23975         mkdir $DIR/$tdir/striped_dir/b
23976
23977         stat $DIR/$tdir/striped_dir/a ||
23978                 error "create dir under striped dir failed"
23979         stat $DIR/$tdir/striped_dir/b ||
23980                 error "create dir under striped dir failed"
23981
23982         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23983                 error "nlink error after mkdir"
23984
23985         rmdir $DIR/$tdir/striped_dir/a
23986         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23987                 error "nlink error after rmdir"
23988
23989         rmdir $DIR/$tdir/striped_dir/b
23990         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23991                 error "nlink error after rmdir"
23992
23993         chattr +i $DIR/$tdir/striped_dir
23994         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23995                 error "immutable flags not working under striped dir!"
23996         chattr -i $DIR/$tdir/striped_dir
23997
23998         rmdir $DIR/$tdir/striped_dir ||
23999                 error "rmdir striped dir error"
24000
24001         cleanup_test_300
24002
24003         true
24004 }
24005
24006 test_300a() {
24007         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24008                 skip "skipped for lustre < 2.7.0"
24009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24010         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24011
24012         test_striped_dir 0 || error "failed on striped dir on MDT0"
24013         test_striped_dir 1 || error "failed on striped dir on MDT0"
24014 }
24015 run_test 300a "basic striped dir sanity test"
24016
24017 test_300b() {
24018         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24019                 skip "skipped for lustre < 2.7.0"
24020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24021         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24022
24023         local i
24024         local mtime1
24025         local mtime2
24026         local mtime3
24027
24028         test_mkdir $DIR/$tdir || error "mkdir fail"
24029         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24030                 error "set striped dir error"
24031         for i in {0..9}; do
24032                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24033                 sleep 1
24034                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24035                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24036                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24037                 sleep 1
24038                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24039                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24040                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24041         done
24042         true
24043 }
24044 run_test 300b "check ctime/mtime for striped dir"
24045
24046 test_300c() {
24047         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24048                 skip "skipped for lustre < 2.7.0"
24049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24050         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24051
24052         local file_count
24053
24054         mkdir_on_mdt0 $DIR/$tdir
24055         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24056                 error "set striped dir error"
24057
24058         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24059                 error "chown striped dir failed"
24060
24061         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24062                 error "create 5k files failed"
24063
24064         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24065
24066         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24067
24068         rm -rf $DIR/$tdir
24069 }
24070 run_test 300c "chown && check ls under striped directory"
24071
24072 test_300d() {
24073         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24074                 skip "skipped for lustre < 2.7.0"
24075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24077
24078         local stripe_count
24079         local file
24080
24081         mkdir -p $DIR/$tdir
24082         $LFS setstripe -c 2 $DIR/$tdir
24083
24084         #local striped directory
24085         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24086                 error "set striped dir error"
24087         #look at the directories for debug purposes
24088         ls -l $DIR/$tdir
24089         $LFS getdirstripe $DIR/$tdir
24090         ls -l $DIR/$tdir/striped_dir
24091         $LFS getdirstripe $DIR/$tdir/striped_dir
24092         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24093                 error "create 10 files failed"
24094
24095         #remote striped directory
24096         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24097                 error "set striped dir error"
24098         #look at the directories for debug purposes
24099         ls -l $DIR/$tdir
24100         $LFS getdirstripe $DIR/$tdir
24101         ls -l $DIR/$tdir/remote_striped_dir
24102         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24103         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24104                 error "create 10 files failed"
24105
24106         for file in $(find $DIR/$tdir); do
24107                 stripe_count=$($LFS getstripe -c $file)
24108                 [ $stripe_count -eq 2 ] ||
24109                         error "wrong stripe $stripe_count for $file"
24110         done
24111
24112         rm -rf $DIR/$tdir
24113 }
24114 run_test 300d "check default stripe under striped directory"
24115
24116 test_300e() {
24117         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24118                 skip "Need MDS version at least 2.7.55"
24119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24121
24122         local stripe_count
24123         local file
24124
24125         mkdir -p $DIR/$tdir
24126
24127         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24128                 error "set striped dir error"
24129
24130         touch $DIR/$tdir/striped_dir/a
24131         touch $DIR/$tdir/striped_dir/b
24132         touch $DIR/$tdir/striped_dir/c
24133
24134         mkdir $DIR/$tdir/striped_dir/dir_a
24135         mkdir $DIR/$tdir/striped_dir/dir_b
24136         mkdir $DIR/$tdir/striped_dir/dir_c
24137
24138         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24139                 error "set striped adir under striped dir error"
24140
24141         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24142                 error "set striped bdir under striped dir error"
24143
24144         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24145                 error "set striped cdir under striped dir error"
24146
24147         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24148                 error "rename dir under striped dir fails"
24149
24150         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24151                 error "rename dir under different stripes fails"
24152
24153         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24154                 error "rename file under striped dir should succeed"
24155
24156         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24157                 error "rename dir under striped dir should succeed"
24158
24159         rm -rf $DIR/$tdir
24160 }
24161 run_test 300e "check rename under striped directory"
24162
24163 test_300f() {
24164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24165         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24166         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24167                 skip "Need MDS version at least 2.7.55"
24168
24169         local stripe_count
24170         local file
24171
24172         rm -rf $DIR/$tdir
24173         mkdir -p $DIR/$tdir
24174
24175         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24176                 error "set striped dir error"
24177
24178         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24179                 error "set striped dir error"
24180
24181         touch $DIR/$tdir/striped_dir/a
24182         mkdir $DIR/$tdir/striped_dir/dir_a
24183         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24184                 error "create striped dir under striped dir fails"
24185
24186         touch $DIR/$tdir/striped_dir1/b
24187         mkdir $DIR/$tdir/striped_dir1/dir_b
24188         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24189                 error "create striped dir under striped dir fails"
24190
24191         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24192                 error "rename dir under different striped dir should fail"
24193
24194         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24195                 error "rename striped dir under diff striped dir should fail"
24196
24197         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24198                 error "rename file under diff striped dirs fails"
24199
24200         rm -rf $DIR/$tdir
24201 }
24202 run_test 300f "check rename cross striped directory"
24203
24204 test_300_check_default_striped_dir()
24205 {
24206         local dirname=$1
24207         local default_count=$2
24208         local default_index=$3
24209         local stripe_count
24210         local stripe_index
24211         local dir_stripe_index
24212         local dir
24213
24214         echo "checking $dirname $default_count $default_index"
24215         $LFS setdirstripe -D -c $default_count -i $default_index \
24216                                 -H all_char $DIR/$tdir/$dirname ||
24217                 error "set default stripe on striped dir error"
24218         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24219         [ $stripe_count -eq $default_count ] ||
24220                 error "expect $default_count get $stripe_count for $dirname"
24221
24222         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24223         [ $stripe_index -eq $default_index ] ||
24224                 error "expect $default_index get $stripe_index for $dirname"
24225
24226         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24227                                                 error "create dirs failed"
24228
24229         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24230         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24231         for dir in $(find $DIR/$tdir/$dirname/*); do
24232                 stripe_count=$($LFS getdirstripe -c $dir)
24233                 (( $stripe_count == $default_count )) ||
24234                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24235                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24236                 error "stripe count $default_count != $stripe_count for $dir"
24237
24238                 stripe_index=$($LFS getdirstripe -i $dir)
24239                 [ $default_index -eq -1 ] ||
24240                         [ $stripe_index -eq $default_index ] ||
24241                         error "$stripe_index != $default_index for $dir"
24242
24243                 #check default stripe
24244                 stripe_count=$($LFS getdirstripe -D -c $dir)
24245                 [ $stripe_count -eq $default_count ] ||
24246                 error "default count $default_count != $stripe_count for $dir"
24247
24248                 stripe_index=$($LFS getdirstripe -D -i $dir)
24249                 [ $stripe_index -eq $default_index ] ||
24250                 error "default index $default_index != $stripe_index for $dir"
24251         done
24252         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24253 }
24254
24255 test_300g() {
24256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24258                 skip "Need MDS version at least 2.7.55"
24259
24260         local dir
24261         local stripe_count
24262         local stripe_index
24263
24264         mkdir_on_mdt0 $DIR/$tdir
24265         mkdir $DIR/$tdir/normal_dir
24266
24267         #Checking when client cache stripe index
24268         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24269         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24270                 error "create striped_dir failed"
24271
24272         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24273                 error "create dir0 fails"
24274         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24275         [ $stripe_index -eq 0 ] ||
24276                 error "dir0 expect index 0 got $stripe_index"
24277
24278         mkdir $DIR/$tdir/striped_dir/dir1 ||
24279                 error "create dir1 fails"
24280         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24281         [ $stripe_index -eq 1 ] ||
24282                 error "dir1 expect index 1 got $stripe_index"
24283
24284         #check default stripe count/stripe index
24285         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24286         test_300_check_default_striped_dir normal_dir 1 0
24287         test_300_check_default_striped_dir normal_dir -1 1
24288         test_300_check_default_striped_dir normal_dir 2 -1
24289
24290         #delete default stripe information
24291         echo "delete default stripeEA"
24292         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24293                 error "set default stripe on striped dir error"
24294
24295         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24296         for dir in $(find $DIR/$tdir/normal_dir/*); do
24297                 stripe_count=$($LFS getdirstripe -c $dir)
24298                 [ $stripe_count -eq 0 ] ||
24299                         error "expect 1 get $stripe_count for $dir"
24300         done
24301 }
24302 run_test 300g "check default striped directory for normal directory"
24303
24304 test_300h() {
24305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24306         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24307                 skip "Need MDS version at least 2.7.55"
24308
24309         local dir
24310         local stripe_count
24311
24312         mkdir $DIR/$tdir
24313         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24314                 error "set striped dir error"
24315
24316         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24317         test_300_check_default_striped_dir striped_dir 1 0
24318         test_300_check_default_striped_dir striped_dir -1 1
24319         test_300_check_default_striped_dir striped_dir 2 -1
24320
24321         #delete default stripe information
24322         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24323                 error "set default stripe on striped dir error"
24324
24325         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24326         for dir in $(find $DIR/$tdir/striped_dir/*); do
24327                 stripe_count=$($LFS getdirstripe -c $dir)
24328                 [ $stripe_count -eq 0 ] ||
24329                         error "expect 1 get $stripe_count for $dir"
24330         done
24331 }
24332 run_test 300h "check default striped directory for striped directory"
24333
24334 test_300i() {
24335         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24336         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24337         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24338                 skip "Need MDS version at least 2.7.55"
24339
24340         local stripe_count
24341         local file
24342
24343         mkdir $DIR/$tdir
24344
24345         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24346                 error "set striped dir error"
24347
24348         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24349                 error "create files under striped dir failed"
24350
24351         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24352                 error "set striped hashdir error"
24353
24354         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24355                 error "create dir0 under hash dir failed"
24356         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24357                 error "create dir1 under hash dir failed"
24358         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24359                 error "create dir2 under hash dir failed"
24360
24361         # unfortunately, we need to umount to clear dir layout cache for now
24362         # once we fully implement dir layout, we can drop this
24363         umount_client $MOUNT || error "umount failed"
24364         mount_client $MOUNT || error "mount failed"
24365
24366         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24367         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24368         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24369
24370         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24371                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24372                         error "create crush2 dir $tdir/hashdir/d3 failed"
24373                 $LFS find -H crush2 $DIR/$tdir/hashdir
24374                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24375                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24376
24377                 # mkdir with an invalid hash type (hash=fail_val) from client
24378                 # should be replaced on MDS with a valid (default) hash type
24379                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24380                 $LCTL set_param fail_loc=0x1901 fail_val=99
24381                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24382
24383                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24384                 local expect=$(do_facet mds1 \
24385                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24386                 [[ $hash == $expect ]] ||
24387                         error "d99 hash '$hash' != expected hash '$expect'"
24388         fi
24389
24390         #set the stripe to be unknown hash type on read
24391         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24392         $LCTL set_param fail_loc=0x1901 fail_val=99
24393         for ((i = 0; i < 10; i++)); do
24394                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24395                         error "stat f-$i failed"
24396                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24397         done
24398
24399         touch $DIR/$tdir/striped_dir/f0 &&
24400                 error "create under striped dir with unknown hash should fail"
24401
24402         $LCTL set_param fail_loc=0
24403
24404         umount_client $MOUNT || error "umount failed"
24405         mount_client $MOUNT || error "mount failed"
24406
24407         return 0
24408 }
24409 run_test 300i "client handle unknown hash type striped directory"
24410
24411 test_300j() {
24412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24414         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24415                 skip "Need MDS version at least 2.7.55"
24416
24417         local stripe_count
24418         local file
24419
24420         mkdir $DIR/$tdir
24421
24422         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24423         $LCTL set_param fail_loc=0x1702
24424         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24425                 error "set striped dir error"
24426
24427         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24428                 error "create files under striped dir failed"
24429
24430         $LCTL set_param fail_loc=0
24431
24432         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24433
24434         return 0
24435 }
24436 run_test 300j "test large update record"
24437
24438 test_300k() {
24439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24441         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24442                 skip "Need MDS version at least 2.7.55"
24443
24444         # this test needs a huge transaction
24445         local kb
24446         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24447              osd*.$FSNAME-MDT0000.kbytestotal")
24448         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24449
24450         local stripe_count
24451         local file
24452
24453         mkdir $DIR/$tdir
24454
24455         #define OBD_FAIL_LARGE_STRIPE   0x1703
24456         $LCTL set_param fail_loc=0x1703
24457         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24458                 error "set striped dir error"
24459         $LCTL set_param fail_loc=0
24460
24461         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24462                 error "getstripeddir fails"
24463         rm -rf $DIR/$tdir/striped_dir ||
24464                 error "unlink striped dir fails"
24465
24466         return 0
24467 }
24468 run_test 300k "test large striped directory"
24469
24470 test_300l() {
24471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24473         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24474                 skip "Need MDS version at least 2.7.55"
24475
24476         local stripe_index
24477
24478         test_mkdir -p $DIR/$tdir/striped_dir
24479         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24480                         error "chown $RUNAS_ID failed"
24481         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24482                 error "set default striped dir failed"
24483
24484         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24485         $LCTL set_param fail_loc=0x80000158
24486         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24487
24488         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24489         [ $stripe_index -eq 1 ] ||
24490                 error "expect 1 get $stripe_index for $dir"
24491 }
24492 run_test 300l "non-root user to create dir under striped dir with stale layout"
24493
24494 test_300m() {
24495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24496         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24497         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24498                 skip "Need MDS version at least 2.7.55"
24499
24500         mkdir -p $DIR/$tdir/striped_dir
24501         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24502                 error "set default stripes dir error"
24503
24504         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24505
24506         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24507         [ $stripe_count -eq 0 ] ||
24508                         error "expect 0 get $stripe_count for a"
24509
24510         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24511                 error "set default stripes dir error"
24512
24513         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24514
24515         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24516         [ $stripe_count -eq 0 ] ||
24517                         error "expect 0 get $stripe_count for b"
24518
24519         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24520                 error "set default stripes dir error"
24521
24522         mkdir $DIR/$tdir/striped_dir/c &&
24523                 error "default stripe_index is invalid, mkdir c should fails"
24524
24525         rm -rf $DIR/$tdir || error "rmdir fails"
24526 }
24527 run_test 300m "setstriped directory on single MDT FS"
24528
24529 cleanup_300n() {
24530         local list=$(comma_list $(mdts_nodes))
24531
24532         trap 0
24533         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24534 }
24535
24536 test_300n() {
24537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24539         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24540                 skip "Need MDS version at least 2.7.55"
24541         remote_mds_nodsh && skip "remote MDS with nodsh"
24542
24543         local stripe_index
24544         local list=$(comma_list $(mdts_nodes))
24545
24546         trap cleanup_300n RETURN EXIT
24547         mkdir -p $DIR/$tdir
24548         chmod 777 $DIR/$tdir
24549         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24550                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24551                 error "create striped dir succeeds with gid=0"
24552
24553         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24554         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24555                 error "create striped dir fails with gid=-1"
24556
24557         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24558         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24559                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24560                 error "set default striped dir succeeds with gid=0"
24561
24562
24563         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24564         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24565                 error "set default striped dir fails with gid=-1"
24566
24567
24568         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24569         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24570                                         error "create test_dir fails"
24571         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24572                                         error "create test_dir1 fails"
24573         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24574                                         error "create test_dir2 fails"
24575         cleanup_300n
24576 }
24577 run_test 300n "non-root user to create dir under striped dir with default EA"
24578
24579 test_300o() {
24580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24582         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24583                 skip "Need MDS version at least 2.7.55"
24584
24585         local numfree1
24586         local numfree2
24587
24588         mkdir -p $DIR/$tdir
24589
24590         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24591         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24592         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24593                 skip "not enough free inodes $numfree1 $numfree2"
24594         fi
24595
24596         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24597         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24598         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24599                 skip "not enough free space $numfree1 $numfree2"
24600         fi
24601
24602         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24603                 error "setdirstripe fails"
24604
24605         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24606                 error "create dirs fails"
24607
24608         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24609         ls $DIR/$tdir/striped_dir > /dev/null ||
24610                 error "ls striped dir fails"
24611         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24612                 error "unlink big striped dir fails"
24613 }
24614 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24615
24616 test_300p() {
24617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24619         remote_mds_nodsh && skip "remote MDS with nodsh"
24620
24621         mkdir_on_mdt0 $DIR/$tdir
24622
24623         #define OBD_FAIL_OUT_ENOSPC     0x1704
24624         do_facet mds2 lctl set_param fail_loc=0x80001704
24625         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24626                  && error "create striped directory should fail"
24627
24628         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24629
24630         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24631         true
24632 }
24633 run_test 300p "create striped directory without space"
24634
24635 test_300q() {
24636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24638
24639         local fd=$(free_fd)
24640         local cmd="exec $fd<$tdir"
24641         cd $DIR
24642         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24643         eval $cmd
24644         cmd="exec $fd<&-"
24645         trap "eval $cmd" EXIT
24646         cd $tdir || error "cd $tdir fails"
24647         rmdir  ../$tdir || error "rmdir $tdir fails"
24648         mkdir local_dir && error "create dir succeeds"
24649         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24650         eval $cmd
24651         return 0
24652 }
24653 run_test 300q "create remote directory under orphan directory"
24654
24655 test_300r() {
24656         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24657                 skip "Need MDS version at least 2.7.55" && return
24658         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24659
24660         mkdir $DIR/$tdir
24661
24662         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24663                 error "set striped dir error"
24664
24665         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24666                 error "getstripeddir fails"
24667
24668         local stripe_count
24669         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24670                       awk '/lmv_stripe_count:/ { print $2 }')
24671
24672         [ $MDSCOUNT -ne $stripe_count ] &&
24673                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24674
24675         rm -rf $DIR/$tdir/striped_dir ||
24676                 error "unlink striped dir fails"
24677 }
24678 run_test 300r "test -1 striped directory"
24679
24680 test_300s_helper() {
24681         local count=$1
24682
24683         local stripe_dir=$DIR/$tdir/striped_dir.$count
24684
24685         $LFS mkdir -c $count $stripe_dir ||
24686                 error "lfs mkdir -c error"
24687
24688         $LFS getdirstripe $stripe_dir ||
24689                 error "lfs getdirstripe fails"
24690
24691         local stripe_count
24692         stripe_count=$($LFS getdirstripe $stripe_dir |
24693                       awk '/lmv_stripe_count:/ { print $2 }')
24694
24695         [ $count -ne $stripe_count ] &&
24696                 error_noexit "bad stripe count $stripe_count expected $count"
24697
24698         local dupe_stripes
24699         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24700                 awk '/0x/ {count[$1] += 1}; END {
24701                         for (idx in count) {
24702                                 if (count[idx]>1) {
24703                                         print "index " idx " count " count[idx]
24704                                 }
24705                         }
24706                 }')
24707
24708         if [[ -n "$dupe_stripes" ]] ; then
24709                 lfs getdirstripe $stripe_dir
24710                 error_noexit "Dupe MDT above: $dupe_stripes "
24711         fi
24712
24713         rm -rf $stripe_dir ||
24714                 error_noexit "unlink $stripe_dir fails"
24715 }
24716
24717 test_300s() {
24718         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24719                 skip "Need MDS version at least 2.7.55" && return
24720         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24721
24722         mkdir $DIR/$tdir
24723         for count in $(seq 2 $MDSCOUNT); do
24724                 test_300s_helper $count
24725         done
24726 }
24727 run_test 300s "test lfs mkdir -c without -i"
24728
24729 test_300t() {
24730         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24731                 skip "need MDS 2.14.55 or later"
24732         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24733
24734         local testdir="$DIR/$tdir/striped_dir"
24735         local dir1=$testdir/dir1
24736         local dir2=$testdir/dir2
24737
24738         mkdir -p $testdir
24739
24740         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24741                 error "failed to set default stripe count for $testdir"
24742
24743         mkdir $dir1
24744         local stripe_count=$($LFS getdirstripe -c $dir1)
24745
24746         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24747
24748         local max_count=$((MDSCOUNT - 1))
24749         local mdts=$(comma_list $(mdts_nodes))
24750
24751         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24752         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24753
24754         mkdir $dir2
24755         stripe_count=$($LFS getdirstripe -c $dir2)
24756
24757         (( $stripe_count == $max_count )) || error "wrong stripe count"
24758 }
24759 run_test 300t "test max_mdt_stripecount"
24760
24761 prepare_remote_file() {
24762         mkdir $DIR/$tdir/src_dir ||
24763                 error "create remote source failed"
24764
24765         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24766                  error "cp to remote source failed"
24767         touch $DIR/$tdir/src_dir/a
24768
24769         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24770                 error "create remote target dir failed"
24771
24772         touch $DIR/$tdir/tgt_dir/b
24773
24774         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24775                 error "rename dir cross MDT failed!"
24776
24777         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24778                 error "src_child still exists after rename"
24779
24780         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24781                 error "missing file(a) after rename"
24782
24783         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24784                 error "diff after rename"
24785 }
24786
24787 test_310a() {
24788         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24790
24791         local remote_file=$DIR/$tdir/tgt_dir/b
24792
24793         mkdir -p $DIR/$tdir
24794
24795         prepare_remote_file || error "prepare remote file failed"
24796
24797         #open-unlink file
24798         $OPENUNLINK $remote_file $remote_file ||
24799                 error "openunlink $remote_file failed"
24800         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24801 }
24802 run_test 310a "open unlink remote file"
24803
24804 test_310b() {
24805         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24807
24808         local remote_file=$DIR/$tdir/tgt_dir/b
24809
24810         mkdir -p $DIR/$tdir
24811
24812         prepare_remote_file || error "prepare remote file failed"
24813
24814         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24815         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24816         $CHECKSTAT -t file $remote_file || error "check file failed"
24817 }
24818 run_test 310b "unlink remote file with multiple links while open"
24819
24820 test_310c() {
24821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24822         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
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         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24831         multiop_bg_pause $remote_file O_uc ||
24832                         error "mulitop failed for remote file"
24833         MULTIPID=$!
24834         $MULTIOP $DIR/$tfile Ouc
24835         kill -USR1 $MULTIPID
24836         wait $MULTIPID
24837 }
24838 run_test 310c "open-unlink remote file with multiple links"
24839
24840 #LU-4825
24841 test_311() {
24842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24843         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24844         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24845                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24846         remote_mds_nodsh && skip "remote MDS with nodsh"
24847
24848         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24849         local mdts=$(comma_list $(mdts_nodes))
24850
24851         mkdir -p $DIR/$tdir
24852         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24853         createmany -o $DIR/$tdir/$tfile. 1000
24854
24855         # statfs data is not real time, let's just calculate it
24856         old_iused=$((old_iused + 1000))
24857
24858         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24859                         osp.*OST0000*MDT0000.create_count")
24860         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24861                                 osp.*OST0000*MDT0000.max_create_count")
24862         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24863
24864         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24865         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24866         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24867
24868         unlinkmany $DIR/$tdir/$tfile. 1000
24869
24870         do_nodes $mdts "$LCTL set_param -n \
24871                         osp.*OST0000*.max_create_count=$max_count"
24872         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24873                 do_nodes $mdts "$LCTL set_param -n \
24874                                 osp.*OST0000*.create_count=$count"
24875         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24876                         grep "=0" && error "create_count is zero"
24877
24878         local new_iused
24879         for i in $(seq 120); do
24880                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24881                 # system may be too busy to destroy all objs in time, use
24882                 # a somewhat small value to not fail autotest
24883                 [ $((old_iused - new_iused)) -gt 400 ] && break
24884                 sleep 1
24885         done
24886
24887         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24888         [ $((old_iused - new_iused)) -gt 400 ] ||
24889                 error "objs not destroyed after unlink"
24890 }
24891 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24892
24893 zfs_get_objid()
24894 {
24895         local ost=$1
24896         local tf=$2
24897         local fid=($($LFS getstripe $tf | grep 0x))
24898         local seq=${fid[3]#0x}
24899         local objid=${fid[1]}
24900
24901         local vdevdir=$(dirname $(facet_vdevice $ost))
24902         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24903         local zfs_zapid=$(do_facet $ost $cmd |
24904                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24905                           awk '/Object/{getline; print $1}')
24906         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24907                           awk "/$objid = /"'{printf $3}')
24908
24909         echo $zfs_objid
24910 }
24911
24912 zfs_object_blksz() {
24913         local ost=$1
24914         local objid=$2
24915
24916         local vdevdir=$(dirname $(facet_vdevice $ost))
24917         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24918         local blksz=$(do_facet $ost $cmd $objid |
24919                       awk '/dblk/{getline; printf $4}')
24920
24921         case "${blksz: -1}" in
24922                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24923                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24924                 *) ;;
24925         esac
24926
24927         echo $blksz
24928 }
24929
24930 test_312() { # LU-4856
24931         remote_ost_nodsh && skip "remote OST with nodsh"
24932         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
24933
24934         local max_blksz=$(do_facet ost1 \
24935                           $ZFS get -p recordsize $(facet_device ost1) |
24936                           awk '!/VALUE/{print $3}')
24937         local tf=$DIR/$tfile
24938
24939         $LFS setstripe -c1 $tf
24940         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
24941
24942         # Get ZFS object id
24943         local zfs_objid=$(zfs_get_objid $facet $tf)
24944         # block size change by sequential overwrite
24945         local bs
24946
24947         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24948                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24949
24950                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
24951                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
24952         done
24953         rm -f $tf
24954
24955         $LFS setstripe -c1 $tf
24956         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24957
24958         # block size change by sequential append write
24959         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24960         zfs_objid=$(zfs_get_objid $facet $tf)
24961         local count
24962
24963         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24964                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24965                         oflag=sync conv=notrunc
24966
24967                 blksz=$(zfs_object_blksz $facet $zfs_objid)
24968                 (( $blksz == 2 * count * PAGE_SIZE )) ||
24969                         error "blksz error, actual $blksz, " \
24970                                 "expected: 2 * $count * $PAGE_SIZE"
24971         done
24972         rm -f $tf
24973
24974         # random write
24975         $LFS setstripe -c1 $tf
24976         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24977         zfs_objid=$(zfs_get_objid $facet $tf)
24978
24979         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24980         blksz=$(zfs_object_blksz $facet $zfs_objid)
24981         (( blksz == PAGE_SIZE )) ||
24982                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24983
24984         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24985         blksz=$(zfs_object_blksz $facet $zfs_objid)
24986         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
24987
24988         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24989         blksz=$(zfs_object_blksz $facet $zfs_objid)
24990         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
24991 }
24992 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24993
24994 test_313() {
24995         remote_ost_nodsh && skip "remote OST with nodsh"
24996
24997         local file=$DIR/$tfile
24998
24999         rm -f $file
25000         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25001
25002         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25003         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25004         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25005                 error "write should failed"
25006         do_facet ost1 "$LCTL set_param fail_loc=0"
25007         rm -f $file
25008 }
25009 run_test 313 "io should fail after last_rcvd update fail"
25010
25011 test_314() {
25012         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25013
25014         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25015         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25016         rm -f $DIR/$tfile
25017         wait_delete_completed
25018         do_facet ost1 "$LCTL set_param fail_loc=0"
25019 }
25020 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25021
25022 test_315() { # LU-618
25023         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25024
25025         local file=$DIR/$tfile
25026         rm -f $file
25027
25028         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25029                 error "multiop file write failed"
25030         $MULTIOP $file oO_RDONLY:r4063232_c &
25031         PID=$!
25032
25033         sleep 2
25034
25035         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25036         kill -USR1 $PID
25037
25038         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25039         rm -f $file
25040 }
25041 run_test 315 "read should be accounted"
25042
25043 test_316() {
25044         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25045         large_xattr_enabled || skip "ea_inode feature disabled"
25046
25047         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25048         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25049         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25050         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25051
25052         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25053 }
25054 run_test 316 "lfs migrate of file with large_xattr enabled"
25055
25056 test_317() {
25057         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25058                 skip "Need MDS version at least 2.11.53"
25059         if [ "$ost1_FSTYPE" == "zfs" ]; then
25060                 skip "LU-10370: no implementation for ZFS"
25061         fi
25062
25063         local trunc_sz
25064         local grant_blk_size
25065
25066         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25067                         awk '/grant_block_size:/ { print $2; exit; }')
25068         #
25069         # Create File of size 5M. Truncate it to below size's and verify
25070         # blocks count.
25071         #
25072         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25073                 error "Create file $DIR/$tfile failed"
25074         stack_trap "rm -f $DIR/$tfile" EXIT
25075
25076         for trunc_sz in 2097152 4097 4000 509 0; do
25077                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25078                         error "truncate $tfile to $trunc_sz failed"
25079                 local sz=$(stat --format=%s $DIR/$tfile)
25080                 local blk=$(stat --format=%b $DIR/$tfile)
25081                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25082                                      grant_blk_size) * 8))
25083
25084                 if [[ $blk -ne $trunc_blk ]]; then
25085                         $(which stat) $DIR/$tfile
25086                         error "Expected Block $trunc_blk got $blk for $tfile"
25087                 fi
25088
25089                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25090                         error "Expected Size $trunc_sz got $sz for $tfile"
25091         done
25092
25093         #
25094         # sparse file test
25095         # Create file with a hole and write actual 65536 bytes which aligned
25096         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25097         #
25098         local bs=65536
25099         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25100                 error "Create file : $DIR/$tfile"
25101
25102         #
25103         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25104         # blocks. The block count must drop to 8.
25105         #
25106         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25107                 ((bs - grant_blk_size) + 1)))
25108         $TRUNCATE $DIR/$tfile $trunc_sz ||
25109                 error "truncate $tfile to $trunc_sz failed"
25110
25111         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25112         sz=$(stat --format=%s $DIR/$tfile)
25113         blk=$(stat --format=%b $DIR/$tfile)
25114
25115         if [[ $blk -ne $trunc_bsz ]]; then
25116                 $(which stat) $DIR/$tfile
25117                 error "Expected Block $trunc_bsz got $blk for $tfile"
25118         fi
25119
25120         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25121                 error "Expected Size $trunc_sz got $sz for $tfile"
25122 }
25123 run_test 317 "Verify blocks get correctly update after truncate"
25124
25125 test_318() {
25126         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25127         local old_max_active=$($LCTL get_param -n \
25128                             ${llite_name}.max_read_ahead_async_active \
25129                             2>/dev/null)
25130
25131         $LCTL set_param llite.*.max_read_ahead_async_active=256
25132         local max_active=$($LCTL get_param -n \
25133                            ${llite_name}.max_read_ahead_async_active \
25134                            2>/dev/null)
25135         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25136
25137         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25138                 error "set max_read_ahead_async_active should succeed"
25139
25140         $LCTL set_param llite.*.max_read_ahead_async_active=512
25141         max_active=$($LCTL get_param -n \
25142                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25143         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25144
25145         # restore @max_active
25146         [ $old_max_active -ne 0 ] && $LCTL set_param \
25147                 llite.*.max_read_ahead_async_active=$old_max_active
25148
25149         local old_threshold=$($LCTL get_param -n \
25150                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25151         local max_per_file_mb=$($LCTL get_param -n \
25152                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25153
25154         local invalid=$(($max_per_file_mb + 1))
25155         $LCTL set_param \
25156                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25157                         && error "set $invalid should fail"
25158
25159         local valid=$(($invalid - 1))
25160         $LCTL set_param \
25161                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25162                         error "set $valid should succeed"
25163         local threshold=$($LCTL get_param -n \
25164                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25165         [ $threshold -eq $valid ] || error \
25166                 "expect threshold $valid got $threshold"
25167         $LCTL set_param \
25168                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25169 }
25170 run_test 318 "Verify async readahead tunables"
25171
25172 test_319() {
25173         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25174
25175         local before=$(date +%s)
25176         local evict
25177         local mdir=$DIR/$tdir
25178         local file=$mdir/xxx
25179
25180         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25181         touch $file
25182
25183 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25184         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25185         $LFS migrate -m1 $mdir &
25186
25187         sleep 1
25188         dd if=$file of=/dev/null
25189         wait
25190         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25191           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25192
25193         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25194 }
25195 run_test 319 "lost lease lock on migrate error"
25196
25197 test_398a() { # LU-4198
25198         local ost1_imp=$(get_osc_import_name client ost1)
25199         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25200                          cut -d'.' -f2)
25201
25202         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25203         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25204
25205         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25206         # request a new lock on client
25207         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25208
25209         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25210         #local lock_count=$($LCTL get_param -n \
25211         #                  ldlm.namespaces.$imp_name.lru_size)
25212         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25213
25214         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25215
25216         # no lock cached, should use lockless DIO and not enqueue new lock
25217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25218                 conv=notrunc ||
25219                 error "dio write failed"
25220         lock_count=$($LCTL get_param -n \
25221                      ldlm.namespaces.$imp_name.lru_size)
25222         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25223
25224         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25225
25226         # no lock cached, should use locked DIO append
25227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25228                 conv=notrunc || error "DIO append failed"
25229         lock_count=$($LCTL get_param -n \
25230                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25231         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25232 }
25233 run_test 398a "direct IO should cancel lock otherwise lockless"
25234
25235 test_398b() { # LU-4198
25236         local before=$(date +%s)
25237         local njobs=4
25238         local size=48
25239
25240         which fio || skip_env "no fio installed"
25241         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25242         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25243
25244         # Single page, multiple pages, stripe size, 4*stripe size
25245         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25246                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25247                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25248                         --numjobs=$njobs --fallocate=none \
25249                         --iodepth=16 --allow_file_create=0 \
25250                         --size=$((size/njobs))M \
25251                         --filename=$DIR/$tfile &
25252                 bg_pid=$!
25253
25254                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25255                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25256                         --numjobs=$njobs --fallocate=none \
25257                         --iodepth=16 --allow_file_create=0 \
25258                         --size=$((size/njobs))M \
25259                         --filename=$DIR/$tfile || true
25260                 wait $bg_pid
25261         done
25262
25263         evict=$(do_facet client $LCTL get_param \
25264                 osc.$FSNAME-OST*-osc-*/state |
25265             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25266
25267         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25268                 (do_facet client $LCTL get_param \
25269                         osc.$FSNAME-OST*-osc-*/state;
25270                     error "eviction happened: $evict before:$before")
25271
25272         rm -f $DIR/$tfile
25273 }
25274 run_test 398b "DIO and buffer IO race"
25275
25276 test_398c() { # LU-4198
25277         local ost1_imp=$(get_osc_import_name client ost1)
25278         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25279                          cut -d'.' -f2)
25280
25281         which fio || skip_env "no fio installed"
25282
25283         saved_debug=$($LCTL get_param -n debug)
25284         $LCTL set_param debug=0
25285
25286         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25287         ((size /= 1024)) # by megabytes
25288         ((size /= 2)) # write half of the OST at most
25289         [ $size -gt 40 ] && size=40 #reduce test time anyway
25290
25291         $LFS setstripe -c 1 $DIR/$tfile
25292
25293         # it seems like ldiskfs reserves more space than necessary if the
25294         # writing blocks are not mapped, so it extends the file firstly
25295         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25296         cancel_lru_locks osc
25297
25298         # clear and verify rpc_stats later
25299         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25300
25301         local njobs=4
25302         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25303         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25304                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25305                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25306                 --filename=$DIR/$tfile
25307         [ $? -eq 0 ] || error "fio write error"
25308
25309         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25310                 error "Locks were requested while doing AIO"
25311
25312         # get the percentage of 1-page I/O
25313         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25314                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25315                 awk '{print $7}')
25316         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25317
25318         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25319         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25320                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25321                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25322                 --filename=$DIR/$tfile
25323         [ $? -eq 0 ] || error "fio mixed read write error"
25324
25325         echo "AIO with large block size ${size}M"
25326         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25327                 --numjobs=1 --fallocate=none --ioengine=libaio \
25328                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25329                 --filename=$DIR/$tfile
25330         [ $? -eq 0 ] || error "fio large block size failed"
25331
25332         rm -f $DIR/$tfile
25333         $LCTL set_param debug="$saved_debug"
25334 }
25335 run_test 398c "run fio to test AIO"
25336
25337 test_398d() { #  LU-13846
25338         which aiocp || skip_env "no aiocp installed"
25339         local aio_file=$DIR/$tfile.aio
25340
25341         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25342
25343         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25344         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25345         stack_trap "rm -f $DIR/$tfile $aio_file"
25346
25347         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25348
25349         # make sure we don't crash and fail properly
25350         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25351                 error "aio not aligned with PAGE SIZE should fail"
25352
25353         rm -f $DIR/$tfile $aio_file
25354 }
25355 run_test 398d "run aiocp to verify block size > stripe size"
25356
25357 test_398e() {
25358         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25359         touch $DIR/$tfile.new
25360         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25361 }
25362 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25363
25364 test_398f() { #  LU-14687
25365         which aiocp || skip_env "no aiocp installed"
25366         local aio_file=$DIR/$tfile.aio
25367
25368         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25369
25370         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25371         stack_trap "rm -f $DIR/$tfile $aio_file"
25372
25373         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25374         $LCTL set_param fail_loc=0x1418
25375         # make sure we don't crash and fail properly
25376         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25377                 error "aio with page allocation failure succeeded"
25378         $LCTL set_param fail_loc=0
25379         diff $DIR/$tfile $aio_file
25380         [[ $? != 0 ]] || error "no diff after failed aiocp"
25381 }
25382 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25383
25384 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25385 # stripe and i/o size must be > stripe size
25386 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25387 # single RPC in flight.  This test shows async DIO submission is working by
25388 # showing multiple RPCs in flight.
25389 test_398g() { #  LU-13798
25390         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25391
25392         # We need to do some i/o first to acquire enough grant to put our RPCs
25393         # in flight; otherwise a new connection may not have enough grant
25394         # available
25395         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25396                 error "parallel dio failed"
25397         stack_trap "rm -f $DIR/$tfile"
25398
25399         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25400         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25401         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25402         stack_trap "$LCTL set_param -n $pages_per_rpc"
25403
25404         # Recreate file so it's empty
25405         rm -f $DIR/$tfile
25406         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25407         #Pause rpc completion to guarantee we see multiple rpcs in flight
25408         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25409         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25410         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25411
25412         # Clear rpc stats
25413         $LCTL set_param osc.*.rpc_stats=c
25414
25415         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25416                 error "parallel dio failed"
25417         stack_trap "rm -f $DIR/$tfile"
25418
25419         $LCTL get_param osc.*-OST0000-*.rpc_stats
25420         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25421                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25422                 grep "8:" | awk '{print $8}')
25423         # We look at the "8 rpcs in flight" field, and verify A) it is present
25424         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25425         # as expected for an 8M DIO to a file with 1M stripes.
25426         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25427
25428         # Verify turning off parallel dio works as expected
25429         # Clear rpc stats
25430         $LCTL set_param osc.*.rpc_stats=c
25431         $LCTL set_param llite.*.parallel_dio=0
25432         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25433
25434         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25435                 error "dio with parallel dio disabled failed"
25436
25437         # Ideally, we would see only one RPC in flight here, but there is an
25438         # unavoidable race between i/o completion and RPC in flight counting,
25439         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25440         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25441         # So instead we just verify it's always < 8.
25442         $LCTL get_param osc.*-OST0000-*.rpc_stats
25443         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25444                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25445                 grep '^$' -B1 | grep . | awk '{print $1}')
25446         [ $ret != "8:" ] ||
25447                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25448 }
25449 run_test 398g "verify parallel dio async RPC submission"
25450
25451 test_398h() { #  LU-13798
25452         local dio_file=$DIR/$tfile.dio
25453
25454         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25455
25456         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25457         stack_trap "rm -f $DIR/$tfile $dio_file"
25458
25459         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25460                 error "parallel dio failed"
25461         diff $DIR/$tfile $dio_file
25462         [[ $? == 0 ]] || error "file diff after aiocp"
25463 }
25464 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25465
25466 test_398i() { #  LU-13798
25467         local dio_file=$DIR/$tfile.dio
25468
25469         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25470
25471         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25472         stack_trap "rm -f $DIR/$tfile $dio_file"
25473
25474         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25475         $LCTL set_param fail_loc=0x1418
25476         # make sure we don't crash and fail properly
25477         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25478                 error "parallel dio page allocation failure succeeded"
25479         diff $DIR/$tfile $dio_file
25480         [[ $? != 0 ]] || error "no diff after failed aiocp"
25481 }
25482 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25483
25484 test_398j() { #  LU-13798
25485         # Stripe size > RPC size but less than i/o size tests split across
25486         # stripes and RPCs for individual i/o op
25487         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25488
25489         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25490         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25491         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25492         stack_trap "$LCTL set_param -n $pages_per_rpc"
25493
25494         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25495                 error "parallel dio write failed"
25496         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25497
25498         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25499                 error "parallel dio read failed"
25500         diff $DIR/$tfile $DIR/$tfile.2
25501         [[ $? == 0 ]] || error "file diff after parallel dio read"
25502 }
25503 run_test 398j "test parallel dio where stripe size > rpc_size"
25504
25505 test_398k() { #  LU-13798
25506         wait_delete_completed
25507         wait_mds_ost_sync
25508
25509         # 4 stripe file; we will cause out of space on OST0
25510         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25511
25512         # Fill OST0 (if it's not too large)
25513         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25514                    head -n1)
25515         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25516                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25517         fi
25518         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25519         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25520                 error "dd should fill OST0"
25521         stack_trap "rm -f $DIR/$tfile.1"
25522
25523         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25524         err=$?
25525
25526         ls -la $DIR/$tfile
25527         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25528                 error "file is not 0 bytes in size"
25529
25530         # dd above should not succeed, but don't error until here so we can
25531         # get debug info above
25532         [[ $err != 0 ]] ||
25533                 error "parallel dio write with enospc succeeded"
25534         stack_trap "rm -f $DIR/$tfile"
25535 }
25536 run_test 398k "test enospc on first stripe"
25537
25538 test_398l() { #  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         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25544         # happens on the second i/o chunk we issue
25545         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25546
25547         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25548         stack_trap "rm -f $DIR/$tfile"
25549
25550         # Fill OST0 (if it's not too large)
25551         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25552                    head -n1)
25553         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25554                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25555         fi
25556         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25557         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25558                 error "dd should fill OST0"
25559         stack_trap "rm -f $DIR/$tfile.1"
25560
25561         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25562         err=$?
25563         stack_trap "rm -f $DIR/$tfile.2"
25564
25565         # Check that short write completed as expected
25566         ls -la $DIR/$tfile.2
25567         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25568                 error "file is not 1M in size"
25569
25570         # dd above should not succeed, but don't error until here so we can
25571         # get debug info above
25572         [[ $err != 0 ]] ||
25573                 error "parallel dio write with enospc succeeded"
25574
25575         # Truncate source file to same length as output file and diff them
25576         $TRUNCATE $DIR/$tfile 1048576
25577         diff $DIR/$tfile $DIR/$tfile.2
25578         [[ $? == 0 ]] || error "data incorrect after short write"
25579 }
25580 run_test 398l "test enospc on intermediate stripe/RPC"
25581
25582 test_398m() { #  LU-13798
25583         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25584
25585         # Set up failure on OST0, the first stripe:
25586         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25587         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25588         # OST0 is on ost1, OST1 is on ost2.
25589         # So this fail_val specifies OST0
25590         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25591         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25592
25593         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25594                 error "parallel dio write with failure on first stripe succeeded"
25595         stack_trap "rm -f $DIR/$tfile"
25596         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25597
25598         # Place data in file for read
25599         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25600                 error "parallel dio write failed"
25601
25602         # Fail read on OST0, first stripe
25603         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25604         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25605         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25606                 error "parallel dio read with error on first stripe succeeded"
25607         rm -f $DIR/$tfile.2
25608         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25609
25610         # Switch to testing on OST1, second stripe
25611         # Clear file contents, maintain striping
25612         echo > $DIR/$tfile
25613         # Set up failure on OST1, second stripe:
25614         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25615         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25616
25617         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25618                 error "parallel dio write with failure on second stripe succeeded"
25619         stack_trap "rm -f $DIR/$tfile"
25620         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25621
25622         # Place data in file for read
25623         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25624                 error "parallel dio write failed"
25625
25626         # Fail read on OST1, second stripe
25627         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25628         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25629         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25630                 error "parallel dio read with error on second stripe succeeded"
25631         rm -f $DIR/$tfile.2
25632         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25633 }
25634 run_test 398m "test RPC failures with parallel dio"
25635
25636 # Parallel submission of DIO should not cause problems for append, but it's
25637 # important to verify.
25638 test_398n() { #  LU-13798
25639         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25640
25641         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25642                 error "dd to create source file failed"
25643         stack_trap "rm -f $DIR/$tfile"
25644
25645         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25646                 error "parallel dio write with failure on second stripe succeeded"
25647         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25648         diff $DIR/$tfile $DIR/$tfile.1
25649         [[ $? == 0 ]] || error "data incorrect after append"
25650
25651 }
25652 run_test 398n "test append with parallel DIO"
25653
25654 test_398o() {
25655         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25656 }
25657 run_test 398o "right kms with DIO"
25658
25659 test_fake_rw() {
25660         local read_write=$1
25661         if [ "$read_write" = "write" ]; then
25662                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25663         elif [ "$read_write" = "read" ]; then
25664                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25665         else
25666                 error "argument error"
25667         fi
25668
25669         # turn off debug for performance testing
25670         local saved_debug=$($LCTL get_param -n debug)
25671         $LCTL set_param debug=0
25672
25673         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25674
25675         # get ost1 size - $FSNAME-OST0000
25676         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25677         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25678         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25679
25680         if [ "$read_write" = "read" ]; then
25681                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25682         fi
25683
25684         local start_time=$(date +%s.%N)
25685         $dd_cmd bs=1M count=$blocks oflag=sync ||
25686                 error "real dd $read_write error"
25687         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25688
25689         if [ "$read_write" = "write" ]; then
25690                 rm -f $DIR/$tfile
25691         fi
25692
25693         # define OBD_FAIL_OST_FAKE_RW           0x238
25694         do_facet ost1 $LCTL set_param fail_loc=0x238
25695
25696         local start_time=$(date +%s.%N)
25697         $dd_cmd bs=1M count=$blocks oflag=sync ||
25698                 error "fake dd $read_write error"
25699         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25700
25701         if [ "$read_write" = "write" ]; then
25702                 # verify file size
25703                 cancel_lru_locks osc
25704                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25705                         error "$tfile size not $blocks MB"
25706         fi
25707         do_facet ost1 $LCTL set_param fail_loc=0
25708
25709         echo "fake $read_write $duration_fake vs. normal $read_write" \
25710                 "$duration in seconds"
25711         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25712                 error_not_in_vm "fake write is slower"
25713
25714         $LCTL set_param -n debug="$saved_debug"
25715         rm -f $DIR/$tfile
25716 }
25717 test_399a() { # LU-7655 for OST fake write
25718         remote_ost_nodsh && skip "remote OST with nodsh"
25719
25720         test_fake_rw write
25721 }
25722 run_test 399a "fake write should not be slower than normal write"
25723
25724 test_399b() { # LU-8726 for OST fake read
25725         remote_ost_nodsh && skip "remote OST with nodsh"
25726         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25727                 skip_env "ldiskfs only test"
25728         fi
25729
25730         test_fake_rw read
25731 }
25732 run_test 399b "fake read should not be slower than normal read"
25733
25734 test_400a() { # LU-1606, was conf-sanity test_74
25735         if ! which $CC > /dev/null 2>&1; then
25736                 skip_env "$CC is not installed"
25737         fi
25738
25739         local extra_flags=''
25740         local out=$TMP/$tfile
25741         local prefix=/usr/include/lustre
25742         local prog
25743
25744         # Oleg removes .c files in his test rig so test if any c files exist
25745         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25746                 skip_env "Needed .c test files are missing"
25747
25748         if ! [[ -d $prefix ]]; then
25749                 # Assume we're running in tree and fixup the include path.
25750                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25751                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25752                 extra_flags+=" -L$LUSTRE/utils/.libs"
25753         fi
25754
25755         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25756                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25757                         error "client api broken"
25758         done
25759         rm -f $out
25760 }
25761 run_test 400a "Lustre client api program can compile and link"
25762
25763 test_400b() { # LU-1606, LU-5011
25764         local header
25765         local out=$TMP/$tfile
25766         local prefix=/usr/include/linux/lustre
25767
25768         # We use a hard coded prefix so that this test will not fail
25769         # when run in tree. There are headers in lustre/include/lustre/
25770         # that are not packaged (like lustre_idl.h) and have more
25771         # complicated include dependencies (like config.h and lnet/types.h).
25772         # Since this test about correct packaging we just skip them when
25773         # they don't exist (see below) rather than try to fixup cppflags.
25774
25775         if ! which $CC > /dev/null 2>&1; then
25776                 skip_env "$CC is not installed"
25777         fi
25778
25779         for header in $prefix/*.h; do
25780                 if ! [[ -f "$header" ]]; then
25781                         continue
25782                 fi
25783
25784                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25785                         continue # lustre_ioctl.h is internal header
25786                 fi
25787
25788                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25789                         error "cannot compile '$header'"
25790         done
25791         rm -f $out
25792 }
25793 run_test 400b "packaged headers can be compiled"
25794
25795 test_401a() { #LU-7437
25796         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25797         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25798
25799         #count the number of parameters by "list_param -R"
25800         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25801         #count the number of parameters by listing proc files
25802         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25803         echo "proc_dirs='$proc_dirs'"
25804         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25805         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25806                       sort -u | wc -l)
25807
25808         [ $params -eq $procs ] ||
25809                 error "found $params parameters vs. $procs proc files"
25810
25811         # test the list_param -D option only returns directories
25812         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25813         #count the number of parameters by listing proc directories
25814         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25815                 sort -u | wc -l)
25816
25817         [ $params -eq $procs ] ||
25818                 error "found $params parameters vs. $procs proc files"
25819 }
25820 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25821
25822 test_401b() {
25823         # jobid_var may not allow arbitrary values, so use jobid_name
25824         # if available
25825         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25826                 local testname=jobid_name tmp='testing%p'
25827         else
25828                 local testname=jobid_var tmp=testing
25829         fi
25830
25831         local save=$($LCTL get_param -n $testname)
25832
25833         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25834                 error "no error returned when setting bad parameters"
25835
25836         local jobid_new=$($LCTL get_param -n foe $testname baz)
25837         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25838
25839         $LCTL set_param -n fog=bam $testname=$save bat=fog
25840         local jobid_old=$($LCTL get_param -n foe $testname bag)
25841         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25842 }
25843 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25844
25845 test_401c() {
25846         # jobid_var may not allow arbitrary values, so use jobid_name
25847         # if available
25848         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25849                 local testname=jobid_name
25850         else
25851                 local testname=jobid_var
25852         fi
25853
25854         local jobid_var_old=$($LCTL get_param -n $testname)
25855         local jobid_var_new
25856
25857         $LCTL set_param $testname= &&
25858                 error "no error returned for 'set_param a='"
25859
25860         jobid_var_new=$($LCTL get_param -n $testname)
25861         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25862                 error "$testname was changed by setting without value"
25863
25864         $LCTL set_param $testname &&
25865                 error "no error returned for 'set_param a'"
25866
25867         jobid_var_new=$($LCTL get_param -n $testname)
25868         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25869                 error "$testname was changed by setting without value"
25870 }
25871 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25872
25873 test_401d() {
25874         # jobid_var may not allow arbitrary values, so use jobid_name
25875         # if available
25876         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25877                 local testname=jobid_name new_value='foo=bar%p'
25878         else
25879                 local testname=jobid_var new_valuie=foo=bar
25880         fi
25881
25882         local jobid_var_old=$($LCTL get_param -n $testname)
25883         local jobid_var_new
25884
25885         $LCTL set_param $testname=$new_value ||
25886                 error "'set_param a=b' did not accept a value containing '='"
25887
25888         jobid_var_new=$($LCTL get_param -n $testname)
25889         [[ "$jobid_var_new" == "$new_value" ]] ||
25890                 error "'set_param a=b' failed on a value containing '='"
25891
25892         # Reset the $testname to test the other format
25893         $LCTL set_param $testname=$jobid_var_old
25894         jobid_var_new=$($LCTL get_param -n $testname)
25895         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25896                 error "failed to reset $testname"
25897
25898         $LCTL set_param $testname $new_value ||
25899                 error "'set_param a b' did not accept a value containing '='"
25900
25901         jobid_var_new=$($LCTL get_param -n $testname)
25902         [[ "$jobid_var_new" == "$new_value" ]] ||
25903                 error "'set_param a b' failed on a value containing '='"
25904
25905         $LCTL set_param $testname $jobid_var_old
25906         jobid_var_new=$($LCTL get_param -n $testname)
25907         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25908                 error "failed to reset $testname"
25909 }
25910 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25911
25912 test_401e() { # LU-14779
25913         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25914                 error "lctl list_param MGC* failed"
25915         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25916         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25917                 error "lctl get_param lru_size failed"
25918 }
25919 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25920
25921 test_402() {
25922         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25923         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25924                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25925         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25926                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25927                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25928         remote_mds_nodsh && skip "remote MDS with nodsh"
25929
25930         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25931 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25932         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25933         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25934                 echo "Touch failed - OK"
25935 }
25936 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25937
25938 test_403() {
25939         local file1=$DIR/$tfile.1
25940         local file2=$DIR/$tfile.2
25941         local tfile=$TMP/$tfile
25942
25943         rm -f $file1 $file2 $tfile
25944
25945         touch $file1
25946         ln $file1 $file2
25947
25948         # 30 sec OBD_TIMEOUT in ll_getattr()
25949         # right before populating st_nlink
25950         $LCTL set_param fail_loc=0x80001409
25951         stat -c %h $file1 > $tfile &
25952
25953         # create an alias, drop all locks and reclaim the dentry
25954         < $file2
25955         cancel_lru_locks mdc
25956         cancel_lru_locks osc
25957         sysctl -w vm.drop_caches=2
25958
25959         wait
25960
25961         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25962
25963         rm -f $tfile $file1 $file2
25964 }
25965 run_test 403 "i_nlink should not drop to zero due to aliasing"
25966
25967 test_404() { # LU-6601
25968         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25969                 skip "Need server version newer than 2.8.52"
25970         remote_mds_nodsh && skip "remote MDS with nodsh"
25971
25972         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25973                 awk '/osp .*-osc-MDT/ { print $4}')
25974
25975         local osp
25976         for osp in $mosps; do
25977                 echo "Deactivate: " $osp
25978                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25979                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25980                         awk -vp=$osp '$4 == p { print $2 }')
25981                 [ $stat = IN ] || {
25982                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25983                         error "deactivate error"
25984                 }
25985                 echo "Activate: " $osp
25986                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25987                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25988                         awk -vp=$osp '$4 == p { print $2 }')
25989                 [ $stat = UP ] || {
25990                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25991                         error "activate error"
25992                 }
25993         done
25994 }
25995 run_test 404 "validate manual {de}activated works properly for OSPs"
25996
25997 test_405() {
25998         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25999         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26000                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26001                         skip "Layout swap lock is not supported"
26002
26003         check_swap_layouts_support
26004         check_swap_layout_no_dom $DIR
26005
26006         test_mkdir $DIR/$tdir
26007         swap_lock_test -d $DIR/$tdir ||
26008                 error "One layout swap locked test failed"
26009 }
26010 run_test 405 "Various layout swap lock tests"
26011
26012 test_406() {
26013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26014         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26015         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26017         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26018                 skip "Need MDS version at least 2.8.50"
26019
26020         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26021         local test_pool=$TESTNAME
26022
26023         pool_add $test_pool || error "pool_add failed"
26024         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26025                 error "pool_add_targets failed"
26026
26027         save_layout_restore_at_exit $MOUNT
26028
26029         # parent set default stripe count only, child will stripe from both
26030         # parent and fs default
26031         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26032                 error "setstripe $MOUNT failed"
26033         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26034         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26035         for i in $(seq 10); do
26036                 local f=$DIR/$tdir/$tfile.$i
26037                 touch $f || error "touch failed"
26038                 local count=$($LFS getstripe -c $f)
26039                 [ $count -eq $OSTCOUNT ] ||
26040                         error "$f stripe count $count != $OSTCOUNT"
26041                 local offset=$($LFS getstripe -i $f)
26042                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26043                 local size=$($LFS getstripe -S $f)
26044                 [ $size -eq $((def_stripe_size * 2)) ] ||
26045                         error "$f stripe size $size != $((def_stripe_size * 2))"
26046                 local pool=$($LFS getstripe -p $f)
26047                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26048         done
26049
26050         # change fs default striping, delete parent default striping, now child
26051         # will stripe from new fs default striping only
26052         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26053                 error "change $MOUNT default stripe failed"
26054         $LFS setstripe -c 0 $DIR/$tdir ||
26055                 error "delete $tdir default stripe failed"
26056         for i in $(seq 11 20); do
26057                 local f=$DIR/$tdir/$tfile.$i
26058                 touch $f || error "touch $f failed"
26059                 local count=$($LFS getstripe -c $f)
26060                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26061                 local offset=$($LFS getstripe -i $f)
26062                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26063                 local size=$($LFS getstripe -S $f)
26064                 [ $size -eq $def_stripe_size ] ||
26065                         error "$f stripe size $size != $def_stripe_size"
26066                 local pool=$($LFS getstripe -p $f)
26067                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26068         done
26069
26070         unlinkmany $DIR/$tdir/$tfile. 1 20
26071
26072         local f=$DIR/$tdir/$tfile
26073         pool_remove_all_targets $test_pool $f
26074         pool_remove $test_pool $f
26075 }
26076 run_test 406 "DNE support fs default striping"
26077
26078 test_407() {
26079         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26080         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26081                 skip "Need MDS version at least 2.8.55"
26082         remote_mds_nodsh && skip "remote MDS with nodsh"
26083
26084         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26085                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26086         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26087                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26088         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26089
26090         #define OBD_FAIL_DT_TXN_STOP    0x2019
26091         for idx in $(seq $MDSCOUNT); do
26092                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26093         done
26094         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26095         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26096                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26097         true
26098 }
26099 run_test 407 "transaction fail should cause operation fail"
26100
26101 test_408() {
26102         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26103
26104         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26105         lctl set_param fail_loc=0x8000040a
26106         # let ll_prepare_partial_page() fail
26107         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26108
26109         rm -f $DIR/$tfile
26110
26111         # create at least 100 unused inodes so that
26112         # shrink_icache_memory(0) should not return 0
26113         touch $DIR/$tfile-{0..100}
26114         rm -f $DIR/$tfile-{0..100}
26115         sync
26116
26117         echo 2 > /proc/sys/vm/drop_caches
26118 }
26119 run_test 408 "drop_caches should not hang due to page leaks"
26120
26121 test_409()
26122 {
26123         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26124
26125         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26126         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26127         touch $DIR/$tdir/guard || error "(2) Fail to create"
26128
26129         local PREFIX=$(str_repeat 'A' 128)
26130         echo "Create 1K hard links start at $(date)"
26131         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26132                 error "(3) Fail to hard link"
26133
26134         echo "Links count should be right although linkEA overflow"
26135         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26136         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26137         [ $linkcount -eq 1001 ] ||
26138                 error "(5) Unexpected hard links count: $linkcount"
26139
26140         echo "List all links start at $(date)"
26141         ls -l $DIR/$tdir/foo > /dev/null ||
26142                 error "(6) Fail to list $DIR/$tdir/foo"
26143
26144         echo "Unlink hard links start at $(date)"
26145         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26146                 error "(7) Fail to unlink"
26147         echo "Unlink hard links finished at $(date)"
26148 }
26149 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26150
26151 test_410()
26152 {
26153         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26154                 skip "Need client version at least 2.9.59"
26155         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26156                 skip "Need MODULES build"
26157
26158         # Create a file, and stat it from the kernel
26159         local testfile=$DIR/$tfile
26160         touch $testfile
26161
26162         local run_id=$RANDOM
26163         local my_ino=$(stat --format "%i" $testfile)
26164
26165         # Try to insert the module. This will always fail as the
26166         # module is designed to not be inserted.
26167         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26168             &> /dev/null
26169
26170         # Anything but success is a test failure
26171         dmesg | grep -q \
26172             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26173             error "no inode match"
26174 }
26175 run_test 410 "Test inode number returned from kernel thread"
26176
26177 cleanup_test411_cgroup() {
26178         trap 0
26179         rmdir "$1"
26180 }
26181
26182 test_411() {
26183         local cg_basedir=/sys/fs/cgroup/memory
26184         # LU-9966
26185         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26186                 skip "no setup for cgroup"
26187
26188         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26189                 error "test file creation failed"
26190         cancel_lru_locks osc
26191
26192         # Create a very small memory cgroup to force a slab allocation error
26193         local cgdir=$cg_basedir/osc_slab_alloc
26194         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26195         trap "cleanup_test411_cgroup $cgdir" EXIT
26196         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26197         echo 1M > $cgdir/memory.limit_in_bytes
26198
26199         # Should not LBUG, just be killed by oom-killer
26200         # dd will return 0 even allocation failure in some environment.
26201         # So don't check return value
26202         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26203         cleanup_test411_cgroup $cgdir
26204
26205         return 0
26206 }
26207 run_test 411 "Slab allocation error with cgroup does not LBUG"
26208
26209 test_412() {
26210         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26211         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26212                 skip "Need server version at least 2.10.55"
26213
26214         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26215                 error "mkdir failed"
26216         $LFS getdirstripe $DIR/$tdir
26217         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26218         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26219                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26220         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26221         [ $stripe_count -eq 2 ] ||
26222                 error "expect 2 get $stripe_count"
26223
26224         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26225
26226         local index
26227         local index2
26228
26229         # subdirs should be on the same MDT as parent
26230         for i in $(seq 0 $((MDSCOUNT - 1))); do
26231                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26232                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26233                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26234                 (( index == i )) || error "mdt$i/sub on MDT$index"
26235         done
26236
26237         # stripe offset -1, ditto
26238         for i in {1..10}; do
26239                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26240                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26241                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26242                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26243                 (( index == index2 )) ||
26244                         error "qos$i on MDT$index, sub on MDT$index2"
26245         done
26246
26247         local testdir=$DIR/$tdir/inherit
26248
26249         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26250         # inherit 2 levels
26251         for i in 1 2; do
26252                 testdir=$testdir/s$i
26253                 mkdir $testdir || error "mkdir $testdir failed"
26254                 index=$($LFS getstripe -m $testdir)
26255                 (( index == 1 )) ||
26256                         error "$testdir on MDT$index"
26257         done
26258
26259         # not inherit any more
26260         testdir=$testdir/s3
26261         mkdir $testdir || error "mkdir $testdir failed"
26262         getfattr -d -m dmv $testdir | grep dmv &&
26263                 error "default LMV set on $testdir" || true
26264 }
26265 run_test 412 "mkdir on specific MDTs"
26266
26267 TEST413_COUNT=${TEST413_COUNT:-200}
26268 generate_uneven_mdts() {
26269         local threshold=$1
26270         local lmv_qos_maxage
26271         local lod_qos_maxage
26272         local ffree
26273         local bavail
26274         local max
26275         local min
26276         local max_index
26277         local min_index
26278         local tmp
26279         local i
26280
26281         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26282         $LCTL set_param lmv.*.qos_maxage=1
26283         stack_trap "$LCTL set_param \
26284                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26285         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26286                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26287         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26288                 lod.*.mdt_qos_maxage=1
26289         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26290                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26291
26292         echo
26293         echo "Check for uneven MDTs: "
26294
26295         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26296         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26297         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26298
26299         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26300         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26301         max_index=0
26302         min_index=0
26303         for ((i = 1; i < ${#ffree[@]}; i++)); do
26304                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26305                 if [ $tmp -gt $max ]; then
26306                         max=$tmp
26307                         max_index=$i
26308                 fi
26309                 if [ $tmp -lt $min ]; then
26310                         min=$tmp
26311                         min_index=$i
26312                 fi
26313         done
26314
26315         (( ${ffree[min_index]} > 0 )) ||
26316                 skip "no free files in MDT$min_index"
26317         (( ${ffree[min_index]} < 10000000 )) ||
26318                 skip "too many free files in MDT$min_index"
26319
26320         # Check if we need to generate uneven MDTs
26321         local diff=$(((max - min) * 100 / min))
26322         local testdir=$DIR/$tdir-fillmdt
26323         local start
26324
26325         i=0
26326         while (( diff < threshold )); do
26327                 mkdir -p $testdir
26328                 # generate uneven MDTs, create till $threshold% diff
26329                 echo -n "weight diff=$diff% must be > $threshold% ..."
26330                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26331                 testdir=$DIR/$tdir-fillmdt/$i
26332                 [ -d $testdir ] && continue
26333                 $LFS mkdir -i $min_index $testdir ||
26334                         error "mkdir $testdir failed"
26335                 $LFS setstripe -E 1M -L mdt $testdir ||
26336                         error "setstripe $testdir failed"
26337                 start=$SECONDS
26338                 for ((F=0; F < TEST413_COUNT; F++)); do
26339                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26340                                 /dev/null 2>&1 || error "dd $F failed"
26341                 done
26342                 sync; sleep 1; sync
26343
26344                 # wait for QOS to update
26345                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26346
26347                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26348                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26349                 max=$(((${ffree[max_index]} >> 8) *
26350                         (${bavail[max_index]} * bsize >> 16)))
26351                 min=$(((${ffree[min_index]} >> 8) *
26352                         (${bavail[min_index]} * bsize >> 16)))
26353                 diff=$(((max - min) * 100 / min))
26354                 i=$((i + 1))
26355         done
26356
26357         echo "MDT filesfree available: ${ffree[*]}"
26358         echo "MDT blocks available: ${bavail[*]}"
26359         echo "weight diff=$diff%"
26360 }
26361
26362 test_qos_mkdir() {
26363         local mkdir_cmd=$1
26364         local stripe_count=$2
26365         local mdts=$(comma_list $(mdts_nodes))
26366
26367         local testdir
26368         local lmv_qos_prio_free
26369         local lmv_qos_threshold_rr
26370         local lmv_qos_maxage
26371         local lod_qos_prio_free
26372         local lod_qos_threshold_rr
26373         local lod_qos_maxage
26374         local count
26375         local i
26376
26377         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26378         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26379         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26380                 head -n1)
26381         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26382         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26383         stack_trap "$LCTL set_param \
26384                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26385         stack_trap "$LCTL set_param \
26386                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26387         stack_trap "$LCTL set_param \
26388                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26389
26390         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26391                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26392         lod_qos_prio_free=${lod_qos_prio_free%%%}
26393         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26394                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26395         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26396         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26397                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26398         stack_trap "do_nodes $mdts $LCTL set_param \
26399                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26400         stack_trap "do_nodes $mdts $LCTL set_param \
26401                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26402         stack_trap "do_nodes $mdts $LCTL set_param \
26403                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26404
26405         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26406         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26407
26408         testdir=$DIR/$tdir-s$stripe_count/rr
26409
26410         local stripe_index=$($LFS getstripe -m $testdir)
26411         local test_mkdir_rr=true
26412
26413         getfattr -d -m dmv -e hex $testdir | grep dmv
26414         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26415                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26416                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26417                         test_mkdir_rr=false
26418         fi
26419
26420         echo
26421         $test_mkdir_rr &&
26422                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26423                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26424
26425         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26426         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26427                 eval $mkdir_cmd $testdir/subdir$i ||
26428                         error "$mkdir_cmd subdir$i failed"
26429         done
26430
26431         for (( i = 0; i < $MDSCOUNT; i++ )); do
26432                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26433                 echo "$count directories created on MDT$i"
26434                 if $test_mkdir_rr; then
26435                         (( $count == 100 )) ||
26436                                 error "subdirs are not evenly distributed"
26437                 elif (( $i == $stripe_index )); then
26438                         (( $count == 100 * MDSCOUNT )) ||
26439                                 error "$count subdirs created on MDT$i"
26440                 else
26441                         (( $count == 0 )) ||
26442                                 error "$count subdirs created on MDT$i"
26443                 fi
26444
26445                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26446                         count=$($LFS getdirstripe $testdir/* |
26447                                 grep -c -P "^\s+$i\t")
26448                         echo "$count stripes created on MDT$i"
26449                         # deviation should < 5% of average
26450                         (( $count >= 95 * stripe_count &&
26451                            $count <= 105 * stripe_count)) ||
26452                                 error "stripes are not evenly distributed"
26453                 fi
26454         done
26455
26456         echo
26457         echo "Check for uneven MDTs: "
26458
26459         local ffree
26460         local bavail
26461         local max
26462         local min
26463         local max_index
26464         local min_index
26465         local tmp
26466
26467         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26468         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26469         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26470
26471         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26472         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26473         max_index=0
26474         min_index=0
26475         for ((i = 1; i < ${#ffree[@]}; i++)); do
26476                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26477                 if [ $tmp -gt $max ]; then
26478                         max=$tmp
26479                         max_index=$i
26480                 fi
26481                 if [ $tmp -lt $min ]; then
26482                         min=$tmp
26483                         min_index=$i
26484                 fi
26485         done
26486
26487         (( ${ffree[min_index]} > 0 )) ||
26488                 skip "no free files in MDT$min_index"
26489         (( ${ffree[min_index]} < 10000000 )) ||
26490                 skip "too many free files in MDT$min_index"
26491
26492         echo "MDT filesfree available: ${ffree[*]}"
26493         echo "MDT blocks available: ${bavail[*]}"
26494         echo "weight diff=$(((max - min) * 100 / min))%"
26495         echo
26496         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26497
26498         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26499         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26500         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26501         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26502         # decrease statfs age, so that it can be updated in time
26503         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26504         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26505
26506         sleep 1
26507
26508         testdir=$DIR/$tdir-s$stripe_count/qos
26509         local num=200
26510
26511         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26512         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26513                 eval $mkdir_cmd $testdir/subdir$i ||
26514                         error "$mkdir_cmd subdir$i failed"
26515         done
26516
26517         max=0
26518         for (( i = 0; i < $MDSCOUNT; i++ )); do
26519                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26520                 (( count > max )) && max=$count
26521                 echo "$count directories created on MDT$i"
26522         done
26523
26524         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26525
26526         # D-value should > 10% of averge
26527         (( max - min > num / 10 )) ||
26528                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26529
26530         # ditto for stripes
26531         if (( stripe_count > 1 )); then
26532                 max=0
26533                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26534                         count=$($LFS getdirstripe $testdir/* |
26535                                 grep -c -P "^\s+$i\t")
26536                         (( count > max )) && max=$count
26537                         echo "$count stripes created on MDT$i"
26538                 done
26539
26540                 min=$($LFS getdirstripe $testdir/* |
26541                         grep -c -P "^\s+$min_index\t")
26542                 (( max - min > num * stripe_count / 10 )) ||
26543                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26544         fi
26545 }
26546
26547 most_full_mdt() {
26548         local ffree
26549         local bavail
26550         local bsize
26551         local min
26552         local min_index
26553         local tmp
26554
26555         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26556         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26557         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26558
26559         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26560         min_index=0
26561         for ((i = 1; i < ${#ffree[@]}; i++)); do
26562                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26563                 (( tmp < min )) && min=$tmp && min_index=$i
26564         done
26565
26566         echo -n $min_index
26567 }
26568
26569 test_413a() {
26570         [ $MDSCOUNT -lt 2 ] &&
26571                 skip "We need at least 2 MDTs for this test"
26572
26573         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26574                 skip "Need server version at least 2.12.52"
26575
26576         local stripe_count
26577
26578         generate_uneven_mdts 100
26579         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26580                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26581                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26582                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26583                         error "mkdir failed"
26584                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26585         done
26586 }
26587 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26588
26589 test_413b() {
26590         [ $MDSCOUNT -lt 2 ] &&
26591                 skip "We need at least 2 MDTs for this test"
26592
26593         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26594                 skip "Need server version at least 2.12.52"
26595
26596         local testdir
26597         local stripe_count
26598
26599         generate_uneven_mdts 100
26600         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26601                 testdir=$DIR/$tdir-s$stripe_count
26602                 mkdir $testdir || error "mkdir $testdir failed"
26603                 mkdir $testdir/rr || error "mkdir rr failed"
26604                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26605                         error "mkdir qos failed"
26606                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26607                         $testdir/rr || error "setdirstripe rr failed"
26608                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26609                         error "setdirstripe failed"
26610                 test_qos_mkdir "mkdir" $stripe_count
26611         done
26612 }
26613 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26614
26615 test_413c() {
26616         (( $MDSCOUNT >= 2 )) ||
26617                 skip "We need at least 2 MDTs for this test"
26618
26619         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26620                 skip "Need server version at least 2.14.51"
26621
26622         local testdir
26623         local inherit
26624         local inherit_rr
26625
26626         testdir=$DIR/${tdir}-s1
26627         mkdir $testdir || error "mkdir $testdir failed"
26628         mkdir $testdir/rr || error "mkdir rr failed"
26629         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26630         # default max_inherit is -1, default max_inherit_rr is 0
26631         $LFS setdirstripe -D -c 1 $testdir/rr ||
26632                 error "setdirstripe rr failed"
26633         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26634                 error "setdirstripe qos failed"
26635         test_qos_mkdir "mkdir" 1
26636
26637         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26638         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26639         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26640         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26641         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26642
26643         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26644         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26645         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26646         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26647         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26648         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26649         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26650                 error "level2 shouldn't have default LMV" || true
26651 }
26652 run_test 413c "mkdir with default LMV max inherit rr"
26653
26654 test_413d() {
26655         (( MDSCOUNT >= 2 )) ||
26656                 skip "We need at least 2 MDTs for this test"
26657
26658         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26659                 skip "Need server version at least 2.14.51"
26660
26661         local lmv_qos_threshold_rr
26662
26663         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26664                 head -n1)
26665         stack_trap "$LCTL set_param \
26666                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26667
26668         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26669         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26670         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26671                 error "$tdir shouldn't have default LMV"
26672         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26673                 error "mkdir sub failed"
26674
26675         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26676
26677         (( count == 100 )) || error "$count subdirs on MDT0"
26678 }
26679 run_test 413d "inherit ROOT default LMV"
26680
26681 test_413e() {
26682         (( MDSCOUNT >= 2 )) ||
26683                 skip "We need at least 2 MDTs for this test"
26684         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26685                 skip "Need server version at least 2.14.55"
26686
26687         local testdir=$DIR/$tdir
26688         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26689         local max_inherit
26690         local sub_max_inherit
26691
26692         mkdir -p $testdir || error "failed to create $testdir"
26693
26694         # set default max-inherit to -1 if stripe count is 0 or 1
26695         $LFS setdirstripe -D -c 1 $testdir ||
26696                 error "failed to set default LMV"
26697         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26698         (( max_inherit == -1 )) ||
26699                 error "wrong max_inherit value $max_inherit"
26700
26701         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26702         $LFS setdirstripe -D -c -1 $testdir ||
26703                 error "failed to set default LMV"
26704         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26705         (( max_inherit > 0 )) ||
26706                 error "wrong max_inherit value $max_inherit"
26707
26708         # and the subdir will decrease the max_inherit by 1
26709         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26710         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26711         (( sub_max_inherit == max_inherit - 1)) ||
26712                 error "wrong max-inherit of subdir $sub_max_inherit"
26713
26714         # check specified --max-inherit and warning message
26715         stack_trap "rm -f $tmpfile"
26716         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26717                 error "failed to set default LMV"
26718         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26719         (( max_inherit == -1 )) ||
26720                 error "wrong max_inherit value $max_inherit"
26721
26722         # check the warning messages
26723         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26724                 error "failed to detect warning string"
26725         fi
26726 }
26727 run_test 413e "check default max-inherit value"
26728
26729 test_fs_dmv_inherit()
26730 {
26731         local testdir=$DIR/$tdir
26732
26733         local count
26734         local inherit
26735         local inherit_rr
26736
26737         for i in 1 2 3; do
26738                 mkdir $testdir || error "mkdir $testdir failed"
26739                 count=$($LFS getdirstripe -D -c $testdir)
26740                 (( count == 1 )) ||
26741                         error "$testdir default LMV count mismatch $count != 1"
26742                 inherit=$($LFS getdirstripe -D -X $testdir)
26743                 (( inherit == 3 - i )) ||
26744                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26745                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26746                 (( inherit_rr == 3 - i )) ||
26747                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26748                 testdir=$testdir/sub
26749         done
26750
26751         mkdir $testdir || error "mkdir $testdir failed"
26752         count=$($LFS getdirstripe -D -c $testdir)
26753         (( count == 0 )) ||
26754                 error "$testdir default LMV count not zero: $count"
26755 }
26756
26757 test_413f() {
26758         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26759
26760         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26761                 skip "Need server version at least 2.14.55"
26762
26763         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26764                 error "dump $DIR default LMV failed"
26765         stack_trap "setfattr --restore=$TMP/dmv.ea"
26766
26767         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26768                 error "set $DIR default LMV failed"
26769
26770         test_fs_dmv_inherit
26771 }
26772 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26773
26774 test_413g() {
26775         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26776
26777         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26778         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26779                 error "dump $DIR default LMV failed"
26780         stack_trap "setfattr --restore=$TMP/dmv.ea"
26781
26782         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26783                 error "set $DIR default LMV failed"
26784
26785         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26786                 error "mount $MOUNT2 failed"
26787         stack_trap "umount_client $MOUNT2"
26788
26789         local saved_DIR=$DIR
26790
26791         export DIR=$MOUNT2
26792
26793         stack_trap "export DIR=$saved_DIR"
26794
26795         # first check filesystem-wide default LMV inheritance
26796         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26797
26798         # then check subdirs are spread to all MDTs
26799         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26800
26801         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26802
26803         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26804 }
26805 run_test 413g "enforce ROOT default LMV on subdir mount"
26806
26807 test_413h() {
26808         (( MDSCOUNT >= 2 )) ||
26809                 skip "We need at least 2 MDTs for this test"
26810
26811         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26812                 skip "Need server version at least 2.15.50.6"
26813
26814         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26815
26816         stack_trap "$LCTL set_param \
26817                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26818         $LCTL set_param lmv.*.qos_maxage=1
26819
26820         local depth=5
26821         local rr_depth=4
26822         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26823         local count=$((MDSCOUNT * 20))
26824
26825         generate_uneven_mdts 50
26826
26827         mkdir -p $dir || error "mkdir $dir failed"
26828         stack_trap "rm -rf $dir"
26829         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26830                 --max-inherit-rr=$rr_depth $dir
26831
26832         for ((d=0; d < depth + 2; d++)); do
26833                 log "dir=$dir:"
26834                 for ((sub=0; sub < count; sub++)); do
26835                         mkdir $dir/d$sub
26836                 done
26837                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26838                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26839                 # subdirs within $rr_depth should be created round-robin
26840                 if (( d < rr_depth )); then
26841                         (( ${num[0]} != count )) ||
26842                                 error "all objects created on MDT ${num[1]}"
26843                 fi
26844
26845                 dir=$dir/d0
26846         done
26847 }
26848 run_test 413h "don't stick to parent for round-robin dirs"
26849
26850 test_413z() {
26851         local pids=""
26852         local subdir
26853         local pid
26854
26855         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26856                 unlinkmany $subdir/f. $TEST413_COUNT &
26857                 pids="$pids $!"
26858         done
26859
26860         for pid in $pids; do
26861                 wait $pid
26862         done
26863 }
26864 run_test 413z "413 test cleanup"
26865
26866 test_414() {
26867 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26868         $LCTL set_param fail_loc=0x80000521
26869         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26870         rm -f $DIR/$tfile
26871 }
26872 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26873
26874 test_415() {
26875         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26876         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
26877                 skip "Need server version at least 2.11.52"
26878
26879         # LU-11102
26880         local total=500
26881         local max=120
26882
26883         # this test may be slow on ZFS
26884         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
26885
26886         # though this test is designed for striped directory, let's test normal
26887         # directory too since lock is always saved as CoS lock.
26888         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26889         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26890         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
26891         # if looping with ONLY_REPEAT, wait for previous deletions to finish
26892         wait_delete_completed_mds
26893
26894         # run a loop without concurrent touch to measure rename duration.
26895         # only for test debug/robustness, NOT part of COS functional test.
26896         local start_time=$SECONDS
26897         for ((i = 0; i < total; i++)); do
26898                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26899                         > /dev/null
26900         done
26901         local baseline=$((SECONDS - start_time))
26902         echo "rename $total files without 'touch' took $baseline sec"
26903
26904         (
26905                 while true; do
26906                         touch $DIR/$tdir
26907                 done
26908         ) &
26909         local setattr_pid=$!
26910
26911         # rename files back to original name so unlinkmany works
26912         start_time=$SECONDS
26913         for ((i = 0; i < total; i++)); do
26914                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
26915                         > /dev/null
26916         done
26917         local duration=$((SECONDS - start_time))
26918
26919         kill -9 $setattr_pid
26920
26921         echo "rename $total files with 'touch' took $duration sec"
26922         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
26923         (( duration <= max )) || error "rename took $duration > $max sec"
26924 }
26925 run_test 415 "lock revoke is not missing"
26926
26927 test_416() {
26928         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26929                 skip "Need server version at least 2.11.55"
26930
26931         # define OBD_FAIL_OSD_TXN_START    0x19a
26932         do_facet mds1 lctl set_param fail_loc=0x19a
26933
26934         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26935
26936         true
26937 }
26938 run_test 416 "transaction start failure won't cause system hung"
26939
26940 cleanup_417() {
26941         trap 0
26942         do_nodes $(comma_list $(mdts_nodes)) \
26943                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26944         do_nodes $(comma_list $(mdts_nodes)) \
26945                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26946         do_nodes $(comma_list $(mdts_nodes)) \
26947                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26948 }
26949
26950 test_417() {
26951         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26952         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26953                 skip "Need MDS version at least 2.11.56"
26954
26955         trap cleanup_417 RETURN EXIT
26956
26957         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26958         do_nodes $(comma_list $(mdts_nodes)) \
26959                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26960         $LFS migrate -m 0 $DIR/$tdir.1 &&
26961                 error "migrate dir $tdir.1 should fail"
26962
26963         do_nodes $(comma_list $(mdts_nodes)) \
26964                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26965         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26966                 error "create remote dir $tdir.2 should fail"
26967
26968         do_nodes $(comma_list $(mdts_nodes)) \
26969                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26970         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26971                 error "create striped dir $tdir.3 should fail"
26972         true
26973 }
26974 run_test 417 "disable remote dir, striped dir and dir migration"
26975
26976 # Checks that the outputs of df [-i] and lfs df [-i] match
26977 #
26978 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26979 check_lfs_df() {
26980         local dir=$2
26981         local inodes
26982         local df_out
26983         local lfs_df_out
26984         local count
26985         local passed=false
26986
26987         # blocks or inodes
26988         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26989
26990         for count in {1..100}; do
26991                 do_nodes "$CLIENTS" \
26992                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26993                 sync; sleep 0.2
26994
26995                 # read the lines of interest
26996                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26997                         error "df $inodes $dir | tail -n +2 failed"
26998                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26999                         error "lfs df $inodes $dir | grep summary: failed"
27000
27001                 # skip first substrings of each output as they are different
27002                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27003                 # compare the two outputs
27004                 passed=true
27005                 #  skip "available" on MDT until LU-13997 is fixed.
27006                 #for i in {1..5}; do
27007                 for i in 1 2 4 5; do
27008                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27009                 done
27010                 $passed && break
27011         done
27012
27013         if ! $passed; then
27014                 df -P $inodes $dir
27015                 echo
27016                 lfs df $inodes $dir
27017                 error "df and lfs df $1 output mismatch: "      \
27018                       "df ${inodes}: ${df_out[*]}, "            \
27019                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27020         fi
27021 }
27022
27023 test_418() {
27024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27025
27026         local dir=$DIR/$tdir
27027         local numfiles=$((RANDOM % 4096 + 2))
27028         local numblocks=$((RANDOM % 256 + 1))
27029
27030         wait_delete_completed
27031         test_mkdir $dir
27032
27033         # check block output
27034         check_lfs_df blocks $dir
27035         # check inode output
27036         check_lfs_df inodes $dir
27037
27038         # create a single file and retest
27039         echo "Creating a single file and testing"
27040         createmany -o $dir/$tfile- 1 &>/dev/null ||
27041                 error "creating 1 file in $dir failed"
27042         check_lfs_df blocks $dir
27043         check_lfs_df inodes $dir
27044
27045         # create a random number of files
27046         echo "Creating $((numfiles - 1)) files and testing"
27047         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27048                 error "creating $((numfiles - 1)) files in $dir failed"
27049
27050         # write a random number of blocks to the first test file
27051         echo "Writing $numblocks 4K blocks and testing"
27052         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27053                 count=$numblocks &>/dev/null ||
27054                 error "dd to $dir/${tfile}-0 failed"
27055
27056         # retest
27057         check_lfs_df blocks $dir
27058         check_lfs_df inodes $dir
27059
27060         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27061                 error "unlinking $numfiles files in $dir failed"
27062 }
27063 run_test 418 "df and lfs df outputs match"
27064
27065 test_419()
27066 {
27067         local dir=$DIR/$tdir
27068
27069         mkdir -p $dir
27070         touch $dir/file
27071
27072         cancel_lru_locks mdc
27073
27074         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27075         $LCTL set_param fail_loc=0x1410
27076         cat $dir/file
27077         $LCTL set_param fail_loc=0
27078         rm -rf $dir
27079 }
27080 run_test 419 "Verify open file by name doesn't crash kernel"
27081
27082 test_420()
27083 {
27084         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27085                 skip "Need MDS version at least 2.12.53"
27086
27087         local SAVE_UMASK=$(umask)
27088         local dir=$DIR/$tdir
27089         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27090
27091         mkdir -p $dir
27092         umask 0000
27093         mkdir -m03777 $dir/testdir
27094         ls -dn $dir/testdir
27095         # Need to remove trailing '.' when SELinux is enabled
27096         local dirperms=$(ls -dn $dir/testdir |
27097                          awk '{ sub(/\.$/, "", $1); print $1}')
27098         [ $dirperms == "drwxrwsrwt" ] ||
27099                 error "incorrect perms on $dir/testdir"
27100
27101         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27102                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27103         ls -n $dir/testdir/testfile
27104         local fileperms=$(ls -n $dir/testdir/testfile |
27105                           awk '{ sub(/\.$/, "", $1); print $1}')
27106         [ $fileperms == "-rwxr-xr-x" ] ||
27107                 error "incorrect perms on $dir/testdir/testfile"
27108
27109         umask $SAVE_UMASK
27110 }
27111 run_test 420 "clear SGID bit on non-directories for non-members"
27112
27113 test_421a() {
27114         local cnt
27115         local fid1
27116         local fid2
27117
27118         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27119                 skip "Need MDS version at least 2.12.54"
27120
27121         test_mkdir $DIR/$tdir
27122         createmany -o $DIR/$tdir/f 3
27123         cnt=$(ls -1 $DIR/$tdir | wc -l)
27124         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27125
27126         fid1=$(lfs path2fid $DIR/$tdir/f1)
27127         fid2=$(lfs path2fid $DIR/$tdir/f2)
27128         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27129
27130         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27131         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27132
27133         cnt=$(ls -1 $DIR/$tdir | wc -l)
27134         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27135
27136         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27137         createmany -o $DIR/$tdir/f 3
27138         cnt=$(ls -1 $DIR/$tdir | wc -l)
27139         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27140
27141         fid1=$(lfs path2fid $DIR/$tdir/f1)
27142         fid2=$(lfs path2fid $DIR/$tdir/f2)
27143         echo "remove using fsname $FSNAME"
27144         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27145
27146         cnt=$(ls -1 $DIR/$tdir | wc -l)
27147         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27148 }
27149 run_test 421a "simple rm by fid"
27150
27151 test_421b() {
27152         local cnt
27153         local FID1
27154         local FID2
27155
27156         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27157                 skip "Need MDS version at least 2.12.54"
27158
27159         test_mkdir $DIR/$tdir
27160         createmany -o $DIR/$tdir/f 3
27161         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27162         MULTIPID=$!
27163
27164         FID1=$(lfs path2fid $DIR/$tdir/f1)
27165         FID2=$(lfs path2fid $DIR/$tdir/f2)
27166         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27167
27168         kill -USR1 $MULTIPID
27169         wait
27170
27171         cnt=$(ls $DIR/$tdir | wc -l)
27172         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27173 }
27174 run_test 421b "rm by fid on open file"
27175
27176 test_421c() {
27177         local cnt
27178         local FIDS
27179
27180         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27181                 skip "Need MDS version at least 2.12.54"
27182
27183         test_mkdir $DIR/$tdir
27184         createmany -o $DIR/$tdir/f 3
27185         touch $DIR/$tdir/$tfile
27186         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27187         cnt=$(ls -1 $DIR/$tdir | wc -l)
27188         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27189
27190         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27191         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27192
27193         cnt=$(ls $DIR/$tdir | wc -l)
27194         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27195 }
27196 run_test 421c "rm by fid against hardlinked files"
27197
27198 test_421d() {
27199         local cnt
27200         local FIDS
27201
27202         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27203                 skip "Need MDS version at least 2.12.54"
27204
27205         test_mkdir $DIR/$tdir
27206         createmany -o $DIR/$tdir/f 4097
27207         cnt=$(ls -1 $DIR/$tdir | wc -l)
27208         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27209
27210         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27211         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27212
27213         cnt=$(ls $DIR/$tdir | wc -l)
27214         rm -rf $DIR/$tdir
27215         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27216 }
27217 run_test 421d "rmfid en masse"
27218
27219 test_421e() {
27220         local cnt
27221         local FID
27222
27223         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27224         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27225                 skip "Need MDS version at least 2.12.54"
27226
27227         mkdir -p $DIR/$tdir
27228         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27229         createmany -o $DIR/$tdir/striped_dir/f 512
27230         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27231         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27232
27233         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27234                 sed "s/[/][^:]*://g")
27235         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27236
27237         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27238         rm -rf $DIR/$tdir
27239         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27240 }
27241 run_test 421e "rmfid in DNE"
27242
27243 test_421f() {
27244         local cnt
27245         local FID
27246
27247         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27248                 skip "Need MDS version at least 2.12.54"
27249
27250         test_mkdir $DIR/$tdir
27251         touch $DIR/$tdir/f
27252         cnt=$(ls -1 $DIR/$tdir | wc -l)
27253         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27254
27255         FID=$(lfs path2fid $DIR/$tdir/f)
27256         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27257         # rmfid should fail
27258         cnt=$(ls -1 $DIR/$tdir | wc -l)
27259         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27260
27261         chmod a+rw $DIR/$tdir
27262         ls -la $DIR/$tdir
27263         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27264         # rmfid should fail
27265         cnt=$(ls -1 $DIR/$tdir | wc -l)
27266         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27267
27268         rm -f $DIR/$tdir/f
27269         $RUNAS touch $DIR/$tdir/f
27270         FID=$(lfs path2fid $DIR/$tdir/f)
27271         echo "rmfid as root"
27272         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27273         cnt=$(ls -1 $DIR/$tdir | wc -l)
27274         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27275
27276         rm -f $DIR/$tdir/f
27277         $RUNAS touch $DIR/$tdir/f
27278         cnt=$(ls -1 $DIR/$tdir | wc -l)
27279         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27280         FID=$(lfs path2fid $DIR/$tdir/f)
27281         # rmfid w/o user_fid2path mount option should fail
27282         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27283         cnt=$(ls -1 $DIR/$tdir | wc -l)
27284         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27285
27286         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27287         stack_trap "rmdir $tmpdir"
27288         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27289                 error "failed to mount client'"
27290         stack_trap "umount_client $tmpdir"
27291
27292         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27293         # rmfid should succeed
27294         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27295         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27296
27297         # rmfid shouldn't allow to remove files due to dir's permission
27298         chmod a+rwx $tmpdir/$tdir
27299         touch $tmpdir/$tdir/f
27300         ls -la $tmpdir/$tdir
27301         FID=$(lfs path2fid $tmpdir/$tdir/f)
27302         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27303         return 0
27304 }
27305 run_test 421f "rmfid checks permissions"
27306
27307 test_421g() {
27308         local cnt
27309         local FIDS
27310
27311         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27312         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27313                 skip "Need MDS version at least 2.12.54"
27314
27315         mkdir -p $DIR/$tdir
27316         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27317         createmany -o $DIR/$tdir/striped_dir/f 512
27318         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27319         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27320
27321         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27322                 sed "s/[/][^:]*://g")
27323
27324         rm -f $DIR/$tdir/striped_dir/f1*
27325         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27326         removed=$((512 - cnt))
27327
27328         # few files have been just removed, so we expect
27329         # rmfid to fail on their fids
27330         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27331         [ $removed != $errors ] && error "$errors != $removed"
27332
27333         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27334         rm -rf $DIR/$tdir
27335         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27336 }
27337 run_test 421g "rmfid to return errors properly"
27338
27339 test_422() {
27340         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27341         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27342         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27343         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27344         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27345
27346         local amc=$(at_max_get client)
27347         local amo=$(at_max_get mds1)
27348         local timeout=`lctl get_param -n timeout`
27349
27350         at_max_set 0 client
27351         at_max_set 0 mds1
27352
27353 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27354         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27355                         fail_val=$(((2*timeout + 10)*1000))
27356         touch $DIR/$tdir/d3/file &
27357         sleep 2
27358 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27359         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27360                         fail_val=$((2*timeout + 5))
27361         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27362         local pid=$!
27363         sleep 1
27364         kill -9 $pid
27365         sleep $((2 * timeout))
27366         echo kill $pid
27367         kill -9 $pid
27368         lctl mark touch
27369         touch $DIR/$tdir/d2/file3
27370         touch $DIR/$tdir/d2/file4
27371         touch $DIR/$tdir/d2/file5
27372
27373         wait
27374         at_max_set $amc client
27375         at_max_set $amo mds1
27376
27377         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27378         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27379                 error "Watchdog is always throttled"
27380 }
27381 run_test 422 "kill a process with RPC in progress"
27382
27383 stat_test() {
27384     df -h $MOUNT &
27385     df -h $MOUNT &
27386     df -h $MOUNT &
27387     df -h $MOUNT &
27388     df -h $MOUNT &
27389     df -h $MOUNT &
27390 }
27391
27392 test_423() {
27393     local _stats
27394     # ensure statfs cache is expired
27395     sleep 2;
27396
27397     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27398     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27399
27400     return 0
27401 }
27402 run_test 423 "statfs should return a right data"
27403
27404 test_424() {
27405 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27406         $LCTL set_param fail_loc=0x80000522
27407         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27408         rm -f $DIR/$tfile
27409 }
27410 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27411
27412 test_425() {
27413         test_mkdir -c -1 $DIR/$tdir
27414         $LFS setstripe -c -1 $DIR/$tdir
27415
27416         lru_resize_disable "" 100
27417         stack_trap "lru_resize_enable" EXIT
27418
27419         sleep 5
27420
27421         for i in $(seq $((MDSCOUNT * 125))); do
27422                 local t=$DIR/$tdir/$tfile_$i
27423
27424                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27425                         error_noexit "Create file $t"
27426         done
27427         stack_trap "rm -rf $DIR/$tdir" EXIT
27428
27429         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27430                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27431                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27432
27433                 [ $lock_count -le $lru_size ] ||
27434                         error "osc lock count $lock_count > lru size $lru_size"
27435         done
27436
27437         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27438                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27439                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27440
27441                 [ $lock_count -le $lru_size ] ||
27442                         error "mdc lock count $lock_count > lru size $lru_size"
27443         done
27444 }
27445 run_test 425 "lock count should not exceed lru size"
27446
27447 test_426() {
27448         splice-test -r $DIR/$tfile
27449         splice-test -rd $DIR/$tfile
27450         splice-test $DIR/$tfile
27451         splice-test -d $DIR/$tfile
27452 }
27453 run_test 426 "splice test on Lustre"
27454
27455 test_427() {
27456         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27457         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27458                 skip "Need MDS version at least 2.12.4"
27459         local log
27460
27461         mkdir $DIR/$tdir
27462         mkdir $DIR/$tdir/1
27463         mkdir $DIR/$tdir/2
27464         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27465         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27466
27467         $LFS getdirstripe $DIR/$tdir/1/dir
27468
27469         #first setfattr for creating updatelog
27470         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27471
27472 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27473         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27474         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27475         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27476
27477         sleep 2
27478         fail mds2
27479         wait_recovery_complete mds2 $((2*TIMEOUT))
27480
27481         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27482         echo $log | grep "get update log failed" &&
27483                 error "update log corruption is detected" || true
27484 }
27485 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27486
27487 test_428() {
27488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27489         local cache_limit=$CACHE_MAX
27490
27491         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27492         $LCTL set_param -n llite.*.max_cached_mb=64
27493
27494         mkdir $DIR/$tdir
27495         $LFS setstripe -c 1 $DIR/$tdir
27496         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27497         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27498         #test write
27499         for f in $(seq 4); do
27500                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27501         done
27502         wait
27503
27504         cancel_lru_locks osc
27505         # Test read
27506         for f in $(seq 4); do
27507                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27508         done
27509         wait
27510 }
27511 run_test 428 "large block size IO should not hang"
27512
27513 test_429() { # LU-7915 / LU-10948
27514         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27515         local testfile=$DIR/$tfile
27516         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27517         local new_flag=1
27518         local first_rpc
27519         local second_rpc
27520         local third_rpc
27521
27522         $LCTL get_param $ll_opencache_threshold_count ||
27523                 skip "client does not have opencache parameter"
27524
27525         set_opencache $new_flag
27526         stack_trap "restore_opencache"
27527         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27528                 error "enable opencache failed"
27529         touch $testfile
27530         # drop MDC DLM locks
27531         cancel_lru_locks mdc
27532         # clear MDC RPC stats counters
27533         $LCTL set_param $mdc_rpcstats=clear
27534
27535         # According to the current implementation, we need to run 3 times
27536         # open & close file to verify if opencache is enabled correctly.
27537         # 1st, RPCs are sent for lookup/open and open handle is released on
27538         #      close finally.
27539         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27540         #      so open handle won't be released thereafter.
27541         # 3rd, No RPC is sent out.
27542         $MULTIOP $testfile oc || error "multiop failed"
27543         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27544         echo "1st: $first_rpc RPCs in flight"
27545
27546         $MULTIOP $testfile oc || error "multiop failed"
27547         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27548         echo "2nd: $second_rpc RPCs in flight"
27549
27550         $MULTIOP $testfile oc || error "multiop failed"
27551         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27552         echo "3rd: $third_rpc RPCs in flight"
27553
27554         #verify no MDC RPC is sent
27555         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27556 }
27557 run_test 429 "verify if opencache flag on client side does work"
27558
27559 lseek_test_430() {
27560         local offset
27561         local file=$1
27562
27563         # data at [200K, 400K)
27564         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27565                 error "256K->512K dd fails"
27566         # data at [2M, 3M)
27567         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27568                 error "2M->3M dd fails"
27569         # data at [4M, 5M)
27570         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27571                 error "4M->5M dd fails"
27572         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27573         # start at first component hole #1
27574         printf "Seeking hole from 1000 ... "
27575         offset=$(lseek_test -l 1000 $file)
27576         echo $offset
27577         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27578         printf "Seeking data from 1000 ... "
27579         offset=$(lseek_test -d 1000 $file)
27580         echo $offset
27581         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27582
27583         # start at first component data block
27584         printf "Seeking hole from 300000 ... "
27585         offset=$(lseek_test -l 300000 $file)
27586         echo $offset
27587         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27588         printf "Seeking data from 300000 ... "
27589         offset=$(lseek_test -d 300000 $file)
27590         echo $offset
27591         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27592
27593         # start at the first component but beyond end of object size
27594         printf "Seeking hole from 1000000 ... "
27595         offset=$(lseek_test -l 1000000 $file)
27596         echo $offset
27597         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27598         printf "Seeking data from 1000000 ... "
27599         offset=$(lseek_test -d 1000000 $file)
27600         echo $offset
27601         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27602
27603         # start at second component stripe 2 (empty file)
27604         printf "Seeking hole from 1500000 ... "
27605         offset=$(lseek_test -l 1500000 $file)
27606         echo $offset
27607         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27608         printf "Seeking data from 1500000 ... "
27609         offset=$(lseek_test -d 1500000 $file)
27610         echo $offset
27611         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27612
27613         # start at second component stripe 1 (all data)
27614         printf "Seeking hole from 3000000 ... "
27615         offset=$(lseek_test -l 3000000 $file)
27616         echo $offset
27617         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27618         printf "Seeking data from 3000000 ... "
27619         offset=$(lseek_test -d 3000000 $file)
27620         echo $offset
27621         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27622
27623         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27624                 error "2nd dd fails"
27625         echo "Add data block at 640K...1280K"
27626
27627         # start at before new data block, in hole
27628         printf "Seeking hole from 600000 ... "
27629         offset=$(lseek_test -l 600000 $file)
27630         echo $offset
27631         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27632         printf "Seeking data from 600000 ... "
27633         offset=$(lseek_test -d 600000 $file)
27634         echo $offset
27635         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27636
27637         # start at the first component new data block
27638         printf "Seeking hole from 1000000 ... "
27639         offset=$(lseek_test -l 1000000 $file)
27640         echo $offset
27641         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27642         printf "Seeking data from 1000000 ... "
27643         offset=$(lseek_test -d 1000000 $file)
27644         echo $offset
27645         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27646
27647         # start at second component stripe 2, new data
27648         printf "Seeking hole from 1200000 ... "
27649         offset=$(lseek_test -l 1200000 $file)
27650         echo $offset
27651         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27652         printf "Seeking data from 1200000 ... "
27653         offset=$(lseek_test -d 1200000 $file)
27654         echo $offset
27655         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27656
27657         # start beyond file end
27658         printf "Using offset > filesize ... "
27659         lseek_test -l 4000000 $file && error "lseek should fail"
27660         printf "Using offset > filesize ... "
27661         lseek_test -d 4000000 $file && error "lseek should fail"
27662
27663         printf "Done\n\n"
27664 }
27665
27666 test_430a() {
27667         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27668                 skip "MDT does not support SEEK_HOLE"
27669
27670         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27671                 skip "OST does not support SEEK_HOLE"
27672
27673         local file=$DIR/$tdir/$tfile
27674
27675         mkdir -p $DIR/$tdir
27676
27677         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27678         # OST stripe #1 will have continuous data at [1M, 3M)
27679         # OST stripe #2 is empty
27680         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27681         lseek_test_430 $file
27682         rm $file
27683         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27684         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27685         lseek_test_430 $file
27686         rm $file
27687         $LFS setstripe -c2 -S 512K $file
27688         echo "Two stripes, stripe size 512K"
27689         lseek_test_430 $file
27690         rm $file
27691         # FLR with stale mirror
27692         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27693                        -N -c2 -S 1M $file
27694         echo "Mirrored file:"
27695         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27696         echo "Plain 2 stripes 1M"
27697         lseek_test_430 $file
27698         rm $file
27699 }
27700 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27701
27702 test_430b() {
27703         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27704                 skip "OST does not support SEEK_HOLE"
27705
27706         local offset
27707         local file=$DIR/$tdir/$tfile
27708
27709         mkdir -p $DIR/$tdir
27710         # Empty layout lseek should fail
27711         $MCREATE $file
27712         # seek from 0
27713         printf "Seeking hole from 0 ... "
27714         lseek_test -l 0 $file && error "lseek should fail"
27715         printf "Seeking data from 0 ... "
27716         lseek_test -d 0 $file && error "lseek should fail"
27717         rm $file
27718
27719         # 1M-hole file
27720         $LFS setstripe -E 1M -c2 -E eof $file
27721         $TRUNCATE $file 1048576
27722         printf "Seeking hole from 1000000 ... "
27723         offset=$(lseek_test -l 1000000 $file)
27724         echo $offset
27725         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27726         printf "Seeking data from 1000000 ... "
27727         lseek_test -d 1000000 $file && error "lseek should fail"
27728         rm $file
27729
27730         # full component followed by non-inited one
27731         $LFS setstripe -E 1M -c2 -E eof $file
27732         dd if=/dev/urandom of=$file bs=1M count=1
27733         printf "Seeking hole from 1000000 ... "
27734         offset=$(lseek_test -l 1000000 $file)
27735         echo $offset
27736         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27737         printf "Seeking hole from 1048576 ... "
27738         lseek_test -l 1048576 $file && error "lseek should fail"
27739         # init second component and truncate back
27740         echo "123" >> $file
27741         $TRUNCATE $file 1048576
27742         printf "Seeking hole from 1000000 ... "
27743         offset=$(lseek_test -l 1000000 $file)
27744         echo $offset
27745         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27746         printf "Seeking hole from 1048576 ... "
27747         lseek_test -l 1048576 $file && error "lseek should fail"
27748         # boundary checks for big values
27749         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27750         offset=$(lseek_test -d 0 $file.10g)
27751         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27752         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27753         offset=$(lseek_test -d 0 $file.100g)
27754         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27755         return 0
27756 }
27757 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27758
27759 test_430c() {
27760         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27761                 skip "OST does not support SEEK_HOLE"
27762
27763         local file=$DIR/$tdir/$tfile
27764         local start
27765
27766         mkdir -p $DIR/$tdir
27767         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27768
27769         # cp version 8.33+ prefers lseek over fiemap
27770         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27771                 start=$SECONDS
27772                 time cp $file /dev/null
27773                 (( SECONDS - start < 5 )) ||
27774                         error "cp: too long runtime $((SECONDS - start))"
27775
27776         fi
27777         # tar version 1.29+ supports SEEK_HOLE/DATA
27778         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27779                 start=$SECONDS
27780                 time tar cS $file - | cat > /dev/null
27781                 (( SECONDS - start < 5 )) ||
27782                         error "tar: too long runtime $((SECONDS - start))"
27783         fi
27784 }
27785 run_test 430c "lseek: external tools check"
27786
27787 test_431() { # LU-14187
27788         local file=$DIR/$tdir/$tfile
27789
27790         mkdir -p $DIR/$tdir
27791         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27792         dd if=/dev/urandom of=$file bs=4k count=1
27793         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27794         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27795         #define OBD_FAIL_OST_RESTART_IO 0x251
27796         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27797         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27798         cp $file $file.0
27799         cancel_lru_locks
27800         sync_all_data
27801         echo 3 > /proc/sys/vm/drop_caches
27802         diff  $file $file.0 || error "data diff"
27803 }
27804 run_test 431 "Restart transaction for IO"
27805
27806 cleanup_test_432() {
27807         do_facet mgs $LCTL nodemap_activate 0
27808         wait_nm_sync active
27809 }
27810
27811 test_432() {
27812         local tmpdir=$TMP/dir432
27813
27814         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27815                 skip "Need MDS version at least 2.14.52"
27816
27817         stack_trap cleanup_test_432 EXIT
27818         mkdir $DIR/$tdir
27819         mkdir $tmpdir
27820
27821         do_facet mgs $LCTL nodemap_activate 1
27822         wait_nm_sync active
27823         do_facet mgs $LCTL nodemap_modify --name default \
27824                 --property admin --value 1
27825         do_facet mgs $LCTL nodemap_modify --name default \
27826                 --property trusted --value 1
27827         cancel_lru_locks mdc
27828         wait_nm_sync default admin_nodemap
27829         wait_nm_sync default trusted_nodemap
27830
27831         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27832                grep -ci "Operation not permitted") -ne 0 ]; then
27833                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27834         fi
27835 }
27836 run_test 432 "mv dir from outside Lustre"
27837
27838 test_433() {
27839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27840
27841         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27842                 skip "inode cache not supported"
27843
27844         $LCTL set_param llite.*.inode_cache=0
27845         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27846
27847         local count=256
27848         local before
27849         local after
27850
27851         cancel_lru_locks mdc
27852         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27853         createmany -m $DIR/$tdir/f $count
27854         createmany -d $DIR/$tdir/d $count
27855         ls -l $DIR/$tdir > /dev/null
27856         stack_trap "rm -rf $DIR/$tdir"
27857
27858         before=$(num_objects)
27859         cancel_lru_locks mdc
27860         after=$(num_objects)
27861
27862         # sometimes even @before is less than 2 * count
27863         while (( before - after < count )); do
27864                 sleep 1
27865                 after=$(num_objects)
27866                 wait=$((wait + 1))
27867                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27868                 if (( wait > 60 )); then
27869                         error "inode slab grew from $before to $after"
27870                 fi
27871         done
27872
27873         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27874 }
27875 run_test 433 "ldlm lock cancel releases dentries and inodes"
27876
27877 test_434() {
27878         local file
27879         local getxattr_count
27880         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27881         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27882
27883         [[ $(getenforce) == "Disabled" ]] ||
27884                 skip "lsm selinux module have to be disabled for this test"
27885
27886         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27887                 error "fail to create $DIR/$tdir/ on MDT0000"
27888
27889         touch $DIR/$tdir/$tfile-{001..100}
27890
27891         # disable the xattr cache
27892         save_lustre_params client "llite.*.xattr_cache" > $p
27893         lctl set_param llite.*.xattr_cache=0
27894         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27895
27896         # clear clients mdc stats
27897         clear_stats $mdc_stat_param ||
27898                 error "fail to clear stats on mdc MDT0000"
27899
27900         for file in $DIR/$tdir/$tfile-{001..100}; do
27901                 getfattr -n security.selinux $file |&
27902                         grep -q "Operation not supported" ||
27903                         error "getxattr on security.selinux should return EOPNOTSUPP"
27904         done
27905
27906         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27907         (( getxattr_count < 100 )) ||
27908                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27909 }
27910 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27911
27912 test_440() {
27913         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
27914                 source $LUSTRE/scripts/bash-completion/lustre
27915         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
27916                 source /usr/share/bash-completion/completions/lustre
27917         else
27918                 skip "bash completion scripts not found"
27919         fi
27920
27921         local lctl_completions
27922         local lfs_completions
27923
27924         lctl_completions=$(_lustre_cmds lctl)
27925         if [[ ! $lctl_completions =~ "get_param" ]]; then
27926                 error "lctl bash completion failed"
27927         fi
27928
27929         lfs_completions=$(_lustre_cmds lfs)
27930         if [[ ! $lfs_completions =~ "setstripe" ]]; then
27931                 error "lfs bash completion failed"
27932         fi
27933 }
27934 run_test 440 "bash completion for lfs, lctl"
27935
27936 prep_801() {
27937         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27938         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27939                 skip "Need server version at least 2.9.55"
27940
27941         start_full_debug_logging
27942 }
27943
27944 post_801() {
27945         stop_full_debug_logging
27946 }
27947
27948 barrier_stat() {
27949         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27950                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27951                            awk '/The barrier for/ { print $7 }')
27952                 echo $st
27953         else
27954                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27955                 echo \'$st\'
27956         fi
27957 }
27958
27959 barrier_expired() {
27960         local expired
27961
27962         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27963                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27964                           awk '/will be expired/ { print $7 }')
27965         else
27966                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27967         fi
27968
27969         echo $expired
27970 }
27971
27972 test_801a() {
27973         prep_801
27974
27975         echo "Start barrier_freeze at: $(date)"
27976         #define OBD_FAIL_BARRIER_DELAY          0x2202
27977         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27978         # Do not reduce barrier time - See LU-11873
27979         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27980
27981         sleep 2
27982         local b_status=$(barrier_stat)
27983         echo "Got barrier status at: $(date)"
27984         [ "$b_status" = "'freezing_p1'" ] ||
27985                 error "(1) unexpected barrier status $b_status"
27986
27987         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27988         wait
27989         b_status=$(barrier_stat)
27990         [ "$b_status" = "'frozen'" ] ||
27991                 error "(2) unexpected barrier status $b_status"
27992
27993         local expired=$(barrier_expired)
27994         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27995         sleep $((expired + 3))
27996
27997         b_status=$(barrier_stat)
27998         [ "$b_status" = "'expired'" ] ||
27999                 error "(3) unexpected barrier status $b_status"
28000
28001         # Do not reduce barrier time - See LU-11873
28002         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28003                 error "(4) fail to freeze barrier"
28004
28005         b_status=$(barrier_stat)
28006         [ "$b_status" = "'frozen'" ] ||
28007                 error "(5) unexpected barrier status $b_status"
28008
28009         echo "Start barrier_thaw at: $(date)"
28010         #define OBD_FAIL_BARRIER_DELAY          0x2202
28011         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28012         do_facet mgs $LCTL barrier_thaw $FSNAME &
28013
28014         sleep 2
28015         b_status=$(barrier_stat)
28016         echo "Got barrier status at: $(date)"
28017         [ "$b_status" = "'thawing'" ] ||
28018                 error "(6) 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" = "'thawed'" ] ||
28024                 error "(7) unexpected barrier status $b_status"
28025
28026         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28027         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28028         do_facet mgs $LCTL barrier_freeze $FSNAME
28029
28030         b_status=$(barrier_stat)
28031         [ "$b_status" = "'failed'" ] ||
28032                 error "(8) unexpected barrier status $b_status"
28033
28034         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28035         do_facet mgs $LCTL barrier_thaw $FSNAME
28036
28037         post_801
28038 }
28039 run_test 801a "write barrier user interfaces and stat machine"
28040
28041 test_801b() {
28042         prep_801
28043
28044         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28045         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28046         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28047         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28048         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28049
28050         cancel_lru_locks mdc
28051
28052         # 180 seconds should be long enough
28053         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28054
28055         local b_status=$(barrier_stat)
28056         [ "$b_status" = "'frozen'" ] ||
28057                 error "(6) unexpected barrier status $b_status"
28058
28059         mkdir $DIR/$tdir/d0/d10 &
28060         mkdir_pid=$!
28061
28062         touch $DIR/$tdir/d1/f13 &
28063         touch_pid=$!
28064
28065         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28066         ln_pid=$!
28067
28068         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28069         mv_pid=$!
28070
28071         rm -f $DIR/$tdir/d4/f12 &
28072         rm_pid=$!
28073
28074         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28075
28076         # To guarantee taht the 'stat' is not blocked
28077         b_status=$(barrier_stat)
28078         [ "$b_status" = "'frozen'" ] ||
28079                 error "(8) unexpected barrier status $b_status"
28080
28081         # let above commands to run at background
28082         sleep 5
28083
28084         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28085         ps -p $touch_pid || error "(10) touch should be blocked"
28086         ps -p $ln_pid || error "(11) link should be blocked"
28087         ps -p $mv_pid || error "(12) rename should be blocked"
28088         ps -p $rm_pid || error "(13) unlink should be blocked"
28089
28090         b_status=$(barrier_stat)
28091         [ "$b_status" = "'frozen'" ] ||
28092                 error "(14) unexpected barrier status $b_status"
28093
28094         do_facet mgs $LCTL barrier_thaw $FSNAME
28095         b_status=$(barrier_stat)
28096         [ "$b_status" = "'thawed'" ] ||
28097                 error "(15) unexpected barrier status $b_status"
28098
28099         wait $mkdir_pid || error "(16) mkdir should succeed"
28100         wait $touch_pid || error "(17) touch should succeed"
28101         wait $ln_pid || error "(18) link should succeed"
28102         wait $mv_pid || error "(19) rename should succeed"
28103         wait $rm_pid || error "(20) unlink should succeed"
28104
28105         post_801
28106 }
28107 run_test 801b "modification will be blocked by write barrier"
28108
28109 test_801c() {
28110         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28111
28112         prep_801
28113
28114         stop mds2 || error "(1) Fail to stop mds2"
28115
28116         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28117
28118         local b_status=$(barrier_stat)
28119         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28120                 do_facet mgs $LCTL barrier_thaw $FSNAME
28121                 error "(2) unexpected barrier status $b_status"
28122         }
28123
28124         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28125                 error "(3) Fail to rescan barrier bitmap"
28126
28127         # Do not reduce barrier time - See LU-11873
28128         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28129
28130         b_status=$(barrier_stat)
28131         [ "$b_status" = "'frozen'" ] ||
28132                 error "(4) unexpected barrier status $b_status"
28133
28134         do_facet mgs $LCTL barrier_thaw $FSNAME
28135         b_status=$(barrier_stat)
28136         [ "$b_status" = "'thawed'" ] ||
28137                 error "(5) unexpected barrier status $b_status"
28138
28139         local devname=$(mdsdevname 2)
28140
28141         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28142
28143         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28144                 error "(7) Fail to rescan barrier bitmap"
28145
28146         post_801
28147 }
28148 run_test 801c "rescan barrier bitmap"
28149
28150 test_802b() {
28151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28152         remote_mds_nodsh && skip "remote MDS with nodsh"
28153
28154         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28155                 skip "readonly option not available"
28156
28157         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28158
28159         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28160                 error "(2) Fail to copy"
28161
28162         # write back all cached data before setting MDT to readonly
28163         cancel_lru_locks
28164         sync_all_data
28165
28166         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28167         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28168
28169         echo "Modify should be refused"
28170         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28171
28172         echo "Read should be allowed"
28173         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28174                 error "(7) Read should succeed under ro mode"
28175
28176         # disable readonly
28177         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28178 }
28179 run_test 802b "be able to set MDTs to readonly"
28180
28181 test_803a() {
28182         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28183         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28184                 skip "MDS needs to be newer than 2.10.54"
28185
28186         mkdir_on_mdt0 $DIR/$tdir
28187         # Create some objects on all MDTs to trigger related logs objects
28188         for idx in $(seq $MDSCOUNT); do
28189                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28190                         $DIR/$tdir/dir${idx} ||
28191                         error "Fail to create $DIR/$tdir/dir${idx}"
28192         done
28193
28194         wait_delete_completed # ensure old test cleanups are finished
28195         sleep 3
28196         echo "before create:"
28197         $LFS df -i $MOUNT
28198         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28199
28200         for i in {1..10}; do
28201                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28202                         error "Fail to create $DIR/$tdir/foo$i"
28203         done
28204
28205         # sync ZFS-on-MDS to refresh statfs data
28206         wait_zfs_commit mds1
28207         sleep 3
28208         echo "after create:"
28209         $LFS df -i $MOUNT
28210         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28211
28212         # allow for an llog to be cleaned up during the test
28213         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28214                 error "before ($before_used) + 10 > after ($after_used)"
28215
28216         for i in {1..10}; do
28217                 rm -rf $DIR/$tdir/foo$i ||
28218                         error "Fail to remove $DIR/$tdir/foo$i"
28219         done
28220
28221         # sync ZFS-on-MDS to refresh statfs data
28222         wait_zfs_commit mds1
28223         wait_delete_completed
28224         sleep 3 # avoid MDT return cached statfs
28225         echo "after unlink:"
28226         $LFS df -i $MOUNT
28227         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28228
28229         # allow for an llog to be created during the test
28230         [ $after_used -le $((before_used + 1)) ] ||
28231                 error "after ($after_used) > before ($before_used) + 1"
28232 }
28233 run_test 803a "verify agent object for remote object"
28234
28235 test_803b() {
28236         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28237         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28238                 skip "MDS needs to be newer than 2.13.56"
28239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28240
28241         for i in $(seq 0 $((MDSCOUNT - 1))); do
28242                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28243         done
28244
28245         local before=0
28246         local after=0
28247
28248         local tmp
28249
28250         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28251         for i in $(seq 0 $((MDSCOUNT - 1))); do
28252                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28253                         awk '/getattr/ { print $2 }')
28254                 before=$((before + tmp))
28255         done
28256         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28257         for i in $(seq 0 $((MDSCOUNT - 1))); do
28258                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28259                         awk '/getattr/ { print $2 }')
28260                 after=$((after + tmp))
28261         done
28262
28263         [ $before -eq $after ] || error "getattr count $before != $after"
28264 }
28265 run_test 803b "remote object can getattr from cache"
28266
28267 test_804() {
28268         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28269         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28270                 skip "MDS needs to be newer than 2.10.54"
28271         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28272
28273         mkdir -p $DIR/$tdir
28274         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28275                 error "Fail to create $DIR/$tdir/dir0"
28276
28277         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28278         local dev=$(mdsdevname 2)
28279
28280         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28281                 grep ${fid} || error "NOT found agent entry for dir0"
28282
28283         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28284                 error "Fail to create $DIR/$tdir/dir1"
28285
28286         touch $DIR/$tdir/dir1/foo0 ||
28287                 error "Fail to create $DIR/$tdir/dir1/foo0"
28288         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28289         local rc=0
28290
28291         for idx in $(seq $MDSCOUNT); do
28292                 dev=$(mdsdevname $idx)
28293                 do_facet mds${idx} \
28294                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28295                         grep ${fid} && rc=$idx
28296         done
28297
28298         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28299                 error "Fail to rename foo0 to foo1"
28300         if [ $rc -eq 0 ]; then
28301                 for idx in $(seq $MDSCOUNT); do
28302                         dev=$(mdsdevname $idx)
28303                         do_facet mds${idx} \
28304                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28305                         grep ${fid} && rc=$idx
28306                 done
28307         fi
28308
28309         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28310                 error "Fail to rename foo1 to foo2"
28311         if [ $rc -eq 0 ]; then
28312                 for idx in $(seq $MDSCOUNT); do
28313                         dev=$(mdsdevname $idx)
28314                         do_facet mds${idx} \
28315                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28316                         grep ${fid} && rc=$idx
28317                 done
28318         fi
28319
28320         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28321
28322         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28323                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28324         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28325                 error "Fail to rename foo2 to foo0"
28326         unlink $DIR/$tdir/dir1/foo0 ||
28327                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28328         rm -rf $DIR/$tdir/dir0 ||
28329                 error "Fail to rm $DIR/$tdir/dir0"
28330
28331         for idx in $(seq $MDSCOUNT); do
28332                 rc=0
28333
28334                 stop mds${idx}
28335                 dev=$(mdsdevname $idx)
28336                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28337                         rc=$?
28338                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28339                         error "mount mds$idx failed"
28340                 df $MOUNT > /dev/null 2>&1
28341
28342                 # e2fsck should not return error
28343                 [ $rc -eq 0 ] ||
28344                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28345         done
28346 }
28347 run_test 804 "verify agent entry for remote entry"
28348
28349 cleanup_805() {
28350         do_facet $SINGLEMDS zfs set quota=$old $fsset
28351         unlinkmany $DIR/$tdir/f- 1000000
28352         trap 0
28353 }
28354
28355 test_805() {
28356         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28357         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28358         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28359                 skip "netfree not implemented before 0.7"
28360         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28361                 skip "Need MDS version at least 2.10.57"
28362
28363         local fsset
28364         local freekb
28365         local usedkb
28366         local old
28367         local quota
28368         local pref="osd-zfs.$FSNAME-MDT0000."
28369
28370         # limit available space on MDS dataset to meet nospace issue
28371         # quickly. then ZFS 0.7.2 can use reserved space if asked
28372         # properly (using netfree flag in osd_declare_destroy()
28373         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28374         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28375                 gawk '{print $3}')
28376         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28377         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28378         let "usedkb=usedkb-freekb"
28379         let "freekb=freekb/2"
28380         if let "freekb > 5000"; then
28381                 let "freekb=5000"
28382         fi
28383         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28384         trap cleanup_805 EXIT
28385         mkdir_on_mdt0 $DIR/$tdir
28386         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28387                 error "Can't set PFL layout"
28388         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28389         rm -rf $DIR/$tdir || error "not able to remove"
28390         do_facet $SINGLEMDS zfs set quota=$old $fsset
28391         trap 0
28392 }
28393 run_test 805 "ZFS can remove from full fs"
28394
28395 # Size-on-MDS test
28396 check_lsom_data()
28397 {
28398         local file=$1
28399         local expect=$(stat -c %s $file)
28400
28401         check_lsom_size $1 $expect
28402
28403         local blocks=$($LFS getsom -b $file)
28404         expect=$(stat -c %b $file)
28405         [[ $blocks == $expect ]] ||
28406                 error "$file expected blocks: $expect, got: $blocks"
28407 }
28408
28409 check_lsom_size()
28410 {
28411         local size
28412         local expect=$2
28413
28414         cancel_lru_locks mdc
28415
28416         size=$($LFS getsom -s $1)
28417         [[ $size == $expect ]] ||
28418                 error "$file expected size: $expect, got: $size"
28419 }
28420
28421 test_806() {
28422         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28423                 skip "Need MDS version at least 2.11.52"
28424
28425         local bs=1048576
28426
28427         touch $DIR/$tfile || error "touch $tfile failed"
28428
28429         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28430         save_lustre_params client "llite.*.xattr_cache" > $save
28431         lctl set_param llite.*.xattr_cache=0
28432         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28433
28434         # single-threaded write
28435         echo "Test SOM for single-threaded write"
28436         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28437                 error "write $tfile failed"
28438         check_lsom_size $DIR/$tfile $bs
28439
28440         local num=32
28441         local size=$(($num * $bs))
28442         local offset=0
28443         local i
28444
28445         echo "Test SOM for single client multi-threaded($num) write"
28446         $TRUNCATE $DIR/$tfile 0
28447         for ((i = 0; i < $num; i++)); do
28448                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28449                 local pids[$i]=$!
28450                 offset=$((offset + $bs))
28451         done
28452         for (( i=0; i < $num; i++ )); do
28453                 wait ${pids[$i]}
28454         done
28455         check_lsom_size $DIR/$tfile $size
28456
28457         $TRUNCATE $DIR/$tfile 0
28458         for ((i = 0; i < $num; i++)); do
28459                 offset=$((offset - $bs))
28460                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28461                 local pids[$i]=$!
28462         done
28463         for (( i=0; i < $num; i++ )); do
28464                 wait ${pids[$i]}
28465         done
28466         check_lsom_size $DIR/$tfile $size
28467
28468         # multi-client writes
28469         num=$(get_node_count ${CLIENTS//,/ })
28470         size=$(($num * $bs))
28471         offset=0
28472         i=0
28473
28474         echo "Test SOM for multi-client ($num) writes"
28475         $TRUNCATE $DIR/$tfile 0
28476         for client in ${CLIENTS//,/ }; do
28477                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28478                 local pids[$i]=$!
28479                 i=$((i + 1))
28480                 offset=$((offset + $bs))
28481         done
28482         for (( i=0; i < $num; i++ )); do
28483                 wait ${pids[$i]}
28484         done
28485         check_lsom_size $DIR/$tfile $offset
28486
28487         i=0
28488         $TRUNCATE $DIR/$tfile 0
28489         for client in ${CLIENTS//,/ }; do
28490                 offset=$((offset - $bs))
28491                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28492                 local pids[$i]=$!
28493                 i=$((i + 1))
28494         done
28495         for (( i=0; i < $num; i++ )); do
28496                 wait ${pids[$i]}
28497         done
28498         check_lsom_size $DIR/$tfile $size
28499
28500         # verify truncate
28501         echo "Test SOM for truncate"
28502         $TRUNCATE $DIR/$tfile 1048576
28503         check_lsom_size $DIR/$tfile 1048576
28504         $TRUNCATE $DIR/$tfile 1234
28505         check_lsom_size $DIR/$tfile 1234
28506
28507         # verify SOM blocks count
28508         echo "Verify SOM block count"
28509         $TRUNCATE $DIR/$tfile 0
28510         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28511                 error "failed to write file $tfile"
28512         check_lsom_data $DIR/$tfile
28513 }
28514 run_test 806 "Verify Lazy Size on MDS"
28515
28516 test_807() {
28517         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28518         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28519                 skip "Need MDS version at least 2.11.52"
28520
28521         # Registration step
28522         changelog_register || error "changelog_register failed"
28523         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28524         changelog_users $SINGLEMDS | grep -q $cl_user ||
28525                 error "User $cl_user not found in changelog_users"
28526
28527         rm -rf $DIR/$tdir || error "rm $tdir failed"
28528         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28529         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28530         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28531         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28532                 error "truncate $tdir/trunc failed"
28533
28534         local bs=1048576
28535         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28536                 error "write $tfile failed"
28537
28538         # multi-client wirtes
28539         local num=$(get_node_count ${CLIENTS//,/ })
28540         local offset=0
28541         local i=0
28542
28543         echo "Test SOM for multi-client ($num) writes"
28544         touch $DIR/$tfile || error "touch $tfile failed"
28545         $TRUNCATE $DIR/$tfile 0
28546         for client in ${CLIENTS//,/ }; do
28547                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28548                 local pids[$i]=$!
28549                 i=$((i + 1))
28550                 offset=$((offset + $bs))
28551         done
28552         for (( i=0; i < $num; i++ )); do
28553                 wait ${pids[$i]}
28554         done
28555
28556         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28557         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28558         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28559         check_lsom_data $DIR/$tdir/trunc
28560         check_lsom_data $DIR/$tdir/single_dd
28561         check_lsom_data $DIR/$tfile
28562
28563         rm -rf $DIR/$tdir
28564         # Deregistration step
28565         changelog_deregister || error "changelog_deregister failed"
28566 }
28567 run_test 807 "verify LSOM syncing tool"
28568
28569 check_som_nologged()
28570 {
28571         local lines=$($LFS changelog $FSNAME-MDT0000 |
28572                 grep 'x=trusted.som' | wc -l)
28573         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28574 }
28575
28576 test_808() {
28577         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28578                 skip "Need MDS version at least 2.11.55"
28579
28580         # Registration step
28581         changelog_register || error "changelog_register failed"
28582
28583         touch $DIR/$tfile || error "touch $tfile failed"
28584         check_som_nologged
28585
28586         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28587                 error "write $tfile failed"
28588         check_som_nologged
28589
28590         $TRUNCATE $DIR/$tfile 1234
28591         check_som_nologged
28592
28593         $TRUNCATE $DIR/$tfile 1048576
28594         check_som_nologged
28595
28596         # Deregistration step
28597         changelog_deregister || error "changelog_deregister failed"
28598 }
28599 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28600
28601 check_som_nodata()
28602 {
28603         $LFS getsom $1
28604         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28605 }
28606
28607 test_809() {
28608         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28609                 skip "Need MDS version at least 2.11.56"
28610
28611         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28612                 error "failed to create DoM-only file $DIR/$tfile"
28613         touch $DIR/$tfile || error "touch $tfile failed"
28614         check_som_nodata $DIR/$tfile
28615
28616         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28617                 error "write $tfile failed"
28618         check_som_nodata $DIR/$tfile
28619
28620         $TRUNCATE $DIR/$tfile 1234
28621         check_som_nodata $DIR/$tfile
28622
28623         $TRUNCATE $DIR/$tfile 4097
28624         check_som_nodata $DIR/$file
28625 }
28626 run_test 809 "Verify no SOM xattr store for DoM-only files"
28627
28628 test_810() {
28629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28630         $GSS && skip_env "could not run with gss"
28631         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28632                 skip "OST < 2.12.58 doesn't align checksum"
28633
28634         set_checksums 1
28635         stack_trap "set_checksums $ORIG_CSUM" EXIT
28636         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28637
28638         local csum
28639         local before
28640         local after
28641         for csum in $CKSUM_TYPES; do
28642                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28643                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28644                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28645                         eval set -- $i
28646                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28647                         before=$(md5sum $DIR/$tfile)
28648                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28649                         after=$(md5sum $DIR/$tfile)
28650                         [ "$before" == "$after" ] ||
28651                                 error "$csum: $before != $after bs=$1 seek=$2"
28652                 done
28653         done
28654 }
28655 run_test 810 "partial page writes on ZFS (LU-11663)"
28656
28657 test_812a() {
28658         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28659                 skip "OST < 2.12.51 doesn't support this fail_loc"
28660
28661         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28662         # ensure ost1 is connected
28663         stat $DIR/$tfile >/dev/null || error "can't stat"
28664         wait_osc_import_state client ost1 FULL
28665         # no locks, no reqs to let the connection idle
28666         cancel_lru_locks osc
28667
28668         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28669 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28670         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28671         wait_osc_import_state client ost1 CONNECTING
28672         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28673
28674         stat $DIR/$tfile >/dev/null || error "can't stat file"
28675 }
28676 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28677
28678 test_812b() { # LU-12378
28679         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28680                 skip "OST < 2.12.51 doesn't support this fail_loc"
28681
28682         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28683         # ensure ost1 is connected
28684         stat $DIR/$tfile >/dev/null || error "can't stat"
28685         wait_osc_import_state client ost1 FULL
28686         # no locks, no reqs to let the connection idle
28687         cancel_lru_locks osc
28688
28689         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28690 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28691         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28692         wait_osc_import_state client ost1 CONNECTING
28693         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28694
28695         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28696         wait_osc_import_state client ost1 IDLE
28697 }
28698 run_test 812b "do not drop no resend request for idle connect"
28699
28700 test_812c() {
28701         local old
28702
28703         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28704
28705         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28706         $LFS getstripe $DIR/$tfile
28707         $LCTL set_param osc.*.idle_timeout=10
28708         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28709         # ensure ost1 is connected
28710         stat $DIR/$tfile >/dev/null || error "can't stat"
28711         wait_osc_import_state client ost1 FULL
28712         # no locks, no reqs to let the connection idle
28713         cancel_lru_locks osc
28714
28715 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28716         $LCTL set_param fail_loc=0x80000533
28717         sleep 15
28718         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28719 }
28720 run_test 812c "idle import vs lock enqueue race"
28721
28722 test_813() {
28723         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28724         [ -z "$file_heat_sav" ] && skip "no file heat support"
28725
28726         local readsample
28727         local writesample
28728         local readbyte
28729         local writebyte
28730         local readsample1
28731         local writesample1
28732         local readbyte1
28733         local writebyte1
28734
28735         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28736         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28737
28738         $LCTL set_param -n llite.*.file_heat=1
28739         echo "Turn on file heat"
28740         echo "Period second: $period_second, Decay percentage: $decay_pct"
28741
28742         echo "QQQQ" > $DIR/$tfile
28743         echo "QQQQ" > $DIR/$tfile
28744         echo "QQQQ" > $DIR/$tfile
28745         cat $DIR/$tfile > /dev/null
28746         cat $DIR/$tfile > /dev/null
28747         cat $DIR/$tfile > /dev/null
28748         cat $DIR/$tfile > /dev/null
28749
28750         local out=$($LFS heat_get $DIR/$tfile)
28751
28752         $LFS heat_get $DIR/$tfile
28753         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28754         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28755         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28756         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28757
28758         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28759         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28760         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28761         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28762
28763         sleep $((period_second + 3))
28764         echo "Sleep $((period_second + 3)) seconds..."
28765         # The recursion formula to calculate the heat of the file f is as
28766         # follow:
28767         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28768         # Where Hi is the heat value in the period between time points i*I and
28769         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28770         # to the weight of Ci.
28771         out=$($LFS heat_get $DIR/$tfile)
28772         $LFS heat_get $DIR/$tfile
28773         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28774         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28775         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28776         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28777
28778         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28779                 error "read sample ($readsample) is wrong"
28780         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28781                 error "write sample ($writesample) is wrong"
28782         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28783                 error "read bytes ($readbyte) is wrong"
28784         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28785                 error "write bytes ($writebyte) is wrong"
28786
28787         echo "QQQQ" > $DIR/$tfile
28788         echo "QQQQ" > $DIR/$tfile
28789         echo "QQQQ" > $DIR/$tfile
28790         cat $DIR/$tfile > /dev/null
28791         cat $DIR/$tfile > /dev/null
28792         cat $DIR/$tfile > /dev/null
28793         cat $DIR/$tfile > /dev/null
28794
28795         sleep $((period_second + 3))
28796         echo "Sleep $((period_second + 3)) seconds..."
28797
28798         out=$($LFS heat_get $DIR/$tfile)
28799         $LFS heat_get $DIR/$tfile
28800         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28801         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28802         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28803         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28804
28805         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28806                 4 * $decay_pct) / 100") -eq 1 ] ||
28807                 error "read sample ($readsample1) is wrong"
28808         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28809                 3 * $decay_pct) / 100") -eq 1 ] ||
28810                 error "write sample ($writesample1) is wrong"
28811         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28812                 20 * $decay_pct) / 100") -eq 1 ] ||
28813                 error "read bytes ($readbyte1) is wrong"
28814         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28815                 15 * $decay_pct) / 100") -eq 1 ] ||
28816                 error "write bytes ($writebyte1) is wrong"
28817
28818         echo "Turn off file heat for the file $DIR/$tfile"
28819         $LFS heat_set -o $DIR/$tfile
28820
28821         echo "QQQQ" > $DIR/$tfile
28822         echo "QQQQ" > $DIR/$tfile
28823         echo "QQQQ" > $DIR/$tfile
28824         cat $DIR/$tfile > /dev/null
28825         cat $DIR/$tfile > /dev/null
28826         cat $DIR/$tfile > /dev/null
28827         cat $DIR/$tfile > /dev/null
28828
28829         out=$($LFS heat_get $DIR/$tfile)
28830         $LFS heat_get $DIR/$tfile
28831         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28832         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28833         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28834         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28835
28836         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28837         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28838         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28839         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28840
28841         echo "Trun on file heat for the file $DIR/$tfile"
28842         $LFS heat_set -O $DIR/$tfile
28843
28844         echo "QQQQ" > $DIR/$tfile
28845         echo "QQQQ" > $DIR/$tfile
28846         echo "QQQQ" > $DIR/$tfile
28847         cat $DIR/$tfile > /dev/null
28848         cat $DIR/$tfile > /dev/null
28849         cat $DIR/$tfile > /dev/null
28850         cat $DIR/$tfile > /dev/null
28851
28852         out=$($LFS heat_get $DIR/$tfile)
28853         $LFS heat_get $DIR/$tfile
28854         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28855         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28856         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28857         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28858
28859         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28860         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28861         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28862         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28863
28864         $LFS heat_set -c $DIR/$tfile
28865         $LCTL set_param -n llite.*.file_heat=0
28866         echo "Turn off file heat support for the Lustre filesystem"
28867
28868         echo "QQQQ" > $DIR/$tfile
28869         echo "QQQQ" > $DIR/$tfile
28870         echo "QQQQ" > $DIR/$tfile
28871         cat $DIR/$tfile > /dev/null
28872         cat $DIR/$tfile > /dev/null
28873         cat $DIR/$tfile > /dev/null
28874         cat $DIR/$tfile > /dev/null
28875
28876         out=$($LFS heat_get $DIR/$tfile)
28877         $LFS heat_get $DIR/$tfile
28878         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28879         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28880         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28881         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28882
28883         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28884         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28885         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28886         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28887
28888         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28889         rm -f $DIR/$tfile
28890 }
28891 run_test 813 "File heat verfication"
28892
28893 test_814()
28894 {
28895         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28896         echo -n y >> $DIR/$tfile
28897         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28898         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28899 }
28900 run_test 814 "sparse cp works as expected (LU-12361)"
28901
28902 test_815()
28903 {
28904         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28905         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28906 }
28907 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28908
28909 test_816() {
28910         local ost1_imp=$(get_osc_import_name client ost1)
28911         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28912                          cut -d'.' -f2)
28913
28914         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28915         # ensure ost1 is connected
28916
28917         stat $DIR/$tfile >/dev/null || error "can't stat"
28918         wait_osc_import_state client ost1 FULL
28919         # no locks, no reqs to let the connection idle
28920         cancel_lru_locks osc
28921         lru_resize_disable osc
28922         local before
28923         local now
28924         before=$($LCTL get_param -n \
28925                  ldlm.namespaces.$imp_name.lru_size)
28926
28927         wait_osc_import_state client ost1 IDLE
28928         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28929         now=$($LCTL get_param -n \
28930               ldlm.namespaces.$imp_name.lru_size)
28931         [ $before == $now ] || error "lru_size changed $before != $now"
28932 }
28933 run_test 816 "do not reset lru_resize on idle reconnect"
28934
28935 cleanup_817() {
28936         umount $tmpdir
28937         exportfs -u localhost:$DIR/nfsexp
28938         rm -rf $DIR/nfsexp
28939 }
28940
28941 test_817() {
28942         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28943
28944         mkdir -p $DIR/nfsexp
28945         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28946                 error "failed to export nfs"
28947
28948         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28949         stack_trap cleanup_817 EXIT
28950
28951         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28952                 error "failed to mount nfs to $tmpdir"
28953
28954         cp /bin/true $tmpdir
28955         $DIR/nfsexp/true || error "failed to execute 'true' command"
28956 }
28957 run_test 817 "nfsd won't cache write lock for exec file"
28958
28959 test_818() {
28960         test_mkdir -i0 -c1 $DIR/$tdir
28961         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28962         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28963         stop $SINGLEMDS
28964
28965         # restore osp-syn threads
28966         stack_trap "fail $SINGLEMDS"
28967
28968         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28969         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28970         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28971                 error "start $SINGLEMDS failed"
28972         rm -rf $DIR/$tdir
28973
28974         local testid=$(echo $TESTNAME | tr '_' ' ')
28975
28976         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28977                 grep "run LFSCK" || error "run LFSCK is not suggested"
28978 }
28979 run_test 818 "unlink with failed llog"
28980
28981 test_819a() {
28982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28983         cancel_lru_locks osc
28984         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28985         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28986         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28987         rm -f $TDIR/$tfile
28988 }
28989 run_test 819a "too big niobuf in read"
28990
28991 test_819b() {
28992         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28993         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28994         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28995         cancel_lru_locks osc
28996         sleep 1
28997         rm -f $TDIR/$tfile
28998 }
28999 run_test 819b "too big niobuf in write"
29000
29001
29002 function test_820_start_ost() {
29003         sleep 5
29004
29005         for num in $(seq $OSTCOUNT); do
29006                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29007         done
29008 }
29009
29010 test_820() {
29011         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29012
29013         mkdir $DIR/$tdir
29014         umount_client $MOUNT || error "umount failed"
29015         for num in $(seq $OSTCOUNT); do
29016                 stop ost$num
29017         done
29018
29019         # mount client with no active OSTs
29020         # so that the client can't initialize max LOV EA size
29021         # from OSC notifications
29022         mount_client $MOUNT || error "mount failed"
29023         # delay OST starting to keep this 0 max EA size for a while
29024         test_820_start_ost &
29025
29026         # create a directory on MDS2
29027         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29028                 error "Failed to create directory"
29029         # open intent should update default EA size
29030         # see mdc_update_max_ea_from_body()
29031         # notice this is the very first RPC to MDS2
29032         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29033         ret=$?
29034         echo $out
29035         # With SSK, this situation can lead to -EPERM being returned.
29036         # In that case, simply retry.
29037         if [ $ret -ne 0 ] && $SHARED_KEY; then
29038                 if echo "$out" | grep -q "not permitted"; then
29039                         cp /etc/services $DIR/$tdir/mds2
29040                         ret=$?
29041                 fi
29042         fi
29043         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29044 }
29045 run_test 820 "update max EA from open intent"
29046
29047 test_823() {
29048         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29049         local OST_MAX_PRECREATE=20000
29050
29051         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29052                 skip "Need MDS version at least 2.14.56"
29053
29054         save_lustre_params mds1 \
29055                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29056         do_facet $SINGLEMDS "$LCTL set_param -n \
29057                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29058         do_facet $SINGLEMDS "$LCTL set_param -n \
29059                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29060
29061         stack_trap "restore_lustre_params < $p; rm $p"
29062
29063         do_facet $SINGLEMDS "$LCTL set_param -n \
29064                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29065
29066         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29067                       osp.$FSNAME-OST0000*MDT0000.create_count")
29068         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29069                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29070         local expect_count=$(((($max/2)/256) * 256))
29071
29072         log "setting create_count to 100200:"
29073         log " -result- count: $count with max: $max, expecting: $expect_count"
29074
29075         [[ $count -eq expect_count ]] ||
29076                 error "Create count not set to max precreate."
29077 }
29078 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29079
29080 test_831() {
29081         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29082                 skip "Need MDS version 2.14.56"
29083
29084         local sync_changes=$(do_facet $SINGLEMDS \
29085                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29086
29087         [ "$sync_changes" -gt 100 ] &&
29088                 skip "Sync changes $sync_changes > 100 already"
29089
29090         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29091
29092         $LFS mkdir -i 0 $DIR/$tdir
29093         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29094
29095         save_lustre_params mds1 \
29096                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29097         save_lustre_params mds1 \
29098                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29099
29100         do_facet mds1 "$LCTL set_param -n \
29101                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29102                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29103         stack_trap "restore_lustre_params < $p" EXIT
29104
29105         createmany -o $DIR/$tdir/f- 1000
29106         unlinkmany $DIR/$tdir/f- 1000 &
29107         local UNLINK_PID=$!
29108
29109         while sleep 1; do
29110                 sync_changes=$(do_facet mds1 \
29111                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29112                 # the check in the code is racy, fail the test
29113                 # if the value above the limit by 10.
29114                 [ $sync_changes -gt 110 ] && {
29115                         kill -2 $UNLINK_PID
29116                         wait
29117                         error "osp changes throttling failed, $sync_changes>110"
29118                 }
29119                 kill -0 $UNLINK_PID 2> /dev/null || break
29120         done
29121         wait
29122 }
29123 run_test 831 "throttling unlink/setattr queuing on OSP"
29124
29125 test_832() {
29126         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29127         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29128                 skip "Need MDS version 2.15.52+"
29129         is_rmentry_supported || skip "rm_entry not supported"
29130
29131         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29132         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29133         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29134                 error "mkdir remote_dir failed"
29135         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29136                 error "mkdir striped_dir failed"
29137         touch $DIR/$tdir/file || error "touch file failed"
29138         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29139         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29140 }
29141 run_test 832 "lfs rm_entry"
29142
29143 #
29144 # tests that do cleanup/setup should be run at the end
29145 #
29146
29147 test_900() {
29148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29149         local ls
29150
29151         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29152         $LCTL set_param fail_loc=0x903
29153
29154         cancel_lru_locks MGC
29155
29156         FAIL_ON_ERROR=true cleanup
29157         FAIL_ON_ERROR=true setup
29158 }
29159 run_test 900 "umount should not race with any mgc requeue thread"
29160
29161 # LUS-6253/LU-11185
29162 test_901() {
29163         local old
29164         local count
29165         local oldc
29166         local newc
29167         local olds
29168         local news
29169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29170
29171         # some get_param have a bug to handle dot in param name
29172         cancel_lru_locks MGC
29173         old=$(mount -t lustre | wc -l)
29174         # 1 config+sptlrpc
29175         # 2 params
29176         # 3 nodemap
29177         # 4 IR
29178         old=$((old * 4))
29179         oldc=0
29180         count=0
29181         while [ $old -ne $oldc ]; do
29182                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29183                 sleep 1
29184                 ((count++))
29185                 if [ $count -ge $TIMEOUT ]; then
29186                         error "too large timeout"
29187                 fi
29188         done
29189         umount_client $MOUNT || error "umount failed"
29190         mount_client $MOUNT || error "mount failed"
29191         cancel_lru_locks MGC
29192         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29193
29194         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29195
29196         return 0
29197 }
29198 run_test 901 "don't leak a mgc lock on client umount"
29199
29200 # LU-13377
29201 test_902() {
29202         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29203                 skip "client does not have LU-13377 fix"
29204         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29205         $LCTL set_param fail_loc=0x1415
29206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29207         cancel_lru_locks osc
29208         rm -f $DIR/$tfile
29209 }
29210 run_test 902 "test short write doesn't hang lustre"
29211
29212 # LU-14711
29213 test_903() {
29214         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29215         echo "blah" > $DIR/${tfile}-2
29216         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29217         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29218         $LCTL set_param fail_loc=0x417 fail_val=20
29219
29220         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29221         sleep 1 # To start the destroy
29222         wait_destroy_complete 150 || error "Destroy taking too long"
29223         cat $DIR/$tfile > /dev/null || error "Evicted"
29224 }
29225 run_test 903 "Test long page discard does not cause evictions"
29226
29227 test_904() {
29228         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29229         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29230                 grep -q project || skip "skip project quota not supported"
29231
29232         local testfile="$DIR/$tdir/$tfile"
29233         local xattr="trusted.projid"
29234         local projid
29235         local mdts=$(comma_list $(mdts_nodes))
29236         local saved=$(do_facet mds1 $LCTL get_param -n \
29237                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29238
29239         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29240         stack_trap "do_nodes $mdts $LCTL set_param \
29241                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29242
29243         mkdir -p $DIR/$tdir
29244         touch $testfile
29245         #hide projid xattr on server
29246         $LFS project -p 1 $testfile ||
29247                 error "set $testfile project id failed"
29248         getfattr -m - $testfile | grep $xattr &&
29249                 error "do not show trusted.projid when disabled on server"
29250         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29251         #should be hidden when projid is 0
29252         $LFS project -p 0 $testfile ||
29253                 error "set $testfile project id failed"
29254         getfattr -m - $testfile | grep $xattr &&
29255                 error "do not show trusted.projid with project ID 0"
29256
29257         #still can getxattr explicitly
29258         projid=$(getfattr -n $xattr $testfile |
29259                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29260         [ $projid == "0" ] ||
29261                 error "projid expected 0 not $projid"
29262
29263         #set the projid via setxattr
29264         setfattr -n $xattr -v "1000" $testfile ||
29265                 error "setattr failed with $?"
29266         projid=($($LFS project $testfile))
29267         [ ${projid[0]} == "1000" ] ||
29268                 error "projid expected 1000 not $projid"
29269
29270         #check the new projid via getxattr
29271         $LFS project -p 1001 $testfile ||
29272                 error "set $testfile project id failed"
29273         getfattr -m - $testfile | grep $xattr ||
29274                 error "should show trusted.projid when project ID != 0"
29275         projid=$(getfattr -n $xattr $testfile |
29276                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29277         [ $projid == "1001" ] ||
29278                 error "projid expected 1001 not $projid"
29279
29280         #try to set invalid projid
29281         setfattr -n $xattr -v "4294967295" $testfile &&
29282                 error "set invalid projid should fail"
29283
29284         #remove the xattr means setting projid to 0
29285         setfattr -x $xattr $testfile ||
29286                 error "setfattr failed with $?"
29287         projid=($($LFS project $testfile))
29288         [ ${projid[0]} == "0" ] ||
29289                 error "projid expected 0 not $projid"
29290
29291         #should be hidden when parent has inherit flag and same projid
29292         $LFS project -srp 1002 $DIR/$tdir ||
29293                 error "set $tdir project id failed"
29294         getfattr -m - $testfile | grep $xattr &&
29295                 error "do not show trusted.projid with inherit flag"
29296
29297         #still can getxattr explicitly
29298         projid=$(getfattr -n $xattr $testfile |
29299                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29300         [ $projid == "1002" ] ||
29301                 error "projid expected 1002 not $projid"
29302 }
29303 run_test 904 "virtual project ID xattr"
29304
29305 # LU-8582
29306 test_905() {
29307         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29308                 skip "lustre < 2.8.54 does not support ladvise"
29309
29310         remote_ost_nodsh && skip "remote OST with nodsh"
29311         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29312
29313         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29314
29315         #define OBD_FAIL_OST_OPCODE 0x253
29316         # OST_LADVISE = 21
29317         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29318         $LFS ladvise -a willread $DIR/$tfile &&
29319                 error "unexpected success of ladvise with fault injection"
29320         $LFS ladvise -a willread $DIR/$tfile |&
29321                 grep -q "Operation not supported"
29322         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29323 }
29324 run_test 905 "bad or new opcode should not stuck client"
29325
29326 test_906() {
29327         grep -q io_uring_setup /proc/kallsyms ||
29328                 skip "Client OS does not support io_uring I/O engine"
29329         io_uring_probe || skip "kernel does not support io_uring fully"
29330         which fio || skip_env "no fio installed"
29331         fio --enghelp | grep -q io_uring ||
29332                 skip_env "fio does not support io_uring I/O engine"
29333
29334         local file=$DIR/$tfile
29335         local ioengine="io_uring"
29336         local numjobs=2
29337         local size=50M
29338
29339         fio --name=seqwrite --ioengine=$ioengine        \
29340                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29341                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29342                 error "fio seqwrite $file failed"
29343
29344         fio --name=seqread --ioengine=$ioengine \
29345                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29346                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29347                 error "fio seqread $file failed"
29348
29349         rm -f $file || error "rm -f $file failed"
29350 }
29351 run_test 906 "Simple test for io_uring I/O engine via fio"
29352
29353
29354 complete $SECONDS
29355 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29356 check_and_cleanup_lustre
29357 if [ "$I_MOUNTED" != "yes" ]; then
29358         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29359 fi
29360 exit_status