Whamcloud - gitweb
LU-16210 llite: replace selinux_is_enabled()
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-9054  312
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 #                                  5              12     8   12  15   (min)"
67 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
68
69 if [ "$mds1_FSTYPE" = "zfs" ]; then
70         #                                               13    (min)"
71         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
72 fi
73
74 if [ "$ost1_FSTYPE" = "zfs" ]; then
75         always_except LU-1941 130b 130c 130d 130e 130f 130g
76 fi
77
78 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
79
80 # Get the SLES distro version
81 #
82 # Returns a version string that should only be used in comparing
83 # strings returned by version_code()
84 sles_version_code()
85 {
86         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
87
88         # All SuSE Linux versions have one decimal. version_code expects two
89         local sles_version=$version.0
90         version_code $sles_version
91 }
92
93 # Check if we are running on Ubuntu or SLES so we can make decisions on
94 # what tests to run
95 if [ -r /etc/SuSE-release ]; then
96         sles_version=$(sles_version_code)
97         [ $sles_version -lt $(version_code 11.4.0) ] &&
98                 always_except LU-4341 170
99
100         [ $sles_version -lt $(version_code 12.0.0) ] &&
101                 always_except LU-3703 234
102 elif [ -r /etc/os-release ]; then
103         if grep -qi ubuntu /etc/os-release; then
104                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
105                                                 -e 's/^VERSION=//p' \
106                                                 /etc/os-release |
107                                                 awk '{ print $1 }'))
108
109                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
110                         always_except LU-10366 410
111                 fi
112         fi
113 fi
114
115 build_test_filter
116 FAIL_ON_ERROR=false
117
118 cleanup() {
119         echo -n "cln.."
120         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
121         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
122 }
123 setup() {
124         echo -n "mnt.."
125         load_modules
126         setupall || exit 10
127         echo "done"
128 }
129
130 check_swap_layouts_support()
131 {
132         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
133                 skip "Does not support layout lock."
134 }
135
136 check_swap_layout_no_dom()
137 {
138         local FOLDER=$1
139         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
140         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
141 }
142
143 check_and_setup_lustre
144 DIR=${DIR:-$MOUNT}
145 assert_DIR
146
147 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
148
149 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
150 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
151 rm -rf $DIR/[Rdfs][0-9]*
152
153 # $RUNAS_ID may get set incorrectly somewhere else
154 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
155         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
156
157 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
158
159 if [ "${ONLY}" = "MOUNT" ] ; then
160         echo "Lustre is up, please go on"
161         exit
162 fi
163
164 echo "preparing for tests involving mounts"
165 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
166 touch $EXT2_DEV
167 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
168 echo # add a newline after mke2fs.
169
170 umask 077
171
172 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
173 lctl set_param debug=-1 2> /dev/null || true
174 test_0a() {
175         touch $DIR/$tfile
176         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
177         rm $DIR/$tfile
178         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
179 }
180 run_test 0a "touch; rm ====================="
181
182 test_0b() {
183         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
184         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
185 }
186 run_test 0b "chmod 0755 $DIR ============================="
187
188 test_0c() {
189         $LCTL get_param mdc.*.import | grep "state: FULL" ||
190                 error "import not FULL"
191         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
192                 error "bad target"
193 }
194 run_test 0c "check import proc"
195
196 test_0d() { # LU-3397
197         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
198                 skip "proc exports not supported before 2.10.57"
199
200         local mgs_exp="mgs.MGS.exports"
201         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
202         local exp_client_nid
203         local exp_client_version
204         local exp_val
205         local imp_val
206         local temp_imp=$DIR/$tfile.import
207         local temp_exp=$DIR/$tfile.export
208
209         # save mgc import file to $temp_imp
210         $LCTL get_param mgc.*.import | tee $temp_imp
211         # Check if client uuid is found in MGS export
212         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
213                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
214                         $client_uuid ] &&
215                         break;
216         done
217         # save mgs export file to $temp_exp
218         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
219
220         # Compare the value of field "connect_flags"
221         imp_val=$(grep "connect_flags" $temp_imp)
222         exp_val=$(grep "connect_flags" $temp_exp)
223         [ "$exp_val" == "$imp_val" ] ||
224                 error "export flags '$exp_val' != import flags '$imp_val'"
225
226         # Compare client versions.  Only compare top-3 fields for compatibility
227         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
228         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
229         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
230         [ "$exp_val" == "$imp_val" ] ||
231                 error "exp version '$exp_client_version'($exp_val) != " \
232                         "'$(lustre_build_version client)'($imp_val)"
233 }
234 run_test 0d "check export proc ============================="
235
236 test_0e() { # LU-13417
237         (( $MDSCOUNT > 1 )) ||
238                 skip "We need at least 2 MDTs for this test"
239
240         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
241                 skip "Need server version at least 2.14.51"
242
243         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
244         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
245
246         [ $default_lmv_count -eq 1 ] ||
247                 error "$MOUNT default stripe count $default_lmv_count"
248
249         [ $default_lmv_index -eq -1 ] ||
250                 error "$MOUNT default stripe index $default_lmv_index"
251
252         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
253         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
254
255         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
256         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
257
258         [ $mdt_index1 -eq $mdt_index2 ] &&
259                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
260
261         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
262 }
263 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
264
265 test_1() {
266         test_mkdir $DIR/$tdir
267         test_mkdir $DIR/$tdir/d2
268         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
269         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
270         rmdir $DIR/$tdir/d2
271         rmdir $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
273 }
274 run_test 1 "mkdir; remkdir; rmdir"
275
276 test_2() {
277         test_mkdir $DIR/$tdir
278         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
279         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
280         rm -r $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
282 }
283 run_test 2 "mkdir; touch; rmdir; check file"
284
285 test_3() {
286         test_mkdir $DIR/$tdir
287         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
288         touch $DIR/$tdir/$tfile
289         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
290         rm -r $DIR/$tdir
291         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
292 }
293 run_test 3 "mkdir; touch; rmdir; check dir"
294
295 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
296 test_4() {
297         test_mkdir -i 1 $DIR/$tdir
298
299         touch $DIR/$tdir/$tfile ||
300                 error "Create file under remote directory failed"
301
302         rmdir $DIR/$tdir &&
303                 error "Expect error removing in-use dir $DIR/$tdir"
304
305         test -d $DIR/$tdir || error "Remote directory disappeared"
306
307         rm -rf $DIR/$tdir || error "remove remote dir error"
308 }
309 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
310
311 test_5() {
312         test_mkdir $DIR/$tdir
313         test_mkdir $DIR/$tdir/d2
314         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
315         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
316         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
317 }
318 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
319
320 test_6a() {
321         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
322         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
323         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
324                 error "$tfile does not have perm 0666 or UID $UID"
325         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile should be 0666 and owned by UID $UID"
328 }
329 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
330
331 test_6c() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         touch $DIR/$tfile
335         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
336         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
337                 error "$tfile should be owned by UID $RUNAS_ID"
338         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341 }
342 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
343
344 test_6e() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by GID $UID"
351         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
354 }
355 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
356
357 test_6g() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         test_mkdir $DIR/$tdir
361         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
362         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
363         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
364         test_mkdir $DIR/$tdir/d/subdir
365         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
366                 error "$tdir/d/subdir should be GID $RUNAS_GID"
367         if [[ $MDSCOUNT -gt 1 ]]; then
368                 # check remote dir sgid inherite
369                 $LFS mkdir -i 0 $DIR/$tdir.local ||
370                         error "mkdir $tdir.local failed"
371                 chmod g+s $DIR/$tdir.local ||
372                         error "chmod $tdir.local failed"
373                 chgrp $RUNAS_GID $DIR/$tdir.local ||
374                         error "chgrp $tdir.local failed"
375                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
376                         error "mkdir $tdir.remote failed"
377                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
378                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
379                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
380                         error "$tdir.remote should be mode 02755"
381         fi
382 }
383 run_test 6g "verify new dir in sgid dir inherits group"
384
385 test_6h() { # bug 7331
386         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
387
388         touch $DIR/$tfile || error "touch failed"
389         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
390         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
391                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
392         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
393                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
394 }
395 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
396
397 test_7a() {
398         test_mkdir $DIR/$tdir
399         $MCREATE $DIR/$tdir/$tfile
400         chmod 0666 $DIR/$tdir/$tfile
401         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
402                 error "$tdir/$tfile should be mode 0666"
403 }
404 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
405
406 test_7b() {
407         if [ ! -d $DIR/$tdir ]; then
408                 test_mkdir $DIR/$tdir
409         fi
410         $MCREATE $DIR/$tdir/$tfile
411         echo -n foo > $DIR/$tdir/$tfile
412         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
413         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
414 }
415 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
416
417 test_8() {
418         test_mkdir $DIR/$tdir
419         touch $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tfile mode not 0666"
423 }
424 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
425
426 test_9() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         test_mkdir $DIR/$tdir/d2/d3
430         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
431 }
432 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
433
434 test_10() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         touch $DIR/$tdir/d2/$tfile
438         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
439                 error "$tdir/d2/$tfile not a file"
440 }
441 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
442
443 test_11() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         chmod 0666 $DIR/$tdir/d2
447         chmod 0705 $DIR/$tdir/d2
448         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
449                 error "$tdir/d2 mode not 0705"
450 }
451 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
452
453 test_12() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         chmod 0666 $DIR/$tdir/$tfile
457         chmod 0654 $DIR/$tdir/$tfile
458         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
459                 error "$tdir/d2 mode not 0654"
460 }
461 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
462
463 test_13() {
464         test_mkdir $DIR/$tdir
465         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
466         >  $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
468                 error "$tdir/$tfile size not 0 after truncate"
469 }
470 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
471
472 test_14() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         rm $DIR/$tdir/$tfile
476         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
477 }
478 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
479
480 test_15() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
484         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
485                 error "$tdir/${tfile_2} not a file after rename"
486         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
487 }
488 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
489
490 test_16() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         rm -rf $DIR/$tdir/$tfile
494         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
495 }
496 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
497
498 test_17a() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
502         ls -l $DIR/$tdir
503         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
504                 error "$tdir/l-exist not a symlink"
505         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
506                 error "$tdir/l-exist not referencing a file"
507         rm -f $DIR/$tdir/l-exist
508         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
509 }
510 run_test 17a "symlinks: create, remove (real)"
511
512 test_17b() {
513         test_mkdir $DIR/$tdir
514         ln -s no-such-file $DIR/$tdir/l-dangle
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
517                 error "$tdir/l-dangle not referencing no-such-file"
518         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
519                 error "$tdir/l-dangle not referencing non-existent file"
520         rm -f $DIR/$tdir/l-dangle
521         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
522 }
523 run_test 17b "symlinks: create, remove (dangling)"
524
525 test_17c() { # bug 3440 - don't save failed open RPC for replay
526         test_mkdir $DIR/$tdir
527         ln -s foo $DIR/$tdir/$tfile
528         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
529 }
530 run_test 17c "symlinks: open dangling (should return error)"
531
532 test_17d() {
533         test_mkdir $DIR/$tdir
534         ln -s foo $DIR/$tdir/$tfile
535         touch $DIR/$tdir/$tfile || error "creating to new symlink"
536 }
537 run_test 17d "symlinks: create dangling"
538
539 test_17e() {
540         test_mkdir $DIR/$tdir
541         local foo=$DIR/$tdir/$tfile
542         ln -s $foo $foo || error "create symlink failed"
543         ls -l $foo || error "ls -l failed"
544         ls $foo && error "ls not failed" || true
545 }
546 run_test 17e "symlinks: create recursive symlink (should return error)"
547
548 test_17f() {
549         test_mkdir $DIR/$tdir
550         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
556         ls -l  $DIR/$tdir
557 }
558 run_test 17f "symlinks: long and very long symlink name"
559
560 # str_repeat(S, N) generate a string that is string S repeated N times
561 str_repeat() {
562         local s=$1
563         local n=$2
564         local ret=''
565         while [ $((n -= 1)) -ge 0 ]; do
566                 ret=$ret$s
567         done
568         echo $ret
569 }
570
571 # Long symlinks and LU-2241
572 test_17g() {
573         test_mkdir $DIR/$tdir
574         local TESTS="59 60 61 4094 4095"
575
576         # Fix for inode size boundary in 2.1.4
577         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
578                 TESTS="4094 4095"
579
580         # Patch not applied to 2.2 or 2.3 branches
581         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
582         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
583                 TESTS="4094 4095"
584
585         for i in $TESTS; do
586                 local SYMNAME=$(str_repeat 'x' $i)
587                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
588                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
589         done
590 }
591 run_test 17g "symlinks: really long symlink name and inode boundaries"
592
593 test_17h() { #bug 17378
594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
595         remote_mds_nodsh && skip "remote MDS with nodsh"
596
597         local mdt_idx
598
599         test_mkdir $DIR/$tdir
600         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
601         $LFS setstripe -c -1 $DIR/$tdir
602         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
603         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
604         touch $DIR/$tdir/$tfile || true
605 }
606 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
607
608 test_17i() { #bug 20018
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         remote_mds_nodsh && skip "remote MDS with nodsh"
611
612         local foo=$DIR/$tdir/$tfile
613         local mdt_idx
614
615         test_mkdir -c1 $DIR/$tdir
616         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
617         ln -s $foo $foo || error "create symlink failed"
618 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
619         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
620         ls -l $foo && error "error not detected"
621         return 0
622 }
623 run_test 17i "don't panic on short symlink (should return error)"
624
625 test_17k() { #bug 22301
626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
627         [[ -z "$(which rsync 2>/dev/null)" ]] &&
628                 skip "no rsync command"
629         rsync --help | grep -q xattr ||
630                 skip_env "$(rsync --version | head -n1) does not support xattrs"
631         test_mkdir $DIR/$tdir
632         test_mkdir $DIR/$tdir.new
633         touch $DIR/$tdir/$tfile
634         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
635         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
636                 error "rsync failed with xattrs enabled"
637 }
638 run_test 17k "symlinks: rsync with xattrs enabled"
639
640 test_17l() { # LU-279
641         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
642                 skip "no getfattr command"
643
644         test_mkdir $DIR/$tdir
645         touch $DIR/$tdir/$tfile
646         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
647         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
648                 # -h to not follow symlinks. -m '' to list all the xattrs.
649                 # grep to remove first line: '# file: $path'.
650                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
651                 do
652                         lgetxattr_size_check $path $xattr ||
653                                 error "lgetxattr_size_check $path $xattr failed"
654                 done
655         done
656 }
657 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
658
659 # LU-1540
660 test_17m() {
661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
663         remote_mds_nodsh && skip "remote MDS with nodsh"
664         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
665         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
666                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
667
668         local short_sym="0123456789"
669         local wdir=$DIR/$tdir
670         local i
671
672         test_mkdir $wdir
673         long_sym=$short_sym
674         # create a long symlink file
675         for ((i = 0; i < 4; ++i)); do
676                 long_sym=${long_sym}${long_sym}
677         done
678
679         echo "create 512 short and long symlink files under $wdir"
680         for ((i = 0; i < 256; ++i)); do
681                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
682                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
683         done
684
685         echo "erase them"
686         rm -f $wdir/*
687         sync
688         wait_delete_completed
689
690         echo "recreate the 512 symlink files with a shorter string"
691         for ((i = 0; i < 512; ++i)); do
692                 # rewrite the symlink file with a shorter string
693                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
694                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
695         done
696
697         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
698
699         echo "stop and checking mds${mds_index}:"
700         # e2fsck should not return error
701         stop mds${mds_index}
702         local devname=$(mdsdevname $mds_index)
703         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
704         rc=$?
705
706         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
707                 error "start mds${mds_index} failed"
708         df $MOUNT > /dev/null 2>&1
709         [ $rc -eq 0 ] ||
710                 error "e2fsck detected error for short/long symlink: rc=$rc"
711         rm -f $wdir/*
712 }
713 run_test 17m "run e2fsck against MDT which contains short/long symlink"
714
715 check_fs_consistency_17n() {
716         local mdt_index
717         local rc=0
718
719         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
720         # so it only check MDT1/MDT2 instead of all of MDTs.
721         for mdt_index in 1 2; do
722                 # e2fsck should not return error
723                 stop mds${mdt_index}
724                 local devname=$(mdsdevname $mdt_index)
725                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
726                         rc=$((rc + $?))
727
728                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
729                         error "mount mds$mdt_index failed"
730                 df $MOUNT > /dev/null 2>&1
731         done
732         return $rc
733 }
734
735 test_17n() {
736         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
738         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
739         remote_mds_nodsh && skip "remote MDS with nodsh"
740         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
741         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
742                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
743
744         local i
745
746         test_mkdir $DIR/$tdir
747         for ((i=0; i<10; i++)); do
748                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
749                         error "create remote dir error $i"
750                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
751                         error "create files under remote dir failed $i"
752         done
753
754         check_fs_consistency_17n ||
755                 error "e2fsck report error after create files under remote dir"
756
757         for ((i = 0; i < 10; i++)); do
758                 rm -rf $DIR/$tdir/remote_dir_${i} ||
759                         error "destroy remote dir error $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after unlink files under remote dir"
764
765         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
766                 skip "lustre < 2.4.50 does not support migrate mv"
767
768         for ((i = 0; i < 10; i++)); do
769                 mkdir -p $DIR/$tdir/remote_dir_${i}
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
773                         error "migrate remote dir error $i"
774         done
775         check_fs_consistency_17n || error "e2fsck report error after migration"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n || error "e2fsck report error after unlink"
783 }
784 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
785
786 test_17o() {
787         remote_mds_nodsh && skip "remote MDS with nodsh"
788         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
789                 skip "Need MDS version at least 2.3.64"
790
791         local wdir=$DIR/${tdir}o
792         local mdt_index
793         local rc=0
794
795         test_mkdir $wdir
796         touch $wdir/$tfile
797         mdt_index=$($LFS getstripe -m $wdir/$tfile)
798         mdt_index=$((mdt_index + 1))
799
800         cancel_lru_locks mdc
801         #fail mds will wait the failover finish then set
802         #following fail_loc to avoid interfer the recovery process.
803         fail mds${mdt_index}
804
805         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
806         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
807         ls -l $wdir/$tfile && rc=1
808         do_facet mds${mdt_index} lctl set_param fail_loc=0
809         [[ $rc -eq 0 ]] || error "stat file should fail"
810 }
811 run_test 17o "stat file with incompat LMA feature"
812
813 test_18() {
814         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
815         ls $DIR || error "Failed to ls $DIR: $?"
816 }
817 run_test 18 "touch .../f ; ls ... =============================="
818
819 test_19a() {
820         touch $DIR/$tfile
821         ls -l $DIR
822         rm $DIR/$tfile
823         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
824 }
825 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
826
827 test_19b() {
828         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
829 }
830 run_test 19b "ls -l .../f19 (should return error) =============="
831
832 test_19c() {
833         [ $RUNAS_ID -eq $UID ] &&
834                 skip_env "RUNAS_ID = UID = $UID -- skipping"
835
836         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
837 }
838 run_test 19c "$RUNAS touch .../f19 (should return error) =="
839
840 test_19d() {
841         cat $DIR/f19 && error || true
842 }
843 run_test 19d "cat .../f19 (should return error) =============="
844
845 test_20() {
846         touch $DIR/$tfile
847         rm $DIR/$tfile
848         touch $DIR/$tfile
849         rm $DIR/$tfile
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
853 }
854 run_test 20 "touch .../f ; ls -l ..."
855
856 test_21() {
857         test_mkdir $DIR/$tdir
858         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
859         ln -s dangle $DIR/$tdir/link
860         echo foo >> $DIR/$tdir/link
861         cat $DIR/$tdir/dangle
862         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
863         $CHECKSTAT -f -t file $DIR/$tdir/link ||
864                 error "$tdir/link not linked to a file"
865 }
866 run_test 21 "write to dangling link"
867
868 test_22() {
869         local wdir=$DIR/$tdir
870         test_mkdir $wdir
871         chown $RUNAS_ID:$RUNAS_GID $wdir
872         (cd $wdir || error "cd $wdir failed";
873                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
874                 $RUNAS tar xf -)
875         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
876         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
877         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
878                 error "checkstat -u failed"
879 }
880 run_test 22 "unpack tar archive as non-root user"
881
882 # was test_23
883 test_23a() {
884         test_mkdir $DIR/$tdir
885         local file=$DIR/$tdir/$tfile
886
887         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
888         openfile -f O_CREAT:O_EXCL $file &&
889                 error "$file recreate succeeded" || true
890 }
891 run_test 23a "O_CREAT|O_EXCL in subdir"
892
893 test_23b() { # bug 18988
894         test_mkdir $DIR/$tdir
895         local file=$DIR/$tdir/$tfile
896
897         rm -f $file
898         echo foo > $file || error "write filed"
899         echo bar >> $file || error "append filed"
900         $CHECKSTAT -s 8 $file || error "wrong size"
901         rm $file
902 }
903 run_test 23b "O_APPEND check"
904
905 # LU-9409, size with O_APPEND and tiny writes
906 test_23c() {
907         local file=$DIR/$tfile
908
909         # single dd
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
911         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
912         rm -f $file
913
914         # racing tiny writes
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
917         wait
918         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
919         rm -f $file
920
921         #racing tiny & normal writes
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
924         wait
925         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
926         rm -f $file
927
928         #racing tiny & normal writes 2, ugly numbers
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
931         wait
932         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
933         rm -f $file
934 }
935 run_test 23c "O_APPEND size checks for tiny writes"
936
937 # LU-11069 file offset is correct after appending writes
938 test_23d() {
939         local file=$DIR/$tfile
940         local offset
941
942         echo CentaurHauls > $file
943         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
944         if ((offset != 26)); then
945                 error "wrong offset, expected 26, got '$offset'"
946         fi
947 }
948 run_test 23d "file offset is correct after appending writes"
949
950 # rename sanity
951 test_24a() {
952         echo '-- same directory rename'
953         test_mkdir $DIR/$tdir
954         touch $DIR/$tdir/$tfile.1
955         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
956         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
957 }
958 run_test 24a "rename file to non-existent target"
959
960 test_24b() {
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.{1,2}
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24b "rename file to existing target"
968
969 test_24c() {
970         test_mkdir $DIR/$tdir
971         test_mkdir $DIR/$tdir/d$testnum.1
972         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
973         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
974         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
975 }
976 run_test 24c "rename directory to non-existent target"
977
978 test_24d() {
979         test_mkdir -c1 $DIR/$tdir
980         test_mkdir -c1 $DIR/$tdir/d$testnum.1
981         test_mkdir -c1 $DIR/$tdir/d$testnum.2
982         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
983         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
984         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
985 }
986 run_test 24d "rename directory to existing target"
987
988 test_24e() {
989         echo '-- cross directory renames --'
990         test_mkdir $DIR/R5a
991         test_mkdir $DIR/R5b
992         touch $DIR/R5a/f
993         mv $DIR/R5a/f $DIR/R5b/g
994         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
995         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
996 }
997 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
998
999 test_24f() {
1000         test_mkdir $DIR/R6a
1001         test_mkdir $DIR/R6b
1002         touch $DIR/R6a/f $DIR/R6b/g
1003         mv $DIR/R6a/f $DIR/R6b/g
1004         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1005         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1006 }
1007 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1008
1009 test_24g() {
1010         test_mkdir $DIR/R7a
1011         test_mkdir $DIR/R7b
1012         test_mkdir $DIR/R7a/d
1013         mv $DIR/R7a/d $DIR/R7b/e
1014         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1015         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1016 }
1017 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1018
1019 test_24h() {
1020         test_mkdir -c1 $DIR/R8a
1021         test_mkdir -c1 $DIR/R8b
1022         test_mkdir -c1 $DIR/R8a/d
1023         test_mkdir -c1 $DIR/R8b/e
1024         mrename $DIR/R8a/d $DIR/R8b/e
1025         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1026         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1027 }
1028 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1029
1030 test_24i() {
1031         echo "-- rename error cases"
1032         test_mkdir $DIR/R9
1033         test_mkdir $DIR/R9/a
1034         touch $DIR/R9/f
1035         mrename $DIR/R9/f $DIR/R9/a
1036         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1037         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1038         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1039 }
1040 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1041
1042 test_24j() {
1043         test_mkdir $DIR/R10
1044         mrename $DIR/R10/f $DIR/R10/g
1045         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1046         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1047         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1048 }
1049 run_test 24j "source does not exist ============================"
1050
1051 test_24k() {
1052         test_mkdir $DIR/R11a
1053         test_mkdir $DIR/R11a/d
1054         touch $DIR/R11a/f
1055         mv $DIR/R11a/f $DIR/R11a/d
1056         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1057         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1058 }
1059 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1060
1061 # bug 2429 - rename foo foo foo creates invalid file
1062 test_24l() {
1063         f="$DIR/f24l"
1064         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1065 }
1066 run_test 24l "Renaming a file to itself ========================"
1067
1068 test_24m() {
1069         f="$DIR/f24m"
1070         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1071         # on ext3 this does not remove either the source or target files
1072         # though the "expected" operation would be to remove the source
1073         $CHECKSTAT -t file ${f} || error "${f} missing"
1074         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1075 }
1076 run_test 24m "Renaming a file to a hard link to itself ========="
1077
1078 test_24n() {
1079     f="$DIR/f24n"
1080     # this stats the old file after it was renamed, so it should fail
1081     touch ${f}
1082     $CHECKSTAT ${f} || error "${f} missing"
1083     mv ${f} ${f}.rename
1084     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1085     $CHECKSTAT -a ${f} || error "${f} exists"
1086 }
1087 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1088
1089 test_24o() {
1090         test_mkdir $DIR/$tdir
1091         rename_many -s random -v -n 10 $DIR/$tdir
1092 }
1093 run_test 24o "rename of files during htree split"
1094
1095 test_24p() {
1096         test_mkdir $DIR/R12a
1097         test_mkdir $DIR/R12b
1098         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1099         mrename $DIR/R12a $DIR/R12b
1100         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1101         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1102         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1103         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1104 }
1105 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1106
1107 cleanup_multiop_pause() {
1108         trap 0
1109         kill -USR1 $MULTIPID
1110 }
1111
1112 test_24q() {
1113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1114
1115         test_mkdir $DIR/R13a
1116         test_mkdir $DIR/R13b
1117         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1118         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1119         MULTIPID=$!
1120
1121         trap cleanup_multiop_pause EXIT
1122         mrename $DIR/R13a $DIR/R13b
1123         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1124         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1125         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1126         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1127         cleanup_multiop_pause
1128         wait $MULTIPID || error "multiop close failed"
1129 }
1130 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1131
1132 test_24r() { #bug 3789
1133         test_mkdir $DIR/R14a
1134         test_mkdir $DIR/R14a/b
1135         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1137         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1138 }
1139 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1140
1141 test_24s() {
1142         test_mkdir $DIR/R15a
1143         test_mkdir $DIR/R15a/b
1144         test_mkdir $DIR/R15a/b/c
1145         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1147         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1148 }
1149 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1150
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27d() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1716                 error "setstripe failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719 }
1720 run_test 27d "create file with default settings"
1721
1722 test_27e() {
1723         # LU-5839 adds check for existed layout before setting it
1724         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1725                 skip "Need MDS version at least 2.7.56"
1726
1727         test_mkdir $DIR/$tdir
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1729         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1730         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1731 }
1732 run_test 27e "setstripe existing file (should return error)"
1733
1734 test_27f() {
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1737                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1738         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1739                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1741         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1742 }
1743 run_test 27f "setstripe with bad stripe size (should return error)"
1744
1745 test_27g() {
1746         test_mkdir $DIR/$tdir
1747         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1748         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1749                 error "$DIR/$tdir/$tfile has object"
1750 }
1751 run_test 27g "$LFS getstripe with no objects"
1752
1753 test_27ga() {
1754         test_mkdir $DIR/$tdir
1755         touch $DIR/$tdir/$tfile || error "touch failed"
1756         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1757         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1758         local rc=$?
1759         (( rc == 2 )) || error "getstripe did not return ENOENT"
1760 }
1761 run_test 27ga "$LFS getstripe with missing file (should return error)"
1762
1763 test_27i() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1767                 error "missing objects"
1768 }
1769 run_test 27i "$LFS getstripe with some objects"
1770
1771 test_27j() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1774                 error "setstripe failed" || true
1775 }
1776 run_test 27j "setstripe with bad stripe offset (should return error)"
1777
1778 test_27k() { # bug 2844
1779         test_mkdir $DIR/$tdir
1780         local file=$DIR/$tdir/$tfile
1781         local ll_max_blksize=$((4 * 1024 * 1024))
1782         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1783         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1784         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1785         dd if=/dev/zero of=$file bs=4k count=1
1786         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1787         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1788 }
1789 run_test 27k "limit i_blksize for broken user apps"
1790
1791 test_27l() {
1792         mcreate $DIR/$tfile || error "creating file"
1793         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1794                 error "setstripe should have failed" || true
1795 }
1796 run_test 27l "check setstripe permissions (should return error)"
1797
1798 test_27m() {
1799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1800
1801         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1802                 skip_env "multiple clients -- skipping"
1803
1804         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1805                    head -n1)
1806         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1807                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1808         fi
1809         stack_trap simple_cleanup_common
1810         test_mkdir $DIR/$tdir
1811         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1813                 error "dd should fill OST0"
1814         i=2
1815         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1816                 i=$((i + 1))
1817                 [ $i -gt 256 ] && break
1818         done
1819         i=$((i + 1))
1820         touch $DIR/$tdir/$tfile.$i
1821         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1822             awk '{print $1}'| grep -w "0") ] &&
1823                 error "OST0 was full but new created file still use it"
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it" || true
1829 }
1830 run_test 27m "create file while OST0 was full"
1831
1832 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1833 # if the OST isn't full anymore.
1834 reset_enospc() {
1835         local ostidx=${1:-""}
1836         local delay
1837         local ready
1838         local get_prealloc
1839
1840         local list=$(comma_list $(osts_nodes))
1841         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1842
1843         do_nodes $list lctl set_param fail_loc=0
1844         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1845         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1846                 awk '{print $1 * 2;exit;}')
1847         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1848                         grep -v \"^0$\""
1849         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1850 }
1851
1852 test_27n() {
1853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1855         remote_mds_nodsh && skip "remote MDS with nodsh"
1856         remote_ost_nodsh && skip "remote OST with nodsh"
1857
1858         reset_enospc
1859         rm -f $DIR/$tdir/$tfile
1860         exhaust_precreations 0 0x80000215
1861         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1862         touch $DIR/$tdir/$tfile || error "touch failed"
1863         $LFS getstripe $DIR/$tdir/$tfile
1864         reset_enospc
1865 }
1866 run_test 27n "create file with some full OSTs"
1867
1868 test_27o() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876         exhaust_all_precreations 0x215
1877
1878         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1879
1880         reset_enospc
1881         rm -rf $DIR/$tdir/*
1882 }
1883 run_test 27o "create file with all full OSTs (should error)"
1884
1885 function create_and_checktime() {
1886         local fname=$1
1887         local loops=$2
1888         local i
1889
1890         for ((i=0; i < $loops; i++)); do
1891                 local start=$SECONDS
1892                 multiop $fname-$i Oc
1893                 ((SECONDS-start < TIMEOUT)) ||
1894                         error "creation took " $((SECONDS-$start)) && return 1
1895         done
1896 }
1897
1898 test_27oo() {
1899         local mdts=$(comma_list $(mdts_nodes))
1900
1901         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1902                 skip "Need MDS version at least 2.13.57"
1903
1904         local f0=$DIR/${tfile}-0
1905         local f1=$DIR/${tfile}-1
1906
1907         wait_delete_completed
1908
1909         # refill precreated objects
1910         $LFS setstripe -i0 -c1 $f0
1911
1912         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1913         # force QoS allocation policy
1914         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1915         stack_trap "do_nodes $mdts $LCTL set_param \
1916                 lov.*.qos_threshold_rr=$saved" EXIT
1917         sleep_maxage
1918
1919         # one OST is unavailable, but still have few objects preallocated
1920         stop ost1
1921         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1922                 rm -rf $f1 $DIR/$tdir*" EXIT
1923
1924         for ((i=0; i < 7; i++)); do
1925                 mkdir $DIR/$tdir$i || error "can't create dir"
1926                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1927                         error "can't set striping"
1928         done
1929         for ((i=0; i < 7; i++)); do
1930                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1931         done
1932         wait
1933 }
1934 run_test 27oo "don't let few threads to reserve too many objects"
1935
1936 test_27p() {
1937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1939         remote_mds_nodsh && skip "remote MDS with nodsh"
1940         remote_ost_nodsh && skip "remote OST with nodsh"
1941
1942         reset_enospc
1943         rm -f $DIR/$tdir/$tfile
1944         test_mkdir $DIR/$tdir
1945
1946         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1947         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1948         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1949
1950         exhaust_precreations 0 0x80000215
1951         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1952         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1953         $LFS getstripe $DIR/$tdir/$tfile
1954
1955         reset_enospc
1956 }
1957 run_test 27p "append to a truncated file with some full OSTs"
1958
1959 test_27q() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967
1968         mkdir_on_mdt0 $DIR/$tdir
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1971                 error "truncate $DIR/$tdir/$tfile failed"
1972         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1973
1974         exhaust_all_precreations 0x215
1975
1976         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1978
1979         reset_enospc
1980 }
1981 run_test 27q "append to truncated file with all OSTs full (should error)"
1982
1983 test_27r() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         exhaust_precreations 0 0x80000215
1992
1993         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1994
1995         reset_enospc
1996 }
1997 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1998
1999 test_27s() { # bug 10725
2000         test_mkdir $DIR/$tdir
2001         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2002         local stripe_count=0
2003         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2004         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2005                 error "stripe width >= 2^32 succeeded" || true
2006
2007 }
2008 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2009
2010 test_27t() { # bug 10864
2011         WDIR=$(pwd)
2012         WLFS=$(which lfs)
2013         cd $DIR
2014         touch $tfile
2015         $WLFS getstripe $tfile
2016         cd $WDIR
2017 }
2018 run_test 27t "check that utils parse path correctly"
2019
2020 test_27u() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023
2024         local index
2025         local list=$(comma_list $(mdts_nodes))
2026
2027 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2028         do_nodes $list $LCTL set_param fail_loc=0x139
2029         test_mkdir -p $DIR/$tdir
2030         stack_trap "simple_cleanup_common 1000"
2031         createmany -o $DIR/$tdir/$tfile 1000
2032         do_nodes $list $LCTL set_param fail_loc=0
2033
2034         TLOG=$TMP/$tfile.getstripe
2035         $LFS getstripe $DIR/$tdir > $TLOG
2036         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2037         [[ $OBJS -gt 0 ]] &&
2038                 error "$OBJS objects created on OST-0. See $TLOG" ||
2039                 rm -f $TLOG
2040 }
2041 run_test 27u "skip object creation on OSC w/o objects"
2042
2043 test_27v() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2046         remote_mds_nodsh && skip "remote MDS with nodsh"
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048
2049         exhaust_all_precreations 0x215
2050         reset_enospc
2051
2052         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2053
2054         touch $DIR/$tdir/$tfile
2055         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2056         # all except ost1
2057         for (( i=1; i < OSTCOUNT; i++ )); do
2058                 do_facet ost$i lctl set_param fail_loc=0x705
2059         done
2060         local START=`date +%s`
2061         createmany -o $DIR/$tdir/$tfile 32
2062
2063         local FINISH=`date +%s`
2064         local TIMEOUT=`lctl get_param -n timeout`
2065         local PROCESS=$((FINISH - START))
2066         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2067                error "$FINISH - $START >= $TIMEOUT / 2"
2068         sleep $((TIMEOUT / 2 - PROCESS))
2069         reset_enospc
2070 }
2071 run_test 27v "skip object creation on slow OST"
2072
2073 test_27w() { # bug 10997
2074         test_mkdir $DIR/$tdir
2075         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2076         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2077                 error "stripe size $size != 65536" || true
2078         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2079                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2080 }
2081 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2082
2083 test_27wa() {
2084         [[ $OSTCOUNT -lt 2 ]] &&
2085                 skip_env "skipping multiple stripe count/offset test"
2086
2087         test_mkdir $DIR/$tdir
2088         for i in $(seq 1 $OSTCOUNT); do
2089                 offset=$((i - 1))
2090                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2091                         error "setstripe -c $i -i $offset failed"
2092                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2093                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2094                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2095                 [ $index -ne $offset ] &&
2096                         error "stripe offset $index != $offset" || true
2097         done
2098 }
2099 run_test 27wa "check $LFS setstripe -c -i options"
2100
2101 test_27x() {
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         OFFSET=$(($OSTCOUNT - 1))
2107         OSTIDX=0
2108         local OST=$(ostname_from_index $OSTIDX)
2109
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2112         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2113         sleep_maxage
2114         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2115         for i in $(seq 0 $OFFSET); do
2116                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2117                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2118                 error "OST0 was degraded but new created file still use it"
2119         done
2120         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2121 }
2122 run_test 27x "create files while OST0 is degraded"
2123
2124 test_27y() {
2125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2126         remote_mds_nodsh && skip "remote MDS with nodsh"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2129
2130         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2131         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2132                 osp.$mdtosc.prealloc_last_id)
2133         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2134                 osp.$mdtosc.prealloc_next_id)
2135         local fcount=$((last_id - next_id))
2136         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2137         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2138
2139         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2140                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2141         local OST_DEACTIVE_IDX=-1
2142         local OSC
2143         local OSTIDX
2144         local OST
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2150                         OST_DEACTIVE_IDX=$OSTIDX
2151                 fi
2152                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2153                         echo $OSC "is Deactivated:"
2154                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2155                 fi
2156         done
2157
2158         OSTIDX=$(index_from_ostuuid $OST)
2159         test_mkdir $DIR/$tdir
2160         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2161
2162         for OSC in $MDS_OSCS; do
2163                 OST=$(osc_to_ost $OSC)
2164                 OSTIDX=$(index_from_ostuuid $OST)
2165                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2166                         echo $OST "is degraded:"
2167                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2168                                                 obdfilter.$OST.degraded=1
2169                 fi
2170         done
2171
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $fcount
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is recovered from degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=0
2182                 else
2183                         do_facet $SINGLEMDS lctl --device %$OSC activate
2184                 fi
2185         done
2186
2187         # all osp devices get activated, hence -1 stripe count restored
2188         local stripe_count=0
2189
2190         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2191         # devices get activated.
2192         sleep_maxage
2193         $LFS setstripe -c -1 $DIR/$tfile
2194         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2195         rm -f $DIR/$tfile
2196         [ $stripe_count -ne $OSTCOUNT ] &&
2197                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2198         return 0
2199 }
2200 run_test 27y "create files while OST0 is degraded and the rest inactive"
2201
2202 check_seq_oid()
2203 {
2204         log "check file $1"
2205
2206         lmm_count=$($LFS getstripe -c $1)
2207         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2208         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2209
2210         local old_ifs="$IFS"
2211         IFS=$'[:]'
2212         fid=($($LFS path2fid $1))
2213         IFS="$old_ifs"
2214
2215         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2216         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2217
2218         # compare lmm_seq and lu_fid->f_seq
2219         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2220         # compare lmm_object_id and lu_fid->oid
2221         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2222
2223         # check the trusted.fid attribute of the OST objects of the file
2224         local have_obdidx=false
2225         local stripe_nr=0
2226         $LFS getstripe $1 | while read obdidx oid hex seq; do
2227                 # skip lines up to and including "obdidx"
2228                 [ -z "$obdidx" ] && break
2229                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2230                 $have_obdidx || continue
2231
2232                 local ost=$((obdidx + 1))
2233                 local dev=$(ostdevname $ost)
2234                 local oid_hex
2235
2236                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2237
2238                 seq=$(echo $seq | sed -e "s/^0x//g")
2239                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2240                         oid_hex=$(echo $oid)
2241                 else
2242                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2243                 fi
2244                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2245
2246                 local ff=""
2247                 #
2248                 # Don't unmount/remount the OSTs if we don't need to do that.
2249                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2250                 # update too, until that use mount/ll_decode_filter_fid/mount.
2251                 # Re-enable when debugfs will understand new filter_fid.
2252                 #
2253                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2254                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2255                                 $dev 2>/dev/null" | grep "parent=")
2256                 fi
2257                 if [ -z "$ff" ]; then
2258                         stop ost$ost
2259                         mount_fstype ost$ost
2260                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2261                                 $(facet_mntpt ost$ost)/$obj_file)
2262                         unmount_fstype ost$ost
2263                         start ost$ost $dev $OST_MOUNT_OPTS
2264                         clients_up
2265                 fi
2266
2267                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2268
2269                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2270
2271                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2272                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2273                 #
2274                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2275                 #       stripe_size=1048576 component_id=1 component_start=0 \
2276                 #       component_end=33554432
2277                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2278                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2279                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2280                 local ff_pstripe
2281                 if grep -q 'stripe=' <<<$ff; then
2282                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2283                 else
2284                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2285                         # into f_ver in this case.  See comment on ff_parent.
2286                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2287                 fi
2288
2289                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2290                 [ $ff_pseq = $lmm_seq ] ||
2291                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2292                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2293                 [ $ff_poid = $lmm_oid ] ||
2294                         error "FF parent OID $ff_poid != $lmm_oid"
2295                 (($ff_pstripe == $stripe_nr)) ||
2296                         error "FF stripe $ff_pstripe != $stripe_nr"
2297
2298                 stripe_nr=$((stripe_nr + 1))
2299                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2300                         continue
2301                 if grep -q 'stripe_count=' <<<$ff; then
2302                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2303                                             -e 's/ .*//' <<<$ff)
2304                         [ $lmm_count = $ff_scnt ] ||
2305                                 error "FF stripe count $lmm_count != $ff_scnt"
2306                 fi
2307         done
2308 }
2309
2310 test_27z() {
2311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2312         remote_ost_nodsh && skip "remote OST with nodsh"
2313
2314         test_mkdir $DIR/$tdir
2315         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2316                 { error "setstripe -c -1 failed"; return 1; }
2317         # We need to send a write to every object to get parent FID info set.
2318         # This _should_ also work for setattr, but does not currently.
2319         # touch $DIR/$tdir/$tfile-1 ||
2320         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2321                 { error "dd $tfile-1 failed"; return 2; }
2322         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2323                 { error "setstripe -c -1 failed"; return 3; }
2324         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2325                 { error "dd $tfile-2 failed"; return 4; }
2326
2327         # make sure write RPCs have been sent to OSTs
2328         sync; sleep 5; sync
2329
2330         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2331         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2332 }
2333 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2334
2335 test_27A() { # b=19102
2336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2337
2338         save_layout_restore_at_exit $MOUNT
2339         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2340         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2341                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2342         local default_size=$($LFS getstripe -S $MOUNT)
2343         local default_offset=$($LFS getstripe -i $MOUNT)
2344         local dsize=$(do_facet $SINGLEMDS \
2345                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2346         [ $default_size -eq $dsize ] ||
2347                 error "stripe size $default_size != $dsize"
2348         [ $default_offset -eq -1 ] ||
2349                 error "stripe offset $default_offset != -1"
2350 }
2351 run_test 27A "check filesystem-wide default LOV EA values"
2352
2353 test_27B() { # LU-2523
2354         test_mkdir $DIR/$tdir
2355         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2356         touch $DIR/$tdir/f0
2357         # open f1 with O_LOV_DELAY_CREATE
2358         # rename f0 onto f1
2359         # call setstripe ioctl on open file descriptor for f1
2360         # close
2361         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2362                 $DIR/$tdir/f0
2363
2364         rm -f $DIR/$tdir/f1
2365         # open f1 with O_LOV_DELAY_CREATE
2366         # unlink f1
2367         # call setstripe ioctl on open file descriptor for f1
2368         # close
2369         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2370
2371         # Allow multiop to fail in imitation of NFS's busted semantics.
2372         true
2373 }
2374 run_test 27B "call setstripe on open unlinked file/rename victim"
2375
2376 # 27C family tests full striping and overstriping
2377 test_27Ca() { #LU-2871
2378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2379
2380         declare -a ost_idx
2381         local index
2382         local found
2383         local i
2384         local j
2385
2386         test_mkdir $DIR/$tdir
2387         cd $DIR/$tdir
2388         for i in $(seq 0 $((OSTCOUNT - 1))); do
2389                 # set stripe across all OSTs starting from OST$i
2390                 $LFS setstripe -i $i -c -1 $tfile$i
2391                 # get striping information
2392                 ost_idx=($($LFS getstripe $tfile$i |
2393                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2394                 echo "OST Index: ${ost_idx[*]}"
2395
2396                 # check the layout
2397                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2398                         error "${#ost_idx[@]} != $OSTCOUNT"
2399
2400                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2401                         found=0
2402                         for j in "${ost_idx[@]}"; do
2403                                 if [ $index -eq $j ]; then
2404                                         found=1
2405                                         break
2406                                 fi
2407                         done
2408                         [ $found = 1 ] ||
2409                                 error "Can not find $index in ${ost_idx[*]}"
2410                 done
2411         done
2412 }
2413 run_test 27Ca "check full striping across all OSTs"
2414
2415 test_27Cb() {
2416         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2417                 skip "server does not support overstriping"
2418         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2419                 skip_env "too many osts, skipping"
2420
2421         test_mkdir -p $DIR/$tdir
2422         local setcount=$(($OSTCOUNT * 2))
2423         [ $setcount -lt 160 ] || large_xattr_enabled ||
2424                 skip_env "ea_inode feature disabled"
2425
2426         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2427                 error "setstripe failed"
2428
2429         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2430         [ $count -eq $setcount ] ||
2431                 error "stripe count $count, should be $setcount"
2432
2433         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2434                 error "overstriped should be set in pattern"
2435
2436         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2437                 error "dd failed"
2438 }
2439 run_test 27Cb "more stripes than OSTs with -C"
2440
2441 test_27Cc() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2445
2446         test_mkdir -p $DIR/$tdir
2447         local setcount=$(($OSTCOUNT - 1))
2448
2449         [ $setcount -lt 160 ] || large_xattr_enabled ||
2450                 skip_env "ea_inode feature disabled"
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2460                 error "overstriped should not be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464 }
2465 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2466
2467 test_27Cd() {
2468         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2469                 skip "server does not support overstriping"
2470         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2471         large_xattr_enabled || skip_env "ea_inode feature disabled"
2472
2473         test_mkdir -p $DIR/$tdir
2474         local setcount=$LOV_MAX_STRIPE_COUNT
2475
2476         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2477                 error "setstripe failed"
2478
2479         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2480         [ $count -eq $setcount ] ||
2481                 error "stripe count $count, should be $setcount"
2482
2483         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2484                 error "overstriped should be set in pattern"
2485
2486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2487                 error "dd failed"
2488
2489         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2490 }
2491 run_test 27Cd "test maximum stripe count"
2492
2493 test_27Ce() {
2494         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2495                 skip "server does not support overstriping"
2496         test_mkdir -p $DIR/$tdir
2497
2498         pool_add $TESTNAME || error "Pool creation failed"
2499         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2500
2501         local setcount=8
2502
2503         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2504                 error "setstripe failed"
2505
2506         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2507         [ $count -eq $setcount ] ||
2508                 error "stripe count $count, should be $setcount"
2509
2510         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2511                 error "overstriped should be set in pattern"
2512
2513         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2514                 error "dd failed"
2515
2516         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2517 }
2518 run_test 27Ce "test pool with overstriping"
2519
2520 test_27Cf() {
2521         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2522                 skip "server does not support overstriping"
2523         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2524                 skip_env "too many osts, skipping"
2525
2526         test_mkdir -p $DIR/$tdir
2527
2528         local setcount=$(($OSTCOUNT * 2))
2529         [ $setcount -lt 160 ] || large_xattr_enabled ||
2530                 skip_env "ea_inode feature disabled"
2531
2532         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2533                 error "setstripe failed"
2534
2535         echo 1 > $DIR/$tdir/$tfile
2536
2537         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2538         [ $count -eq $setcount ] ||
2539                 error "stripe count $count, should be $setcount"
2540
2541         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2542                 error "overstriped should be set in pattern"
2543
2544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2545                 error "dd failed"
2546
2547         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2548 }
2549 run_test 27Cf "test default inheritance with overstriping"
2550
2551 test_27D() {
2552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2553         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2554         remote_mds_nodsh && skip "remote MDS with nodsh"
2555
2556         local POOL=${POOL:-testpool}
2557         local first_ost=0
2558         local last_ost=$(($OSTCOUNT - 1))
2559         local ost_step=1
2560         local ost_list=$(seq $first_ost $ost_step $last_ost)
2561         local ost_range="$first_ost $last_ost $ost_step"
2562
2563         test_mkdir $DIR/$tdir
2564         pool_add $POOL || error "pool_add failed"
2565         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2566
2567         local skip27D
2568         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2569                 skip27D+="-s 29"
2570         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2571                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2572                         skip27D+=" -s 30,31"
2573         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2574           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2575                 skip27D+=" -s 32,33"
2576         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2577                 skip27D+=" -s 34"
2578         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2579                 error "llapi_layout_test failed"
2580
2581         destroy_test_pools || error "destroy test pools failed"
2582 }
2583 run_test 27D "validate llapi_layout API"
2584
2585 # Verify that default_easize is increased from its initial value after
2586 # accessing a widely striped file.
2587 test_27E() {
2588         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2589         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2590                 skip "client does not have LU-3338 fix"
2591
2592         # 72 bytes is the minimum space required to store striping
2593         # information for a file striped across one OST:
2594         # (sizeof(struct lov_user_md_v3) +
2595         #  sizeof(struct lov_user_ost_data_v1))
2596         local min_easize=72
2597         $LCTL set_param -n llite.*.default_easize $min_easize ||
2598                 error "lctl set_param failed"
2599         local easize=$($LCTL get_param -n llite.*.default_easize)
2600
2601         [ $easize -eq $min_easize ] ||
2602                 error "failed to set default_easize"
2603
2604         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2605                 error "setstripe failed"
2606         # In order to ensure stat() call actually talks to MDS we need to
2607         # do something drastic to this file to shake off all lock, e.g.
2608         # rename it (kills lookup lock forcing cache cleaning)
2609         mv $DIR/$tfile $DIR/${tfile}-1
2610         ls -l $DIR/${tfile}-1
2611         rm $DIR/${tfile}-1
2612
2613         easize=$($LCTL get_param -n llite.*.default_easize)
2614
2615         [ $easize -gt $min_easize ] ||
2616                 error "default_easize not updated"
2617 }
2618 run_test 27E "check that default extended attribute size properly increases"
2619
2620 test_27F() { # LU-5346/LU-7975
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2623         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2624                 skip "Need MDS version at least 2.8.51"
2625         remote_ost_nodsh && skip "remote OST with nodsh"
2626
2627         test_mkdir $DIR/$tdir
2628         rm -f $DIR/$tdir/f0
2629         $LFS setstripe -c 2 $DIR/$tdir
2630
2631         # stop all OSTs to reproduce situation for LU-7975 ticket
2632         for num in $(seq $OSTCOUNT); do
2633                 stop ost$num
2634         done
2635
2636         # open/create f0 with O_LOV_DELAY_CREATE
2637         # truncate f0 to a non-0 size
2638         # close
2639         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2640
2641         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2642         # open/write it again to force delayed layout creation
2643         cat /etc/hosts > $DIR/$tdir/f0 &
2644         catpid=$!
2645
2646         # restart OSTs
2647         for num in $(seq $OSTCOUNT); do
2648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2649                         error "ost$num failed to start"
2650         done
2651
2652         wait $catpid || error "cat failed"
2653
2654         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2655         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2656                 error "wrong stripecount"
2657
2658 }
2659 run_test 27F "Client resend delayed layout creation with non-zero size"
2660
2661 test_27G() { #LU-10629
2662         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2663                 skip "Need MDS version at least 2.11.51"
2664         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2665         remote_mds_nodsh && skip "remote MDS with nodsh"
2666         local POOL=${POOL:-testpool}
2667         local ostrange="0 0 1"
2668
2669         test_mkdir $DIR/$tdir
2670         touch $DIR/$tdir/$tfile.nopool
2671         pool_add $POOL || error "pool_add failed"
2672         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2673         $LFS setstripe -p $POOL $DIR/$tdir
2674
2675         local pool=$($LFS getstripe -p $DIR/$tdir)
2676
2677         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2678         touch $DIR/$tdir/$tfile.default
2679         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2680         $LFS find $DIR/$tdir -type f --pool $POOL
2681         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2682         [[ "$found" == "2" ]] ||
2683                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2684
2685         $LFS setstripe -d $DIR/$tdir
2686
2687         pool=$($LFS getstripe -p -d $DIR/$tdir)
2688
2689         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2690 }
2691 run_test 27G "Clear OST pool from stripe"
2692
2693 test_27H() {
2694         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2695                 skip "Need MDS version newer than 2.11.54"
2696         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2699         touch $DIR/$tdir/$tfile
2700         $LFS getstripe -c $DIR/$tdir/$tfile
2701         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2702                 error "two-stripe file doesn't have two stripes"
2703
2704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2705         $LFS getstripe -y $DIR/$tdir/$tfile
2706         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2707              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2708                 error "expected l_ost_idx: [02]$ not matched"
2709
2710         # make sure ost list has been cleared
2711         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2712         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2713                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2714         touch $DIR/$tdir/f3
2715         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2716 }
2717 run_test 27H "Set specific OSTs stripe"
2718
2719 test_27I() {
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2723                 skip "Need MDS version newer than 2.12.52"
2724         local pool=$TESTNAME
2725         local ostrange="1 1 1"
2726
2727         save_layout_restore_at_exit $MOUNT
2728         $LFS setstripe -c 2 -i 0 $MOUNT
2729         pool_add $pool || error "pool_add failed"
2730         pool_add_targets $pool $ostrange ||
2731                 error "pool_add_targets failed"
2732         test_mkdir $DIR/$tdir
2733         $LFS setstripe -p $pool $DIR/$tdir
2734         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2735         $LFS getstripe $DIR/$tdir/$tfile
2736 }
2737 run_test 27I "check that root dir striping does not break parent dir one"
2738
2739 test_27J() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2741                 skip "Need MDS version newer than 2.12.51"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign file (raw way)
2748         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2749                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2750
2751         ! $LFS setstripe --foreign --flags foo \
2752                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2753                         error "creating $tfile with '--flags foo' should fail"
2754
2755         ! $LFS setstripe --foreign --flags 0xffffffff \
2756                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2757                         error "creating $tfile w/ 0xffffffff flags should fail"
2758
2759         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2760                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2761
2762         # verify foreign file (raw way)
2763         parse_foreign_file -f $DIR/$tdir/$tfile |
2764                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2765                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2766         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2767                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_size: 73" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2771         parse_foreign_file -f $DIR/$tdir/$tfile |
2772                 grep "lov_foreign_type: 1" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_flags: 0x0000DA08" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2777         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_value: 0x" |
2779                 sed -e 's/lov_foreign_value: 0x//')
2780         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2781         [[ $lov = ${lov2// /} ]] ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2783
2784         # create foreign file (lfs + API)
2785         $LFS setstripe --foreign=none --flags 0xda08 \
2786                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: create failed"
2788
2789         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2790                 grep "lfm_magic:.*0x0BD70BD0" ||
2791                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2792         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2793         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2794                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2797         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2798                 grep "lfm_flags:.*0x0000DA08" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2800         $LFS getstripe $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2803
2804         # modify striping should fail
2805         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2806                 error "$DIR/$tdir/$tfile: setstripe should fail"
2807         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2808                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2809
2810         # R/W should fail
2811         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2812         cat $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: read should fail"
2814         cat /etc/passwd > $DIR/$tdir/$tfile &&
2815                 error "$DIR/$tdir/$tfile: write should fail"
2816         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2817                 error "$DIR/$tdir/${tfile}2: write should fail"
2818
2819         # chmod should work
2820         chmod 222 $DIR/$tdir/$tfile ||
2821                 error "$DIR/$tdir/$tfile: chmod failed"
2822         chmod 222 $DIR/$tdir/${tfile}2 ||
2823                 error "$DIR/$tdir/${tfile}2: chmod failed"
2824
2825         # chown should work
2826         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chown failed"
2828         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chown failed"
2830
2831         # rename should work
2832         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2833                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2834         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2835                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2836
2837         #remove foreign file
2838         rm $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2840         rm $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2842 }
2843 run_test 27J "basic ops on file with foreign LOV"
2844
2845 test_27K() {
2846         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2847                 skip "Need MDS version newer than 2.12.49"
2848
2849         test_mkdir $DIR/$tdir
2850         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2851         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2852
2853         # create foreign dir (raw way)
2854         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2855                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2856
2857         ! $LFS setdirstripe --foreign --flags foo \
2858                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2859                         error "creating $tdir with '--flags foo' should fail"
2860
2861         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2862                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2863                         error "creating $tdir w/ 0xffffffff flags should fail"
2864
2865         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2866                 error "create_foreign_dir FAILED"
2867
2868         # verify foreign dir (raw way)
2869         parse_foreign_dir -d $DIR/$tdir/$tdir |
2870                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2871                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2872         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2873                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2874         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2875                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_flags: 55813$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2879         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2880                 grep "lmv_foreign_value: 0x" |
2881                 sed 's/lmv_foreign_value: 0x//')
2882         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2883                 sed 's/ //g')
2884         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2885
2886         # create foreign dir (lfs + API)
2887         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2888                 $DIR/$tdir/${tdir}2 ||
2889                 error "$DIR/$tdir/${tdir}2: create failed"
2890
2891         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2892
2893         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2894                 grep "lfm_magic:.*0x0CD50CD0" ||
2895                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2896         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2897         # - sizeof(lfm_type) - sizeof(lfm_flags)
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2900         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_flags:.*0x0000DA05" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2905         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2908
2909         # file create in dir should fail
2910         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2911         touch $DIR/$tdir/${tdir}2/$tfile &&
2912                 error "$DIR/${tdir}2: file create should fail"
2913
2914         # chmod should work
2915         chmod 777 $DIR/$tdir/$tdir ||
2916                 error "$DIR/$tdir: chmod failed"
2917         chmod 777 $DIR/$tdir/${tdir}2 ||
2918                 error "$DIR/${tdir}2: chmod failed"
2919
2920         # chown should work
2921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chown failed"
2923         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chown failed"
2925
2926         # rename should work
2927         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2928                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2929         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2930                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2931
2932         #remove foreign dir
2933         rmdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2935         rmdir $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2937 }
2938 run_test 27K "basic ops on dir with foreign LMV"
2939
2940 test_27L() {
2941         remote_mds_nodsh && skip "remote MDS with nodsh"
2942
2943         local POOL=${POOL:-$TESTNAME}
2944
2945         pool_add $POOL || error "pool_add failed"
2946
2947         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2948                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2949                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2950 }
2951 run_test 27L "lfs pool_list gives correct pool name"
2952
2953 test_27M() {
2954         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2955                 skip "Need MDS version >= than 2.12.57"
2956         remote_mds_nodsh && skip "remote MDS with nodsh"
2957         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2958
2959         # Set default striping on directory
2960         local setcount=4
2961         local stripe_opt
2962         local mdts=$(comma_list $(mdts_nodes))
2963
2964         # if we run against a 2.12 server which lacks overstring support
2965         # then the connect_flag will not report overstriping, even if client
2966         # is 2.14+
2967         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2968                 stripe_opt="-C $setcount"
2969         elif (( $OSTCOUNT >= $setcount )); then
2970                 stripe_opt="-c $setcount"
2971         else
2972                 skip "server does not support overstriping"
2973         fi
2974
2975         test_mkdir $DIR/$tdir
2976
2977         # Validate existing append_* params and ensure restore
2978         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2979         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2980         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2981
2982         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2983         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2985
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         pool_add $TESTNAME || error "pool creation failed"
3071         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3072         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27T() {
3377         [ $(facet_host client) == $(facet_host ost1) ] &&
3378                 skip "need ost1 and client on different nodes"
3379
3380 #define OBD_FAIL_OSC_NO_GRANT            0x411
3381         $LCTL set_param fail_loc=0x20000411 fail_val=1
3382 #define OBD_FAIL_OST_ENOSPC              0x215
3383         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3385         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3386                 error "multiop failed"
3387 }
3388 run_test 27T "no eio on close on partial write due to enosp"
3389
3390 test_27U() {
3391         local dir=$DIR/$tdir
3392         local file=$dir/$tfile
3393         local append_pool=${TESTNAME}-append
3394         local normal_pool=${TESTNAME}-normal
3395         local pool
3396         local stripe_count
3397         local stripe_count2
3398         local mdts=$(comma_list $(mdts_nodes))
3399
3400         # FIMXE
3401         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3402         #       skip "Need MDS version at least 2.15.42"
3403
3404         # Validate existing append_* params and ensure restore
3405         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3406         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3407         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3408
3409         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3410         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3411         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3412
3413         pool_add $append_pool || error "pool creation failed"
3414         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3415
3416         pool_add $normal_pool || error "pool creation failed"
3417         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3418
3419         test_mkdir $dir
3420         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3421
3422         echo XXX >> $file.1
3423         $LFS getstripe $file.1
3424
3425         pool=$($LFS getstripe -p $file.1)
3426         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3427
3428         stripe_count2=$($LFS getstripe -c $file.1)
3429         ((stripe_count2 == stripe_count)) ||
3430                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3431
3432         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3433
3434         echo XXX >> $file.2
3435         $LFS getstripe $file.2
3436
3437         pool=$($LFS getstripe -p $file.2)
3438         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3439
3440         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3441
3442         echo XXX >> $file.3
3443         $LFS getstripe $file.3
3444
3445         stripe_count2=$($LFS getstripe -c $file.3)
3446         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3447 }
3448 run_test 27U "append pool and stripe count work with composite default layout"
3449
3450 # createtest also checks that device nodes are created and
3451 # then visible correctly (#2091)
3452 test_28() { # bug 2091
3453         test_mkdir $DIR/d28
3454         $CREATETEST $DIR/d28/ct || error "createtest failed"
3455 }
3456 run_test 28 "create/mknod/mkdir with bad file types ============"
3457
3458 test_29() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3462                 disable_opencache
3463                 stack_trap "restore_opencache"
3464         }
3465
3466         sync; sleep 1; sync # flush out any dirty pages from previous tests
3467         cancel_lru_locks
3468         test_mkdir $DIR/d29
3469         touch $DIR/d29/foo
3470         log 'first d29'
3471         ls -l $DIR/d29
3472
3473         declare -i LOCKCOUNTORIG=0
3474         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3475                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3476         done
3477         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3478
3479         declare -i LOCKUNUSEDCOUNTORIG=0
3480         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3481                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3482         done
3483
3484         log 'second d29'
3485         ls -l $DIR/d29
3486         log 'done'
3487
3488         declare -i LOCKCOUNTCURRENT=0
3489         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3490                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3491         done
3492
3493         declare -i LOCKUNUSEDCOUNTCURRENT=0
3494         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3495                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3496         done
3497
3498         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3499                 $LCTL set_param -n ldlm.dump_namespaces ""
3500                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3501                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3502                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3503                 return 2
3504         fi
3505         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3506                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3507                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3508                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3509                 return 3
3510         fi
3511 }
3512 run_test 29 "IT_GETATTR regression  ============================"
3513
3514 test_30a() { # was test_30
3515         cp $(which ls) $DIR || cp /bin/ls $DIR
3516         $DIR/ls / || error "Can't execute binary from lustre"
3517         rm $DIR/ls
3518 }
3519 run_test 30a "execute binary from Lustre (execve) =============="
3520
3521 test_30b() {
3522         cp `which ls` $DIR || cp /bin/ls $DIR
3523         chmod go+rx $DIR/ls
3524         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3525         rm $DIR/ls
3526 }
3527 run_test 30b "execute binary from Lustre as non-root ==========="
3528
3529 test_30c() { # b=22376
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         cp $(which ls) $DIR || cp /bin/ls $DIR
3533         chmod a-rw $DIR/ls
3534         cancel_lru_locks mdc
3535         cancel_lru_locks osc
3536         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3537         rm -f $DIR/ls
3538 }
3539 run_test 30c "execute binary from Lustre without read perms ===="
3540
3541 test_30d() {
3542         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3543
3544         for i in {1..10}; do
3545                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3546                 local PID=$!
3547                 sleep 1
3548                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3549                 wait $PID || error "executing dd from Lustre failed"
3550                 rm -f $DIR/$tfile
3551         done
3552
3553         rm -f $DIR/dd
3554 }
3555 run_test 30d "execute binary from Lustre while clear locks"
3556
3557 test_31a() {
3558         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3559         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3560 }
3561 run_test 31a "open-unlink file =================================="
3562
3563 test_31b() {
3564         touch $DIR/f31 || error "touch $DIR/f31 failed"
3565         ln $DIR/f31 $DIR/f31b || error "ln failed"
3566         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3567         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3568 }
3569 run_test 31b "unlink file with multiple links while open ======="
3570
3571 test_31c() {
3572         touch $DIR/f31 || error "touch $DIR/f31 failed"
3573         ln $DIR/f31 $DIR/f31c || error "ln failed"
3574         multiop_bg_pause $DIR/f31 O_uc ||
3575                 error "multiop_bg_pause for $DIR/f31 failed"
3576         MULTIPID=$!
3577         $MULTIOP $DIR/f31c Ouc
3578         kill -USR1 $MULTIPID
3579         wait $MULTIPID
3580 }
3581 run_test 31c "open-unlink file with multiple links ============="
3582
3583 test_31d() {
3584         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3585         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3586 }
3587 run_test 31d "remove of open directory ========================="
3588
3589 test_31e() { # bug 2904
3590         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3591 }
3592 run_test 31e "remove of open non-empty directory ==============="
3593
3594 test_31f() { # bug 4554
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         set -vx
3598         test_mkdir $DIR/d31f
3599         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3600         cp /etc/hosts $DIR/d31f
3601         ls -l $DIR/d31f
3602         $LFS getstripe $DIR/d31f/hosts
3603         multiop_bg_pause $DIR/d31f D_c || return 1
3604         MULTIPID=$!
3605
3606         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3607         test_mkdir $DIR/d31f
3608         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3609         cp /etc/hosts $DIR/d31f
3610         ls -l $DIR/d31f
3611         $LFS getstripe $DIR/d31f/hosts
3612         multiop_bg_pause $DIR/d31f D_c || return 1
3613         MULTIPID2=$!
3614
3615         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3616         wait $MULTIPID || error "first opendir $MULTIPID failed"
3617
3618         sleep 6
3619
3620         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3621         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3622         set +vx
3623 }
3624 run_test 31f "remove of open directory with open-unlink file ==="
3625
3626 test_31g() {
3627         echo "-- cross directory link --"
3628         test_mkdir -c1 $DIR/${tdir}ga
3629         test_mkdir -c1 $DIR/${tdir}gb
3630         touch $DIR/${tdir}ga/f
3631         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3632         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3633         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3634         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3635         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3636 }
3637 run_test 31g "cross directory link==============="
3638
3639 test_31h() {
3640         echo "-- cross directory link --"
3641         test_mkdir -c1 $DIR/${tdir}
3642         test_mkdir -c1 $DIR/${tdir}/dir
3643         touch $DIR/${tdir}/f
3644         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3645         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3646         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3647         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3648         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3649 }
3650 run_test 31h "cross directory link under child==============="
3651
3652 test_31i() {
3653         echo "-- cross directory link --"
3654         test_mkdir -c1 $DIR/$tdir
3655         test_mkdir -c1 $DIR/$tdir/dir
3656         touch $DIR/$tdir/dir/f
3657         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3658         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3659         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3660         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3661         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3662 }
3663 run_test 31i "cross directory link under parent==============="
3664
3665 test_31j() {
3666         test_mkdir -c1 -p $DIR/$tdir
3667         test_mkdir -c1 -p $DIR/$tdir/dir1
3668         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3669         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3671         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3672         return 0
3673 }
3674 run_test 31j "link for directory==============="
3675
3676 test_31k() {
3677         test_mkdir -c1 -p $DIR/$tdir
3678         touch $DIR/$tdir/s
3679         touch $DIR/$tdir/exist
3680         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3681         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3682         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3683         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3684         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3686         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3687         return 0
3688 }
3689 run_test 31k "link to file: the same, non-existing, dir==============="
3690
3691 test_31m() {
3692         mkdir $DIR/d31m
3693         touch $DIR/d31m/s
3694         mkdir $DIR/d31m2
3695         touch $DIR/d31m2/exist
3696         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3697         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3698         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3699         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3701         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3702         return 0
3703 }
3704 run_test 31m "link to file: the same, non-existing, dir==============="
3705
3706 test_31n() {
3707         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3708         nlink=$(stat --format=%h $DIR/$tfile)
3709         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3710         local fd=$(free_fd)
3711         local cmd="exec $fd<$DIR/$tfile"
3712         eval $cmd
3713         cmd="exec $fd<&-"
3714         trap "eval $cmd" EXIT
3715         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3716         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3717         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3718         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3719         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3720         eval $cmd
3721 }
3722 run_test 31n "check link count of unlinked file"
3723
3724 link_one() {
3725         local tempfile=$(mktemp $1_XXXXXX)
3726         mlink $tempfile $1 2> /dev/null &&
3727                 echo "$BASHPID: link $tempfile to $1 succeeded"
3728         munlink $tempfile
3729 }
3730
3731 test_31o() { # LU-2901
3732         test_mkdir $DIR/$tdir
3733         for LOOP in $(seq 100); do
3734                 rm -f $DIR/$tdir/$tfile*
3735                 for THREAD in $(seq 8); do
3736                         link_one $DIR/$tdir/$tfile.$LOOP &
3737                 done
3738                 wait
3739                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3740                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3741                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3742                         break || true
3743         done
3744 }
3745 run_test 31o "duplicate hard links with same filename"
3746
3747 test_31p() {
3748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3752         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3753
3754         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3755                 error "open unlink test1 failed"
3756         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3757                 error "open unlink test2 failed"
3758
3759         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3760                 error "test1 still exists"
3761         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3762                 error "test2 still exists"
3763 }
3764 run_test 31p "remove of open striped directory"
3765
3766 test_31q() {
3767         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3768
3769         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3770         index=$($LFS getdirstripe -i $DIR/$tdir)
3771         [ $index -eq 3 ] || error "first stripe index $index != 3"
3772         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3773         [ $index -eq 1 ] || error "second stripe index $index != 1"
3774
3775         # when "-c <stripe_count>" is set, the number of MDTs specified after
3776         # "-i" should equal to the stripe count
3777         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3778 }
3779 run_test 31q "create striped directory on specific MDTs"
3780
3781 #LU-14949
3782 test_31r() {
3783         touch $DIR/$tfile.target
3784         touch $DIR/$tfile.source
3785
3786         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3787         $LCTL set_param fail_loc=0x1419 fail_val=3
3788         cat $DIR/$tfile.target &
3789         CATPID=$!
3790
3791         # Guarantee open is waiting before we get here
3792         sleep 1
3793         mv $DIR/$tfile.source $DIR/$tfile.target
3794
3795         wait $CATPID
3796         RC=$?
3797         if [[ $RC -ne 0 ]]; then
3798                 error "open with cat failed, rc=$RC"
3799         fi
3800 }
3801 run_test 31r "open-rename(replace) race"
3802
3803 cleanup_test32_mount() {
3804         local rc=0
3805         trap 0
3806         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3807         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3808         losetup -d $loopdev || true
3809         rm -rf $DIR/$tdir
3810         return $rc
3811 }
3812
3813 test_32a() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         echo "== more mountpoints and symlinks ================="
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3823                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3824         cleanup_test32_mount
3825 }
3826 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3827
3828 test_32b() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3837                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3838         cleanup_test32_mount
3839 }
3840 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3841
3842 test_32c() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2/test_dir
3851         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3852                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3853         cleanup_test32_mount
3854 }
3855 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3856
3857 test_32d() {
3858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3859
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         test_mkdir -p $DIR/$tdir/d2/test_dir
3866         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3868         cleanup_test32_mount
3869 }
3870 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3871
3872 test_32e() {
3873         rm -fr $DIR/$tdir
3874         test_mkdir -p $DIR/$tdir/tmp
3875         local tmp_dir=$DIR/$tdir/tmp
3876         ln -s $DIR/$tdir $tmp_dir/symlink11
3877         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3878         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3879         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3880 }
3881 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3882
3883 test_32f() {
3884         rm -fr $DIR/$tdir
3885         test_mkdir -p $DIR/$tdir/tmp
3886         local tmp_dir=$DIR/$tdir/tmp
3887         ln -s $DIR/$tdir $tmp_dir/symlink11
3888         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3889         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3890         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3891 }
3892 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3893
3894 test_32g() {
3895         local tmp_dir=$DIR/$tdir/tmp
3896         test_mkdir -p $tmp_dir
3897         test_mkdir $DIR/${tdir}2
3898         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3899         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3900         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3901         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3902         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3903         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3904 }
3905 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3906
3907 test_32h() {
3908         rm -fr $DIR/$tdir $DIR/${tdir}2
3909         tmp_dir=$DIR/$tdir/tmp
3910         test_mkdir -p $tmp_dir
3911         test_mkdir $DIR/${tdir}2
3912         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3913         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3914         ls $tmp_dir/symlink12 || error "listing symlink12"
3915         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3916 }
3917 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3918
3919 test_32i() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         touch $DIR/$tdir/test_file
3928         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3929                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3930         cleanup_test32_mount
3931 }
3932 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3933
3934 test_32j() {
3935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3936
3937         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3938         trap cleanup_test32_mount EXIT
3939         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3940         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3941                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3942         touch $DIR/$tdir/test_file
3943         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3948
3949 test_32k() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         test_mkdir -p $DIR/$tdir/d2
3958         touch $DIR/$tdir/d2/test_file || error "touch failed"
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3964
3965 test_32l() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         test_mkdir -p $DIR/$tdir/d2
3974         touch $DIR/$tdir/d2/test_file || error "touch failed"
3975         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3976                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3977         cleanup_test32_mount
3978 }
3979 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3980
3981 test_32m() {
3982         rm -fr $DIR/d32m
3983         test_mkdir -p $DIR/d32m/tmp
3984         TMP_DIR=$DIR/d32m/tmp
3985         ln -s $DIR $TMP_DIR/symlink11
3986         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3987         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3988                 error "symlink11 not a link"
3989         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3990                 error "symlink01 not a link"
3991 }
3992 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3993
3994 test_32n() {
3995         rm -fr $DIR/d32n
3996         test_mkdir -p $DIR/d32n/tmp
3997         TMP_DIR=$DIR/d32n/tmp
3998         ln -s $DIR $TMP_DIR/symlink11
3999         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4000         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4001         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4002 }
4003 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4004
4005 test_32o() {
4006         touch $DIR/$tfile
4007         test_mkdir -p $DIR/d32o/tmp
4008         TMP_DIR=$DIR/d32o/tmp
4009         ln -s $DIR/$tfile $TMP_DIR/symlink12
4010         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4011         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4012                 error "symlink12 not a link"
4013         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4014         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4015                 error "$DIR/d32o/tmp/symlink12 not file type"
4016         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4017                 error "$DIR/d32o/symlink02 not file type"
4018 }
4019 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4020
4021 test_32p() {
4022         log 32p_1
4023         rm -fr $DIR/d32p
4024         log 32p_2
4025         rm -f $DIR/$tfile
4026         log 32p_3
4027         touch $DIR/$tfile
4028         log 32p_4
4029         test_mkdir -p $DIR/d32p/tmp
4030         log 32p_5
4031         TMP_DIR=$DIR/d32p/tmp
4032         log 32p_6
4033         ln -s $DIR/$tfile $TMP_DIR/symlink12
4034         log 32p_7
4035         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4036         log 32p_8
4037         cat $DIR/d32p/tmp/symlink12 ||
4038                 error "Can't open $DIR/d32p/tmp/symlink12"
4039         log 32p_9
4040         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4041         log 32p_10
4042 }
4043 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4044
4045 test_32q() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4055         cleanup_test32_mount
4056 }
4057 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4058
4059 test_32r() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4069         cleanup_test32_mount
4070 }
4071 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4072
4073 test_33aa() {
4074         rm -f $DIR/$tfile
4075         touch $DIR/$tfile
4076         chmod 444 $DIR/$tfile
4077         chown $RUNAS_ID $DIR/$tfile
4078         log 33_1
4079         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4080         log 33_2
4081 }
4082 run_test 33aa "write file with mode 444 (should return error)"
4083
4084 test_33a() {
4085         rm -fr $DIR/$tdir
4086         test_mkdir $DIR/$tdir
4087         chown $RUNAS_ID $DIR/$tdir
4088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4089                 error "$RUNAS create $tdir/$tfile failed"
4090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4091                 error "open RDWR" || true
4092 }
4093 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4094
4095 test_33b() {
4096         rm -fr $DIR/$tdir
4097         test_mkdir $DIR/$tdir
4098         chown $RUNAS_ID $DIR/$tdir
4099         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4100 }
4101 run_test 33b "test open file with malformed flags (No panic)"
4102
4103 test_33c() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105         remote_ost_nodsh && skip "remote OST with nodsh"
4106
4107         local ostnum
4108         local ostname
4109         local write_bytes
4110         local all_zeros
4111
4112         all_zeros=true
4113         test_mkdir $DIR/$tdir
4114         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4115
4116         sync
4117         for ostnum in $(seq $OSTCOUNT); do
4118                 # test-framework's OST numbering is one-based, while Lustre's
4119                 # is zero-based
4120                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4121                 # check if at least some write_bytes stats are counted
4122                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4123                               obdfilter.$ostname.stats |
4124                               awk '/^write_bytes/ {print $7}' )
4125                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4126                 if (( ${write_bytes:-0} > 0 )); then
4127                         all_zeros=false
4128                         break
4129                 fi
4130         done
4131
4132         $all_zeros || return 0
4133
4134         # Write four bytes
4135         echo foo > $DIR/$tdir/bar
4136         # Really write them
4137         sync
4138
4139         # Total up write_bytes after writing.  We'd better find non-zeros.
4140         for ostnum in $(seq $OSTCOUNT); do
4141                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4142                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4143                               obdfilter/$ostname/stats |
4144                               awk '/^write_bytes/ {print $7}' )
4145                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4146                 if (( ${write_bytes:-0} > 0 )); then
4147                         all_zeros=false
4148                         break
4149                 fi
4150         done
4151
4152         if $all_zeros; then
4153                 for ostnum in $(seq $OSTCOUNT); do
4154                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4155                         echo "Check write_bytes is in obdfilter.*.stats:"
4156                         do_facet ost$ostnum lctl get_param -n \
4157                                 obdfilter.$ostname.stats
4158                 done
4159                 error "OST not keeping write_bytes stats (b=22312)"
4160         fi
4161 }
4162 run_test 33c "test write_bytes stats"
4163
4164 test_33d() {
4165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4167
4168         local MDTIDX=1
4169         local remote_dir=$DIR/$tdir/remote_dir
4170
4171         test_mkdir $DIR/$tdir
4172         $LFS mkdir -i $MDTIDX $remote_dir ||
4173                 error "create remote directory failed"
4174
4175         touch $remote_dir/$tfile
4176         chmod 444 $remote_dir/$tfile
4177         chown $RUNAS_ID $remote_dir/$tfile
4178
4179         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4180
4181         chown $RUNAS_ID $remote_dir
4182         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4183                                         error "create" || true
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4185                                     error "open RDWR" || true
4186         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4187 }
4188 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4189
4190 test_33e() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192
4193         mkdir $DIR/$tdir
4194
4195         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4196         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4197         mkdir $DIR/$tdir/local_dir
4198
4199         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4200         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4201         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4202
4203         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4204                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4205
4206         rmdir $DIR/$tdir/* || error "rmdir failed"
4207
4208         umask 777
4209         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4210         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4211         mkdir $DIR/$tdir/local_dir
4212
4213         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4214         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4215         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4216
4217         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4218                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4219
4220         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4221
4222         umask 000
4223         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4224         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4225         mkdir $DIR/$tdir/local_dir
4226
4227         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4228         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4229         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4230
4231         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4232                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4233 }
4234 run_test 33e "mkdir and striped directory should have same mode"
4235
4236 cleanup_33f() {
4237         trap 0
4238         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4239 }
4240
4241 test_33f() {
4242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4243         remote_mds_nodsh && skip "remote MDS with nodsh"
4244
4245         mkdir $DIR/$tdir
4246         chmod go+rwx $DIR/$tdir
4247         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4248         trap cleanup_33f EXIT
4249
4250         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4251                 error "cannot create striped directory"
4252
4253         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4254                 error "cannot create files in striped directory"
4255
4256         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4257                 error "cannot remove files in striped directory"
4258
4259         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4260                 error "cannot remove striped directory"
4261
4262         cleanup_33f
4263 }
4264 run_test 33f "nonroot user can create, access, and remove a striped directory"
4265
4266 test_33g() {
4267         mkdir -p $DIR/$tdir/dir2
4268
4269         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4270         echo $err
4271         [[ $err =~ "exists" ]] || error "Not exists error"
4272 }
4273 run_test 33g "nonroot user create already existing root created file"
4274
4275 sub_33h() {
4276         local hash_type=$1
4277         local count=250
4278
4279         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4280                 error "lfs mkdir -H $hash_type $tdir failed"
4281         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4282
4283         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4284         local index2
4285         local fname
4286
4287         for fname in $DIR/$tdir/$tfile.bak \
4288                      $DIR/$tdir/$tfile.SAV \
4289                      $DIR/$tdir/$tfile.orig \
4290                      $DIR/$tdir/$tfile~; do
4291                 touch $fname || error "touch $fname failed"
4292                 index2=$($LFS getstripe -m $fname)
4293                 (( $index == $index2 )) ||
4294                         error "$fname MDT index mismatch $index != $index2"
4295         done
4296
4297         local failed=0
4298         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4299         local pattern
4300
4301         for pattern in ${patterns[*]}; do
4302                 echo "pattern $pattern"
4303                 fname=$DIR/$tdir/$pattern
4304                 for (( i = 0; i < $count; i++ )); do
4305                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4306                                 error "mktemp $DIR/$tdir/$pattern failed"
4307                         index2=$($LFS getstripe -m $fname)
4308                         (( $index == $index2 )) && continue
4309
4310                         failed=$((failed + 1))
4311                         echo "$fname MDT index mismatch $index != $index2"
4312                 done
4313         done
4314
4315         echo "$failed/$count MDT index mismatches, expect ~2-4"
4316         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4317
4318         local same=0
4319         local expect
4320
4321         # verify that "crush" is still broken with all files on same MDT,
4322         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4323         [[ "$hash_type" == "crush" ]] && expect=$count ||
4324                 expect=$((count / MDSCOUNT))
4325
4326         # crush2 doesn't put all-numeric suffixes on the same MDT,
4327         # filename like $tfile.12345678 should *not* be considered temp
4328         for pattern in ${patterns[*]}; do
4329                 local base=${pattern%%X*}
4330                 local suff=${pattern#$base}
4331
4332                 echo "pattern $pattern"
4333                 for (( i = 0; i < $count; i++ )); do
4334                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4335                         touch $fname || error "touch $fname failed"
4336                         index2=$($LFS getstripe -m $fname)
4337                         (( $index != $index2 )) && continue
4338
4339                         same=$((same + 1))
4340                 done
4341         done
4342
4343         # the number of "bad" hashes is random, as it depends on the random
4344         # filenames generated by "mktemp".  Allow some margin in the results.
4345         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4346         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4347            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4348                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4349         same=0
4350
4351         # crush2 doesn't put suffixes with special characters on the same MDT
4352         # filename like $tfile.txt.1234 should *not* be considered temp
4353         for pattern in ${patterns[*]}; do
4354                 local base=${pattern%%X*}
4355                 local suff=${pattern#$base}
4356
4357                 pattern=$base...${suff/XXX}
4358                 echo "pattern=$pattern"
4359                 for (( i = 0; i < $count; i++ )); do
4360                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4361                                 error "touch $fname failed"
4362                         index2=$($LFS getstripe -m $fname)
4363                         (( $index != $index2 )) && continue
4364
4365                         same=$((same + 1))
4366                 done
4367         done
4368
4369         # the number of "bad" hashes is random, as it depends on the random
4370         # filenames generated by "mktemp".  Allow some margin in the results.
4371         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4372         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4373            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4374                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4375 }
4376
4377 test_33h() {
4378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4379         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4380                 skip "Need MDS version at least 2.13.50"
4381
4382         sub_33h crush
4383 }
4384 run_test 33h "temp file is located on the same MDT as target (crush)"
4385
4386 test_33hh() {
4387         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4388         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4389         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4390                 skip "Need MDS version at least 2.15.0 for crush2"
4391
4392         sub_33h crush2
4393 }
4394 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4395
4396 test_33i()
4397 {
4398         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4399
4400         local FNAME=$(str_repeat 'f' 250)
4401
4402         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4403         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4404
4405         local count
4406         local total
4407
4408         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4409
4410         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4411
4412         lctl --device %$MDC deactivate
4413         stack_trap "lctl --device %$MDC activate"
4414         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4415         total=$(\ls -l $DIR/$tdir | wc -l)
4416         # "ls -l" will list total in the first line
4417         total=$((total - 1))
4418         (( total + count == 1000 )) ||
4419                 error "ls list $total files, $count files on MDT1"
4420 }
4421 run_test 33i "striped directory can be accessed when one MDT is down"
4422
4423 test_33j() {
4424         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4425
4426         mkdir -p $DIR/$tdir/
4427
4428         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4429                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4430
4431         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4432                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4433
4434         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4435                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4436
4437         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4438                 error "-D was not specified, but still failed"
4439 }
4440 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4441
4442 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4443 test_34a() {
4444         rm -f $DIR/f34
4445         $MCREATE $DIR/f34 || error "mcreate failed"
4446         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4447                 error "getstripe failed"
4448         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4449         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4450                 error "getstripe failed"
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453 }
4454 run_test 34a "truncate file that has not been opened ==========="
4455
4456 test_34b() {
4457         [ ! -f $DIR/f34 ] && test_34a
4458         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4459                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4460         $OPENFILE -f O_RDONLY $DIR/f34
4461         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4462                 error "getstripe failed"
4463         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4464                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4465 }
4466 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4467
4468 test_34c() {
4469         [ ! -f $DIR/f34 ] && test_34a
4470         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4471                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4472         $OPENFILE -f O_RDWR $DIR/f34
4473         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4474                 error "$LFS getstripe failed"
4475         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4476                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4477 }
4478 run_test 34c "O_RDWR opening file-with-size works =============="
4479
4480 test_34d() {
4481         [ ! -f $DIR/f34 ] && test_34a
4482         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4483                 error "dd failed"
4484         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4485                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4486         rm $DIR/f34
4487 }
4488 run_test 34d "write to sparse file ============================="
4489
4490 test_34e() {
4491         rm -f $DIR/f34e
4492         $MCREATE $DIR/f34e || error "mcreate failed"
4493         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4494         $CHECKSTAT -s 1000 $DIR/f34e ||
4495                 error "Size of $DIR/f34e not equal to 1000 bytes"
4496         $OPENFILE -f O_RDWR $DIR/f34e
4497         $CHECKSTAT -s 1000 $DIR/f34e ||
4498                 error "Size of $DIR/f34e not equal to 1000 bytes"
4499 }
4500 run_test 34e "create objects, some with size and some without =="
4501
4502 test_34f() { # bug 6242, 6243
4503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4504
4505         SIZE34F=48000
4506         rm -f $DIR/f34f
4507         $MCREATE $DIR/f34f || error "mcreate failed"
4508         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4509         dd if=$DIR/f34f of=$TMP/f34f
4510         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4511         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4512         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4513         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4514         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4515 }
4516 run_test 34f "read from a file with no objects until EOF ======="
4517
4518 test_34g() {
4519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4520
4521         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4522                 error "dd failed"
4523         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4524         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4525                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4526         cancel_lru_locks osc
4527         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4528                 error "wrong size after lock cancel"
4529
4530         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4531         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4532                 error "expanding truncate failed"
4533         cancel_lru_locks osc
4534         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4535                 error "wrong expanded size after lock cancel"
4536 }
4537 run_test 34g "truncate long file ==============================="
4538
4539 test_34h() {
4540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4541
4542         local gid=10
4543         local sz=1000
4544
4545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4546         sync # Flush the cache so that multiop below does not block on cache
4547              # flush when getting the group lock
4548         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4549         MULTIPID=$!
4550
4551         # Since just timed wait is not good enough, let's do a sync write
4552         # that way we are sure enough time for a roundtrip + processing
4553         # passed + 2 seconds of extra margin.
4554         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4555         rm $DIR/${tfile}-1
4556         sleep 2
4557
4558         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4559                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4560                 kill -9 $MULTIPID
4561         fi
4562         wait $MULTIPID
4563         local nsz=`stat -c %s $DIR/$tfile`
4564         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4565 }
4566 run_test 34h "ftruncate file under grouplock should not block"
4567
4568 test_35a() {
4569         cp /bin/sh $DIR/f35a
4570         chmod 444 $DIR/f35a
4571         chown $RUNAS_ID $DIR/f35a
4572         $RUNAS $DIR/f35a && error || true
4573         rm $DIR/f35a
4574 }
4575 run_test 35a "exec file with mode 444 (should return and not leak)"
4576
4577 test_36a() {
4578         rm -f $DIR/f36
4579         utime $DIR/f36 || error "utime failed for MDS"
4580 }
4581 run_test 36a "MDS utime check (mknod, utime)"
4582
4583 test_36b() {
4584         echo "" > $DIR/f36
4585         utime $DIR/f36 || error "utime failed for OST"
4586 }
4587 run_test 36b "OST utime check (open, utime)"
4588
4589 test_36c() {
4590         rm -f $DIR/d36/f36
4591         test_mkdir $DIR/d36
4592         chown $RUNAS_ID $DIR/d36
4593         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4594 }
4595 run_test 36c "non-root MDS utime check (mknod, utime)"
4596
4597 test_36d() {
4598         [ ! -d $DIR/d36 ] && test_36c
4599         echo "" > $DIR/d36/f36
4600         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4601 }
4602 run_test 36d "non-root OST utime check (open, utime)"
4603
4604 test_36e() {
4605         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4606
4607         test_mkdir $DIR/$tdir
4608         touch $DIR/$tdir/$tfile
4609         $RUNAS utime $DIR/$tdir/$tfile &&
4610                 error "utime worked, expected failure" || true
4611 }
4612 run_test 36e "utime on non-owned file (should return error)"
4613
4614 subr_36fh() {
4615         local fl="$1"
4616         local LANG_SAVE=$LANG
4617         local LC_LANG_SAVE=$LC_LANG
4618         export LANG=C LC_LANG=C # for date language
4619
4620         DATESTR="Dec 20  2000"
4621         test_mkdir $DIR/$tdir
4622         lctl set_param fail_loc=$fl
4623         date; date +%s
4624         cp /etc/hosts $DIR/$tdir/$tfile
4625         sync & # write RPC generated with "current" inode timestamp, but delayed
4626         sleep 1
4627         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4628         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4629         cancel_lru_locks $OSC
4630         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4631         date; date +%s
4632         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4633                 echo "BEFORE: $LS_BEFORE" && \
4634                 echo "AFTER : $LS_AFTER" && \
4635                 echo "WANT  : $DATESTR" && \
4636                 error "$DIR/$tdir/$tfile timestamps changed" || true
4637
4638         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4639 }
4640
4641 test_36f() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643
4644         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4645         subr_36fh "0x80000214"
4646 }
4647 run_test 36f "utime on file racing with OST BRW write =========="
4648
4649 test_36g() {
4650         remote_ost_nodsh && skip "remote OST with nodsh"
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4653                 skip "Need MDS version at least 2.12.51"
4654
4655         local fmd_max_age
4656         local fmd
4657         local facet="ost1"
4658         local tgt="obdfilter"
4659
4660         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4661
4662         test_mkdir $DIR/$tdir
4663         fmd_max_age=$(do_facet $facet \
4664                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4665                 head -n 1")
4666
4667         echo "FMD max age: ${fmd_max_age}s"
4668         touch $DIR/$tdir/$tfile
4669         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4670                 gawk '{cnt=cnt+$1}  END{print cnt}')
4671         echo "FMD before: $fmd"
4672         [[ $fmd == 0 ]] &&
4673                 error "FMD wasn't create by touch"
4674         sleep $((fmd_max_age + 12))
4675         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4676                 gawk '{cnt=cnt+$1}  END{print cnt}')
4677         echo "FMD after: $fmd"
4678         [[ $fmd == 0 ]] ||
4679                 error "FMD wasn't expired by ping"
4680 }
4681 run_test 36g "FMD cache expiry ====================="
4682
4683 test_36h() {
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685
4686         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4687         subr_36fh "0x80000227"
4688 }
4689 run_test 36h "utime on file racing with OST BRW write =========="
4690
4691 test_36i() {
4692         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4693
4694         test_mkdir $DIR/$tdir
4695         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4696
4697         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4698         local new_mtime=$((mtime + 200))
4699
4700         #change Modify time of striped dir
4701         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4702                         error "change mtime failed"
4703
4704         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4705
4706         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4707 }
4708 run_test 36i "change mtime on striped directory"
4709
4710 # test_37 - duplicate with tests 32q 32r
4711
4712 test_38() {
4713         local file=$DIR/$tfile
4714         touch $file
4715         openfile -f O_DIRECTORY $file
4716         local RC=$?
4717         local ENOTDIR=20
4718         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4719         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4720 }
4721 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4722
4723 test_39a() { # was test_39
4724         touch $DIR/$tfile
4725         touch $DIR/${tfile}2
4726 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4727 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4728 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4729         sleep 2
4730         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4731         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4732                 echo "mtime"
4733                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4734                 echo "atime"
4735                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4736                 echo "ctime"
4737                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4738                 error "O_TRUNC didn't change timestamps"
4739         fi
4740 }
4741 run_test 39a "mtime changed on create"
4742
4743 test_39b() {
4744         test_mkdir -c1 $DIR/$tdir
4745         cp -p /etc/passwd $DIR/$tdir/fopen
4746         cp -p /etc/passwd $DIR/$tdir/flink
4747         cp -p /etc/passwd $DIR/$tdir/funlink
4748         cp -p /etc/passwd $DIR/$tdir/frename
4749         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4750
4751         sleep 1
4752         echo "aaaaaa" >> $DIR/$tdir/fopen
4753         echo "aaaaaa" >> $DIR/$tdir/flink
4754         echo "aaaaaa" >> $DIR/$tdir/funlink
4755         echo "aaaaaa" >> $DIR/$tdir/frename
4756
4757         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4758         local link_new=`stat -c %Y $DIR/$tdir/flink`
4759         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4760         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4761
4762         cat $DIR/$tdir/fopen > /dev/null
4763         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4764         rm -f $DIR/$tdir/funlink2
4765         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4766
4767         for (( i=0; i < 2; i++ )) ; do
4768                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4769                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4770                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4771                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4772
4773                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4774                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4775                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4776                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4777
4778                 cancel_lru_locks $OSC
4779                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4780         done
4781 }
4782 run_test 39b "mtime change on open, link, unlink, rename  ======"
4783
4784 # this should be set to past
4785 TEST_39_MTIME=`date -d "1 year ago" +%s`
4786
4787 # bug 11063
4788 test_39c() {
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local mtime0=`stat -c %Y $DIR1/$tfile`
4792
4793         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4794         local mtime1=`stat -c %Y $DIR1/$tfile`
4795         [ "$mtime1" = $TEST_39_MTIME ] || \
4796                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4797
4798         local d1=`date +%s`
4799         echo hello >> $DIR1/$tfile
4800         local d2=`date +%s`
4801         local mtime2=`stat -c %Y $DIR1/$tfile`
4802         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4803                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4804
4805         mv $DIR1/$tfile $DIR1/$tfile-1
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4809                 [ "$mtime2" = "$mtime3" ] || \
4810                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39c "mtime change on rename ==========================="
4817
4818 # bug 21114
4819 test_39d() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4824
4825         for (( i=0; i < 2; i++ )) ; do
4826                 local mtime=`stat -c %Y $DIR1/$tfile`
4827                 [ $mtime = $TEST_39_MTIME ] || \
4828                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4829
4830                 cancel_lru_locks $OSC
4831                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4832         done
4833 }
4834 run_test 39d "create, utime, stat =============================="
4835
4836 # bug 21114
4837 test_39e() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         touch $DIR1/$tfile
4841         local mtime1=`stat -c %Y $DIR1/$tfile`
4842
4843         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4844
4845         for (( i=0; i < 2; i++ )) ; do
4846                 local mtime2=`stat -c %Y $DIR1/$tfile`
4847                 [ $mtime2 = $TEST_39_MTIME ] || \
4848                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4849
4850                 cancel_lru_locks $OSC
4851                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4852         done
4853 }
4854 run_test 39e "create, stat, utime, stat ========================"
4855
4856 # bug 21114
4857 test_39f() {
4858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4859
4860         touch $DIR1/$tfile
4861         mtime1=`stat -c %Y $DIR1/$tfile`
4862
4863         sleep 2
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865
4866         for (( i=0; i < 2; i++ )) ; do
4867                 local mtime2=`stat -c %Y $DIR1/$tfile`
4868                 [ $mtime2 = $TEST_39_MTIME ] || \
4869                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4870
4871                 cancel_lru_locks $OSC
4872                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4873         done
4874 }
4875 run_test 39f "create, stat, sleep, utime, stat ================="
4876
4877 # bug 11063
4878 test_39g() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         echo hello >> $DIR1/$tfile
4882         local mtime1=`stat -c %Y $DIR1/$tfile`
4883
4884         sleep 2
4885         chmod o+r $DIR1/$tfile
4886
4887         for (( i=0; i < 2; i++ )) ; do
4888                 local mtime2=`stat -c %Y $DIR1/$tfile`
4889                 [ "$mtime1" = "$mtime2" ] || \
4890                         error "lost mtime: $mtime2, should be $mtime1"
4891
4892                 cancel_lru_locks $OSC
4893                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4894         done
4895 }
4896 run_test 39g "write, chmod, stat ==============================="
4897
4898 # bug 11063
4899 test_39h() {
4900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4901
4902         touch $DIR1/$tfile
4903         sleep 1
4904
4905         local d1=`date`
4906         echo hello >> $DIR1/$tfile
4907         local mtime1=`stat -c %Y $DIR1/$tfile`
4908
4909         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4910         local d2=`date`
4911         if [ "$d1" != "$d2" ]; then
4912                 echo "write and touch not within one second"
4913         else
4914                 for (( i=0; i < 2; i++ )) ; do
4915                         local mtime2=`stat -c %Y $DIR1/$tfile`
4916                         [ "$mtime2" = $TEST_39_MTIME ] || \
4917                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4918
4919                         cancel_lru_locks $OSC
4920                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4921                 done
4922         fi
4923 }
4924 run_test 39h "write, utime within one second, stat ============="
4925
4926 test_39i() {
4927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4928
4929         touch $DIR1/$tfile
4930         sleep 1
4931
4932         echo hello >> $DIR1/$tfile
4933         local mtime1=`stat -c %Y $DIR1/$tfile`
4934
4935         mv $DIR1/$tfile $DIR1/$tfile-1
4936
4937         for (( i=0; i < 2; i++ )) ; do
4938                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4939
4940                 [ "$mtime1" = "$mtime2" ] || \
4941                         error "lost mtime: $mtime2, should be $mtime1"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39i "write, rename, stat =============================="
4948
4949 test_39j() {
4950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4951
4952         start_full_debug_logging
4953         touch $DIR1/$tfile
4954         sleep 1
4955
4956         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4957         lctl set_param fail_loc=0x80000412
4958         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4959                 error "multiop failed"
4960         local multipid=$!
4961         local mtime1=`stat -c %Y $DIR1/$tfile`
4962
4963         mv $DIR1/$tfile $DIR1/$tfile-1
4964
4965         kill -USR1 $multipid
4966         wait $multipid || error "multiop close failed"
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4970                 [ "$mtime1" = "$mtime2" ] ||
4971                         error "mtime is lost on close: $mtime2, " \
4972                               "should be $mtime1"
4973
4974                 cancel_lru_locks
4975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4976         done
4977         lctl set_param fail_loc=0
4978         stop_full_debug_logging
4979 }
4980 run_test 39j "write, rename, close, stat ======================="
4981
4982 test_39k() {
4983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4984
4985         touch $DIR1/$tfile
4986         sleep 1
4987
4988         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4989         local multipid=$!
4990         local mtime1=`stat -c %Y $DIR1/$tfile`
4991
4992         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4993
4994         kill -USR1 $multipid
4995         wait $multipid || error "multiop close failed"
4996
4997         for (( i=0; i < 2; i++ )) ; do
4998                 local mtime2=`stat -c %Y $DIR1/$tfile`
4999
5000                 [ "$mtime2" = $TEST_39_MTIME ] || \
5001                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5002
5003                 cancel_lru_locks
5004                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5005         done
5006 }
5007 run_test 39k "write, utime, close, stat ========================"
5008
5009 # this should be set to future
5010 TEST_39_ATIME=`date -d "1 year" +%s`
5011
5012 test_39l() {
5013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5014         remote_mds_nodsh && skip "remote MDS with nodsh"
5015
5016         local atime_diff=$(do_facet $SINGLEMDS \
5017                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5018         rm -rf $DIR/$tdir
5019         mkdir_on_mdt0 $DIR/$tdir
5020
5021         # test setting directory atime to future
5022         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5023         local atime=$(stat -c %X $DIR/$tdir)
5024         [ "$atime" = $TEST_39_ATIME ] ||
5025                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5026
5027         # test setting directory atime from future to now
5028         local now=$(date +%s)
5029         touch -a -d @$now $DIR/$tdir
5030
5031         atime=$(stat -c %X $DIR/$tdir)
5032         [ "$atime" -eq "$now"  ] ||
5033                 error "atime is not updated from future: $atime, $now"
5034
5035         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5036         sleep 3
5037
5038         # test setting directory atime when now > dir atime + atime_diff
5039         local d1=$(date +%s)
5040         ls $DIR/$tdir
5041         local d2=$(date +%s)
5042         cancel_lru_locks mdc
5043         atime=$(stat -c %X $DIR/$tdir)
5044         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5045                 error "atime is not updated  : $atime, should be $d2"
5046
5047         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5048         sleep 3
5049
5050         # test not setting directory atime when now < dir atime + atime_diff
5051         ls $DIR/$tdir
5052         cancel_lru_locks mdc
5053         atime=$(stat -c %X $DIR/$tdir)
5054         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5055                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5056
5057         do_facet $SINGLEMDS \
5058                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5059 }
5060 run_test 39l "directory atime update ==========================="
5061
5062 test_39m() {
5063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5064
5065         touch $DIR1/$tfile
5066         sleep 2
5067         local far_past_mtime=$(date -d "May 29 1953" +%s)
5068         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5069
5070         touch -m -d @$far_past_mtime $DIR1/$tfile
5071         touch -a -d @$far_past_atime $DIR1/$tfile
5072
5073         for (( i=0; i < 2; i++ )) ; do
5074                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5075                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5076                         error "atime or mtime set incorrectly"
5077
5078                 cancel_lru_locks $OSC
5079                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5080         done
5081 }
5082 run_test 39m "test atime and mtime before 1970"
5083
5084 test_39n() { # LU-3832
5085         remote_mds_nodsh && skip "remote MDS with nodsh"
5086
5087         local atime_diff=$(do_facet $SINGLEMDS \
5088                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5089         local atime0
5090         local atime1
5091         local atime2
5092
5093         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5094
5095         rm -rf $DIR/$tfile
5096         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5097         atime0=$(stat -c %X $DIR/$tfile)
5098
5099         sleep 5
5100         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5101         atime1=$(stat -c %X $DIR/$tfile)
5102
5103         sleep 5
5104         cancel_lru_locks mdc
5105         cancel_lru_locks osc
5106         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5107         atime2=$(stat -c %X $DIR/$tfile)
5108
5109         do_facet $SINGLEMDS \
5110                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5111
5112         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5113         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5114 }
5115 run_test 39n "check that O_NOATIME is honored"
5116
5117 test_39o() {
5118         TESTDIR=$DIR/$tdir/$tfile
5119         [ -e $TESTDIR ] && rm -rf $TESTDIR
5120         mkdir -p $TESTDIR
5121         cd $TESTDIR
5122         links1=2
5123         ls
5124         mkdir a b
5125         ls
5126         links2=$(stat -c %h .)
5127         [ $(($links1 + 2)) != $links2 ] &&
5128                 error "wrong links count $(($links1 + 2)) != $links2"
5129         rmdir b
5130         links3=$(stat -c %h .)
5131         [ $(($links1 + 1)) != $links3 ] &&
5132                 error "wrong links count $links1 != $links3"
5133         return 0
5134 }
5135 run_test 39o "directory cached attributes updated after create"
5136
5137 test_39p() {
5138         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5139
5140         local MDTIDX=1
5141         TESTDIR=$DIR/$tdir/$tdir
5142         [ -e $TESTDIR ] && rm -rf $TESTDIR
5143         test_mkdir -p $TESTDIR
5144         cd $TESTDIR
5145         links1=2
5146         ls
5147         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5148         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5149         ls
5150         links2=$(stat -c %h .)
5151         [ $(($links1 + 2)) != $links2 ] &&
5152                 error "wrong links count $(($links1 + 2)) != $links2"
5153         rmdir remote_dir2
5154         links3=$(stat -c %h .)
5155         [ $(($links1 + 1)) != $links3 ] &&
5156                 error "wrong links count $links1 != $links3"
5157         return 0
5158 }
5159 run_test 39p "remote directory cached attributes updated after create ========"
5160
5161 test_39r() {
5162         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5163                 skip "no atime update on old OST"
5164         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5165                 skip_env "ldiskfs only test"
5166         fi
5167
5168         local saved_adiff
5169         saved_adiff=$(do_facet ost1 \
5170                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5171         stack_trap "do_facet ost1 \
5172                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5173
5174         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5175
5176         $LFS setstripe -i 0 $DIR/$tfile
5177         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5178                 error "can't write initial file"
5179         cancel_lru_locks osc
5180
5181         # exceed atime_diff and access file
5182         sleep 10
5183         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5184                 error "can't udpate atime"
5185
5186         local atime_cli=$(stat -c %X $DIR/$tfile)
5187         echo "client atime: $atime_cli"
5188         # allow atime update to be written to device
5189         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5190         sleep 5
5191
5192         local ostdev=$(ostdevname 1)
5193         local fid=($(lfs getstripe -y $DIR/$tfile |
5194                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5195         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5196         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5197
5198         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5199         local atime_ost=$(do_facet ost1 "$cmd" |&
5200                           awk -F'[: ]' '/atime:/ { print $4 }')
5201         (( atime_cli == atime_ost )) ||
5202                 error "atime on client $atime_cli != ost $atime_ost"
5203 }
5204 run_test 39r "lazy atime update on OST"
5205
5206 test_39q() { # LU-8041
5207         local testdir=$DIR/$tdir
5208         mkdir -p $testdir
5209         multiop_bg_pause $testdir D_c || error "multiop failed"
5210         local multipid=$!
5211         cancel_lru_locks mdc
5212         kill -USR1 $multipid
5213         local atime=$(stat -c %X $testdir)
5214         [ "$atime" -ne 0 ] || error "atime is zero"
5215 }
5216 run_test 39q "close won't zero out atime"
5217
5218 test_40() {
5219         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5220         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5221                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5222         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5223                 error "$tfile is not 4096 bytes in size"
5224 }
5225 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5226
5227 test_41() {
5228         # bug 1553
5229         small_write $DIR/f41 18
5230 }
5231 run_test 41 "test small file write + fstat ====================="
5232
5233 count_ost_writes() {
5234         lctl get_param -n ${OSC}.*.stats |
5235                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5236                         END { printf("%0.0f", writes) }'
5237 }
5238
5239 # decent default
5240 WRITEBACK_SAVE=500
5241 DIRTY_RATIO_SAVE=40
5242 MAX_DIRTY_RATIO=50
5243 BG_DIRTY_RATIO_SAVE=10
5244 MAX_BG_DIRTY_RATIO=25
5245
5246 start_writeback() {
5247         trap 0
5248         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5249         # dirty_ratio, dirty_background_ratio
5250         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5251                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5252                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5253                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5254         else
5255                 # if file not here, we are a 2.4 kernel
5256                 kill -CONT `pidof kupdated`
5257         fi
5258 }
5259
5260 stop_writeback() {
5261         # setup the trap first, so someone cannot exit the test at the
5262         # exact wrong time and mess up a machine
5263         trap start_writeback EXIT
5264         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5265         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5266                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5267                 sysctl -w vm.dirty_writeback_centisecs=0
5268                 sysctl -w vm.dirty_writeback_centisecs=0
5269                 # save and increase /proc/sys/vm/dirty_ratio
5270                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5271                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5272                 # save and increase /proc/sys/vm/dirty_background_ratio
5273                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5274                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5275         else
5276                 # if file not here, we are a 2.4 kernel
5277                 kill -STOP `pidof kupdated`
5278         fi
5279 }
5280
5281 # ensure that all stripes have some grant before we test client-side cache
5282 setup_test42() {
5283         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5284                 dd if=/dev/zero of=$i bs=4k count=1
5285                 rm $i
5286         done
5287 }
5288
5289 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5290 # file truncation, and file removal.
5291 test_42a() {
5292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5293
5294         setup_test42
5295         cancel_lru_locks $OSC
5296         stop_writeback
5297         sync; sleep 1; sync # just to be safe
5298         BEFOREWRITES=`count_ost_writes`
5299         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5300         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5301         AFTERWRITES=`count_ost_writes`
5302         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5303                 error "$BEFOREWRITES < $AFTERWRITES"
5304         start_writeback
5305 }
5306 run_test 42a "ensure that we don't flush on close"
5307
5308 test_42b() {
5309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5310
5311         setup_test42
5312         cancel_lru_locks $OSC
5313         stop_writeback
5314         sync
5315         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5316         BEFOREWRITES=$(count_ost_writes)
5317         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5318         AFTERWRITES=$(count_ost_writes)
5319         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5320                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5321         fi
5322         BEFOREWRITES=$(count_ost_writes)
5323         sync || error "sync: $?"
5324         AFTERWRITES=$(count_ost_writes)
5325         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5326                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5327         fi
5328         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5329         start_writeback
5330         return 0
5331 }
5332 run_test 42b "test destroy of file with cached dirty data ======"
5333
5334 # if these tests just want to test the effect of truncation,
5335 # they have to be very careful.  consider:
5336 # - the first open gets a {0,EOF}PR lock
5337 # - the first write conflicts and gets a {0, count-1}PW
5338 # - the rest of the writes are under {count,EOF}PW
5339 # - the open for truncate tries to match a {0,EOF}PR
5340 #   for the filesize and cancels the PWs.
5341 # any number of fixes (don't get {0,EOF} on open, match
5342 # composite locks, do smarter file size management) fix
5343 # this, but for now we want these tests to verify that
5344 # the cancellation with truncate intent works, so we
5345 # start the file with a full-file pw lock to match against
5346 # until the truncate.
5347 trunc_test() {
5348         test=$1
5349         file=$DIR/$test
5350         offset=$2
5351         cancel_lru_locks $OSC
5352         stop_writeback
5353         # prime the file with 0,EOF PW to match
5354         touch $file
5355         $TRUNCATE $file 0
5356         sync; sync
5357         # now the real test..
5358         dd if=/dev/zero of=$file bs=1024 count=100
5359         BEFOREWRITES=`count_ost_writes`
5360         $TRUNCATE $file $offset
5361         cancel_lru_locks $OSC
5362         AFTERWRITES=`count_ost_writes`
5363         start_writeback
5364 }
5365
5366 test_42c() {
5367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5368
5369         trunc_test 42c 1024
5370         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5371                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5372         rm $file
5373 }
5374 run_test 42c "test partial truncate of file with cached dirty data"
5375
5376 test_42d() {
5377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5378
5379         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5380         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5381         $LCTL set_param debug=+cache
5382
5383         trunc_test 42d 0
5384         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5385                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5386         rm $file
5387 }
5388 run_test 42d "test complete truncate of file with cached dirty data"
5389
5390 test_42e() { # bug22074
5391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5392
5393         local TDIR=$DIR/${tdir}e
5394         local pages=16 # hardcoded 16 pages, don't change it.
5395         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5396         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5397         local max_dirty_mb
5398         local warmup_files
5399
5400         test_mkdir $DIR/${tdir}e
5401         $LFS setstripe -c 1 $TDIR
5402         createmany -o $TDIR/f $files
5403
5404         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5405
5406         # we assume that with $OSTCOUNT files, at least one of them will
5407         # be allocated on OST0.
5408         warmup_files=$((OSTCOUNT * max_dirty_mb))
5409         createmany -o $TDIR/w $warmup_files
5410
5411         # write a large amount of data into one file and sync, to get good
5412         # avail_grant number from OST.
5413         for ((i=0; i<$warmup_files; i++)); do
5414                 idx=$($LFS getstripe -i $TDIR/w$i)
5415                 [ $idx -ne 0 ] && continue
5416                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5417                 break
5418         done
5419         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5420         sync
5421         $LCTL get_param $proc_osc0/cur_dirty_bytes
5422         $LCTL get_param $proc_osc0/cur_grant_bytes
5423
5424         # create as much dirty pages as we can while not to trigger the actual
5425         # RPCs directly. but depends on the env, VFS may trigger flush during this
5426         # period, hopefully we are good.
5427         for ((i=0; i<$warmup_files; i++)); do
5428                 idx=$($LFS getstripe -i $TDIR/w$i)
5429                 [ $idx -ne 0 ] && continue
5430                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5431         done
5432         $LCTL get_param $proc_osc0/cur_dirty_bytes
5433         $LCTL get_param $proc_osc0/cur_grant_bytes
5434
5435         # perform the real test
5436         $LCTL set_param $proc_osc0/rpc_stats 0
5437         for ((;i<$files; i++)); do
5438                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5439                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5440         done
5441         sync
5442         $LCTL get_param $proc_osc0/rpc_stats
5443
5444         local percent=0
5445         local have_ppr=false
5446         $LCTL get_param $proc_osc0/rpc_stats |
5447                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5448                         # skip lines until we are at the RPC histogram data
5449                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5450                         $have_ppr || continue
5451
5452                         # we only want the percent stat for < 16 pages
5453                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5454
5455                         percent=$((percent + WPCT))
5456                         if [[ $percent -gt 15 ]]; then
5457                                 error "less than 16-pages write RPCs" \
5458                                       "$percent% > 15%"
5459                                 break
5460                         fi
5461                 done
5462         rm -rf $TDIR
5463 }
5464 run_test 42e "verify sub-RPC writes are not done synchronously"
5465
5466 test_43A() { # was test_43
5467         test_mkdir $DIR/$tdir
5468         cp -p /bin/ls $DIR/$tdir/$tfile
5469         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5470         pid=$!
5471         # give multiop a chance to open
5472         sleep 1
5473
5474         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5475         kill -USR1 $pid
5476         # Wait for multiop to exit
5477         wait $pid
5478 }
5479 run_test 43A "execution of file opened for write should return -ETXTBSY"
5480
5481 test_43a() {
5482         test_mkdir $DIR/$tdir
5483         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5484         $DIR/$tdir/sleep 60 &
5485         SLEEP_PID=$!
5486         # Make sure exec of $tdir/sleep wins race with truncate
5487         sleep 1
5488         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5489         kill $SLEEP_PID
5490 }
5491 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5492
5493 test_43b() {
5494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5495
5496         test_mkdir $DIR/$tdir
5497         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5498         $DIR/$tdir/sleep 60 &
5499         SLEEP_PID=$!
5500         # Make sure exec of $tdir/sleep wins race with truncate
5501         sleep 1
5502         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5503         kill $SLEEP_PID
5504 }
5505 run_test 43b "truncate of file being executed should return -ETXTBSY"
5506
5507 test_43c() {
5508         local testdir="$DIR/$tdir"
5509         test_mkdir $testdir
5510         cp $SHELL $testdir/
5511         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5512                 ( cd $testdir && md5sum -c )
5513 }
5514 run_test 43c "md5sum of copy into lustre"
5515
5516 test_44A() { # was test_44
5517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5518
5519         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5520         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5521 }
5522 run_test 44A "zero length read from a sparse stripe"
5523
5524 test_44a() {
5525         local nstripe=$($LFS getstripe -c -d $DIR)
5526         [ -z "$nstripe" ] && skip "can't get stripe info"
5527         [[ $nstripe -gt $OSTCOUNT ]] &&
5528                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5529
5530         local stride=$($LFS getstripe -S -d $DIR)
5531         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5532                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5533         fi
5534
5535         OFFSETS="0 $((stride/2)) $((stride-1))"
5536         for offset in $OFFSETS; do
5537                 for i in $(seq 0 $((nstripe-1))); do
5538                         local GLOBALOFFSETS=""
5539                         # size in Bytes
5540                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5541                         local myfn=$DIR/d44a-$size
5542                         echo "--------writing $myfn at $size"
5543                         ll_sparseness_write $myfn $size ||
5544                                 error "ll_sparseness_write"
5545                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5546                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5547                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5548
5549                         for j in $(seq 0 $((nstripe-1))); do
5550                                 # size in Bytes
5551                                 size=$((((j + $nstripe )*$stride + $offset)))
5552                                 ll_sparseness_write $myfn $size ||
5553                                         error "ll_sparseness_write"
5554                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5555                         done
5556                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5557                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5558                         rm -f $myfn
5559                 done
5560         done
5561 }
5562 run_test 44a "test sparse pwrite ==============================="
5563
5564 dirty_osc_total() {
5565         tot=0
5566         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5567                 tot=$(($tot + $d))
5568         done
5569         echo $tot
5570 }
5571 do_dirty_record() {
5572         before=`dirty_osc_total`
5573         echo executing "\"$*\""
5574         eval $*
5575         after=`dirty_osc_total`
5576         echo before $before, after $after
5577 }
5578 test_45() {
5579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5580
5581         f="$DIR/f45"
5582         # Obtain grants from OST if it supports it
5583         echo blah > ${f}_grant
5584         stop_writeback
5585         sync
5586         do_dirty_record "echo blah > $f"
5587         [[ $before -eq $after ]] && error "write wasn't cached"
5588         do_dirty_record "> $f"
5589         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5590         do_dirty_record "echo blah > $f"
5591         [[ $before -eq $after ]] && error "write wasn't cached"
5592         do_dirty_record "sync"
5593         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5594         do_dirty_record "echo blah > $f"
5595         [[ $before -eq $after ]] && error "write wasn't cached"
5596         do_dirty_record "cancel_lru_locks osc"
5597         [[ $before -gt $after ]] ||
5598                 error "lock cancellation didn't lower dirty count"
5599         start_writeback
5600 }
5601 run_test 45 "osc io page accounting ============================"
5602
5603 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5604 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5605 # objects offset and an assert hit when an rpc was built with 1023's mapped
5606 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5607 test_46() {
5608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5609
5610         f="$DIR/f46"
5611         stop_writeback
5612         sync
5613         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5614         sync
5615         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5616         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5617         sync
5618         start_writeback
5619 }
5620 run_test 46 "dirtying a previously written page ================"
5621
5622 # test_47 is removed "Device nodes check" is moved to test_28
5623
5624 test_48a() { # bug 2399
5625         [ "$mds1_FSTYPE" = "zfs" ] &&
5626         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5627                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5628
5629         test_mkdir $DIR/$tdir
5630         cd $DIR/$tdir
5631         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5632         test_mkdir $DIR/$tdir
5633         touch foo || error "'touch foo' failed after recreating cwd"
5634         test_mkdir bar
5635         touch .foo || error "'touch .foo' failed after recreating cwd"
5636         test_mkdir .bar
5637         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5638         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5639         cd . || error "'cd .' failed after recreating cwd"
5640         mkdir . && error "'mkdir .' worked after recreating cwd"
5641         rmdir . && error "'rmdir .' worked after recreating cwd"
5642         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5643         cd .. || error "'cd ..' failed after recreating cwd"
5644 }
5645 run_test 48a "Access renamed working dir (should return errors)="
5646
5647 test_48b() { # bug 2399
5648         rm -rf $DIR/$tdir
5649         test_mkdir $DIR/$tdir
5650         cd $DIR/$tdir
5651         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5652         touch foo && error "'touch foo' worked after removing cwd"
5653         mkdir foo && error "'mkdir foo' worked after removing cwd"
5654         touch .foo && error "'touch .foo' worked after removing cwd"
5655         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5656         ls . > /dev/null && error "'ls .' worked after removing cwd"
5657         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5658         mkdir . && error "'mkdir .' worked after removing cwd"
5659         rmdir . && error "'rmdir .' worked after removing cwd"
5660         ln -s . foo && error "'ln -s .' worked after removing cwd"
5661         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5662 }
5663 run_test 48b "Access removed working dir (should return errors)="
5664
5665 test_48c() { # bug 2350
5666         #lctl set_param debug=-1
5667         #set -vx
5668         rm -rf $DIR/$tdir
5669         test_mkdir -p $DIR/$tdir/dir
5670         cd $DIR/$tdir/dir
5671         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5672         $TRACE touch foo && error "touch foo worked after removing cwd"
5673         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5674         touch .foo && error "touch .foo worked after removing cwd"
5675         mkdir .foo && error "mkdir .foo worked after removing cwd"
5676         $TRACE ls . && error "'ls .' worked after removing cwd"
5677         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5678         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5679         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5680         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5681         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5682 }
5683 run_test 48c "Access removed working subdir (should return errors)"
5684
5685 test_48d() { # bug 2350
5686         #lctl set_param debug=-1
5687         #set -vx
5688         rm -rf $DIR/$tdir
5689         test_mkdir -p $DIR/$tdir/dir
5690         cd $DIR/$tdir/dir
5691         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5692         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5693         $TRACE touch foo && error "'touch foo' worked after removing parent"
5694         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5695         touch .foo && error "'touch .foo' worked after removing parent"
5696         mkdir .foo && error "mkdir .foo worked after removing parent"
5697         $TRACE ls . && error "'ls .' worked after removing parent"
5698         $TRACE ls .. && error "'ls ..' worked after removing parent"
5699         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5700         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5701         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5702         true
5703 }
5704 run_test 48d "Access removed parent subdir (should return errors)"
5705
5706 test_48e() { # bug 4134
5707         #lctl set_param debug=-1
5708         #set -vx
5709         rm -rf $DIR/$tdir
5710         test_mkdir -p $DIR/$tdir/dir
5711         cd $DIR/$tdir/dir
5712         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5713         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5714         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5715         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5716         # On a buggy kernel addition of "touch foo" after cd .. will
5717         # produce kernel oops in lookup_hash_it
5718         touch ../foo && error "'cd ..' worked after recreate parent"
5719         cd $DIR
5720         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5721 }
5722 run_test 48e "Access to recreated parent subdir (should return errors)"
5723
5724 test_48f() {
5725         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5726                 skip "need MDS >= 2.13.55"
5727         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5728         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5729                 skip "needs different host for mdt1 mdt2"
5730         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5731
5732         $LFS mkdir -i0 $DIR/$tdir
5733         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5734
5735         for d in sub1 sub2 sub3; do
5736                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5737                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5738                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5739         done
5740
5741         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5742 }
5743 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5744
5745 test_49() { # LU-1030
5746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5747         remote_ost_nodsh && skip "remote OST with nodsh"
5748
5749         # get ost1 size - $FSNAME-OST0000
5750         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5751                 awk '{ print $4 }')
5752         # write 800M at maximum
5753         [[ $ost1_size -lt 2 ]] && ost1_size=2
5754         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5755
5756         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5757         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5758         local dd_pid=$!
5759
5760         # change max_pages_per_rpc while writing the file
5761         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5762         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5763         # loop until dd process exits
5764         while ps ax -opid | grep -wq $dd_pid; do
5765                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5766                 sleep $((RANDOM % 5 + 1))
5767         done
5768         # restore original max_pages_per_rpc
5769         $LCTL set_param $osc1_mppc=$orig_mppc
5770         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5771 }
5772 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5773
5774 test_50() {
5775         # bug 1485
5776         test_mkdir $DIR/$tdir
5777         cd $DIR/$tdir
5778         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5779 }
5780 run_test 50 "special situations: /proc symlinks  ==============="
5781
5782 test_51a() {    # was test_51
5783         # bug 1516 - create an empty entry right after ".." then split dir
5784         test_mkdir -c1 $DIR/$tdir
5785         touch $DIR/$tdir/foo
5786         $MCREATE $DIR/$tdir/bar
5787         rm $DIR/$tdir/foo
5788         createmany -m $DIR/$tdir/longfile 201
5789         FNUM=202
5790         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5791                 $MCREATE $DIR/$tdir/longfile$FNUM
5792                 FNUM=$(($FNUM + 1))
5793                 echo -n "+"
5794         done
5795         echo
5796         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5797 }
5798 run_test 51a "special situations: split htree with empty entry =="
5799
5800 cleanup_print_lfs_df () {
5801         trap 0
5802         $LFS df
5803         $LFS df -i
5804 }
5805
5806 test_51b() {
5807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5808
5809         local dir=$DIR/$tdir
5810         local nrdirs=$((65536 + 100))
5811
5812         # cleanup the directory
5813         rm -fr $dir
5814
5815         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5816
5817         $LFS df
5818         $LFS df -i
5819         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5820         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5821         [[ $numfree -lt $nrdirs ]] &&
5822                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5823
5824         # need to check free space for the directories as well
5825         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5826         numfree=$(( blkfree / $(fs_inode_ksize) ))
5827         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5828
5829         trap cleanup_print_lfs_df EXIT
5830
5831         # create files
5832         createmany -d $dir/d $nrdirs || {
5833                 unlinkmany $dir/d $nrdirs
5834                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5835         }
5836
5837         # really created :
5838         nrdirs=$(ls -U $dir | wc -l)
5839
5840         # unlink all but 100 subdirectories, then check it still works
5841         local left=100
5842         local delete=$((nrdirs - left))
5843
5844         $LFS df
5845         $LFS df -i
5846
5847         # for ldiskfs the nlink count should be 1, but this is OSD specific
5848         # and so this is listed for informational purposes only
5849         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5850         unlinkmany -d $dir/d $delete ||
5851                 error "unlink of first $delete subdirs failed"
5852
5853         echo "nlink between: $(stat -c %h $dir)"
5854         local found=$(ls -U $dir | wc -l)
5855         [ $found -ne $left ] &&
5856                 error "can't find subdirs: found only $found, expected $left"
5857
5858         unlinkmany -d $dir/d $delete $left ||
5859                 error "unlink of second $left subdirs failed"
5860         # regardless of whether the backing filesystem tracks nlink accurately
5861         # or not, the nlink count shouldn't be more than "." and ".." here
5862         local after=$(stat -c %h $dir)
5863         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5864                 echo "nlink after: $after"
5865
5866         cleanup_print_lfs_df
5867 }
5868 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5869
5870 test_51d_sub() {
5871         local stripecount=$1
5872         local nfiles=$2
5873
5874         log "create files with stripecount=$stripecount"
5875         $LFS setstripe -C $stripecount $DIR/$tdir
5876         createmany -o $DIR/$tdir/t- $nfiles
5877         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5878         for ((n = 0; n < $OSTCOUNT; n++)); do
5879                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5880                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5881                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5882                             '($1 == '$n') { objs += 1 } \
5883                             END { printf("%0.0f", objs) }')
5884                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5885         done
5886         unlinkmany $DIR/$tdir/t- $nfiles
5887         rm  -f $TMP/$tfile
5888
5889         local nlast
5890         local min=4
5891         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5892
5893         # For some combinations of stripecount and OSTCOUNT current code
5894         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5895         # than others. Rather than skipping this test entirely, check that
5896         # and keep testing to ensure imbalance does not get worse. LU-15282
5897         (( (OSTCOUNT == 6 && stripecount == 4) ||
5898            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5899            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5900         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5901                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5902                         { $LFS df && $LFS df -i &&
5903                         error "stripecount=$stripecount: " \
5904                               "OST $n has fewer objects vs. OST $nlast " \
5905                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5906                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5907                         { $LFS df && $LFS df -i &&
5908                         error "stripecount=$stripecount: " \
5909                               "OST $n has more objects vs. OST $nlast " \
5910                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5911
5912                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5913                         { $LFS df && $LFS df -i &&
5914                         error "stripecount=$stripecount: " \
5915                               "OST $n has fewer #0 objects vs. OST $nlast " \
5916                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5917                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5918                         { $LFS df && $LFS df -i &&
5919                         error "stripecount=$stripecount: " \
5920                               "OST $n has more #0 objects vs. OST $nlast " \
5921                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5922         done
5923 }
5924
5925 test_51d() {
5926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5927         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5928
5929         local stripecount
5930         local per_ost=100
5931         local nfiles=$((per_ost * OSTCOUNT))
5932         local mdts=$(comma_list $(mdts_nodes))
5933         local param="osp.*.create_count"
5934         local qos_old=$(do_facet mds1 \
5935                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5936
5937         do_nodes $mdts \
5938                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5939         stack_trap "do_nodes $mdts \
5940                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5941
5942         test_mkdir $DIR/$tdir
5943         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5944         (( dirstripes > 0 )) || dirstripes=1
5945
5946         # Ensure enough OST objects precreated for tests to pass without
5947         # running out of objects.  This is an LOV r-r OST algorithm test,
5948         # not an OST object precreation test.
5949         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5950         (( old >= nfiles )) ||
5951         {
5952                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5953
5954                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5955                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5956
5957                 # trigger precreation from all MDTs for all OSTs
5958                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5959                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5960                 done
5961         }
5962
5963         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5964                 sleep 8  # allow object precreation to catch up
5965                 test_51d_sub $stripecount $nfiles
5966         done
5967 }
5968 run_test 51d "check LOV round-robin OST object distribution"
5969
5970 test_51e() {
5971         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5972                 skip_env "ldiskfs only test"
5973         fi
5974
5975         test_mkdir -c1 $DIR/$tdir
5976         test_mkdir -c1 $DIR/$tdir/d0
5977
5978         touch $DIR/$tdir/d0/foo
5979         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5980                 error "file exceed 65000 nlink limit!"
5981         unlinkmany $DIR/$tdir/d0/f- 65001
5982         return 0
5983 }
5984 run_test 51e "check file nlink limit"
5985
5986 test_51f() {
5987         test_mkdir $DIR/$tdir
5988
5989         local max=100000
5990         local ulimit_old=$(ulimit -n)
5991         local spare=20 # number of spare fd's for scripts/libraries, etc.
5992         local mdt=$($LFS getstripe -m $DIR/$tdir)
5993         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5994
5995         echo "MDT$mdt numfree=$numfree, max=$max"
5996         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5997         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5998                 while ! ulimit -n $((numfree + spare)); do
5999                         numfree=$((numfree * 3 / 4))
6000                 done
6001                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6002         else
6003                 echo "left ulimit at $ulimit_old"
6004         fi
6005
6006         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6007                 unlinkmany $DIR/$tdir/f $numfree
6008                 error "create+open $numfree files in $DIR/$tdir failed"
6009         }
6010         ulimit -n $ulimit_old
6011
6012         # if createmany exits at 120s there will be fewer than $numfree files
6013         unlinkmany $DIR/$tdir/f $numfree || true
6014 }
6015 run_test 51f "check many open files limit"
6016
6017 test_52a() {
6018         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6019         test_mkdir $DIR/$tdir
6020         touch $DIR/$tdir/foo
6021         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6022         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6023         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6024         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6025         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6026                                         error "link worked"
6027         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6028         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6029         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6030                                                      error "lsattr"
6031         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6032         cp -r $DIR/$tdir $TMP/
6033         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6034 }
6035 run_test 52a "append-only flag test (should return errors)"
6036
6037 test_52b() {
6038         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6039         test_mkdir $DIR/$tdir
6040         touch $DIR/$tdir/foo
6041         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6042         cat test > $DIR/$tdir/foo && error "cat test worked"
6043         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6044         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6045         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6046                                         error "link worked"
6047         echo foo >> $DIR/$tdir/foo && error "echo worked"
6048         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6049         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6050         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6051         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6052                                                         error "lsattr"
6053         chattr -i $DIR/$tdir/foo || error "chattr failed"
6054
6055         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6056 }
6057 run_test 52b "immutable flag test (should return errors) ======="
6058
6059 test_53() {
6060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6061         remote_mds_nodsh && skip "remote MDS with nodsh"
6062         remote_ost_nodsh && skip "remote OST with nodsh"
6063
6064         local param
6065         local param_seq
6066         local ostname
6067         local mds_last
6068         local mds_last_seq
6069         local ost_last
6070         local ost_last_seq
6071         local ost_last_id
6072         local ostnum
6073         local node
6074         local found=false
6075         local support_last_seq=true
6076
6077         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6078                 support_last_seq=false
6079
6080         # only test MDT0000
6081         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6082         local value
6083         for value in $(do_facet $SINGLEMDS \
6084                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6085                 param=$(echo ${value[0]} | cut -d "=" -f1)
6086                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6087
6088                 if $support_last_seq; then
6089                         param_seq=$(echo $param |
6090                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6091                         mds_last_seq=$(do_facet $SINGLEMDS \
6092                                        $LCTL get_param -n $param_seq)
6093                 fi
6094                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6095
6096                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6097                 node=$(facet_active_host ost$((ostnum+1)))
6098                 param="obdfilter.$ostname.last_id"
6099                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6100                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6101                         ost_last_id=$ost_last
6102
6103                         if $support_last_seq; then
6104                                 ost_last_id=$(echo $ost_last |
6105                                               awk -F':' '{print $2}' |
6106                                               sed -e "s/^0x//g")
6107                                 ost_last_seq=$(echo $ost_last |
6108                                                awk -F':' '{print $1}')
6109                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6110                         fi
6111
6112                         if [[ $ost_last_id != $mds_last ]]; then
6113                                 error "$ost_last_id != $mds_last"
6114                         else
6115                                 found=true
6116                                 break
6117                         fi
6118                 done
6119         done
6120         $found || error "can not match last_seq/last_id for $mdtosc"
6121         return 0
6122 }
6123 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6124
6125 test_54a() {
6126         perl -MSocket -e ';' || skip "no Socket perl module installed"
6127
6128         $SOCKETSERVER $DIR/socket ||
6129                 error "$SOCKETSERVER $DIR/socket failed: $?"
6130         $SOCKETCLIENT $DIR/socket ||
6131                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6132         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6133 }
6134 run_test 54a "unix domain socket test =========================="
6135
6136 test_54b() {
6137         f="$DIR/f54b"
6138         mknod $f c 1 3
6139         chmod 0666 $f
6140         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6141 }
6142 run_test 54b "char device works in lustre ======================"
6143
6144 find_loop_dev() {
6145         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6146         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6147         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6148
6149         for i in $(seq 3 7); do
6150                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6151                 LOOPDEV=$LOOPBASE$i
6152                 LOOPNUM=$i
6153                 break
6154         done
6155 }
6156
6157 cleanup_54c() {
6158         local rc=0
6159         loopdev="$DIR/loop54c"
6160
6161         trap 0
6162         $UMOUNT $DIR/$tdir || rc=$?
6163         losetup -d $loopdev || true
6164         losetup -d $LOOPDEV || true
6165         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6166         return $rc
6167 }
6168
6169 test_54c() {
6170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6171
6172         loopdev="$DIR/loop54c"
6173
6174         find_loop_dev
6175         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6176         trap cleanup_54c EXIT
6177         mknod $loopdev b 7 $LOOPNUM
6178         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6179         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6180         losetup $loopdev $DIR/$tfile ||
6181                 error "can't set up $loopdev for $DIR/$tfile"
6182         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6183         test_mkdir $DIR/$tdir
6184         mount -t ext2 $loopdev $DIR/$tdir ||
6185                 error "error mounting $loopdev on $DIR/$tdir"
6186         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6187                 error "dd write"
6188         df $DIR/$tdir
6189         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6190                 error "dd read"
6191         cleanup_54c
6192 }
6193 run_test 54c "block device works in lustre ====================="
6194
6195 test_54d() {
6196         local pipe="$DIR/$tfile.pipe"
6197         local string="aaaaaa"
6198
6199         mknod $pipe p
6200         echo -n "$string" > $pipe &
6201         local result=$(cat $pipe)
6202         [[ "$result" == "$string" ]] || error "$result != $string"
6203 }
6204 run_test 54d "fifo device works in lustre ======================"
6205
6206 test_54e() {
6207         f="$DIR/f54e"
6208         string="aaaaaa"
6209         cp -aL /dev/console $f
6210         echo $string > $f || error "echo $string to $f failed"
6211 }
6212 run_test 54e "console/tty device works in lustre ======================"
6213
6214 test_56a() {
6215         local numfiles=3
6216         local numdirs=2
6217         local dir=$DIR/$tdir
6218
6219         rm -rf $dir
6220         test_mkdir -p $dir/dir
6221         for i in $(seq $numfiles); do
6222                 touch $dir/file$i
6223                 touch $dir/dir/file$i
6224         done
6225
6226         local numcomp=$($LFS getstripe --component-count $dir)
6227
6228         [[ $numcomp == 0 ]] && numcomp=1
6229
6230         # test lfs getstripe with --recursive
6231         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6232
6233         [[ $filenum -eq $((numfiles * 2)) ]] ||
6234                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6235         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6236         [[ $filenum -eq $numfiles ]] ||
6237                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6238         echo "$LFS getstripe showed obdidx or l_ost_idx"
6239
6240         # test lfs getstripe with file instead of dir
6241         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6242         [[ $filenum -eq 1 ]] ||
6243                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6244         echo "$LFS getstripe file1 passed"
6245
6246         #test lfs getstripe with --verbose
6247         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6248         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6249                 error "$LFS getstripe --verbose $dir: "\
6250                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6251         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6252                 error "$LFS getstripe $dir: showed lmm_magic"
6253
6254         #test lfs getstripe with -v prints lmm_fid
6255         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6256         local countfids=$((numdirs + numfiles * numcomp))
6257         [[ $filenum -eq $countfids ]] ||
6258                 error "$LFS getstripe -v $dir: "\
6259                       "got $filenum want $countfids lmm_fid"
6260         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6261                 error "$LFS getstripe $dir: showed lmm_fid by default"
6262         echo "$LFS getstripe --verbose passed"
6263
6264         #check for FID information
6265         local fid1=$($LFS getstripe --fid $dir/file1)
6266         local fid2=$($LFS getstripe --verbose $dir/file1 |
6267                      awk '/lmm_fid: / { print $2; exit; }')
6268         local fid3=$($LFS path2fid $dir/file1)
6269
6270         [ "$fid1" != "$fid2" ] &&
6271                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6272         [ "$fid1" != "$fid3" ] &&
6273                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6274         echo "$LFS getstripe --fid passed"
6275
6276         #test lfs getstripe with --obd
6277         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6278                 error "$LFS getstripe --obd wrong_uuid: should return error"
6279
6280         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6281
6282         local ostidx=1
6283         local obduuid=$(ostuuid_from_index $ostidx)
6284         local found=$($LFS getstripe -r --obd $obduuid $dir |
6285                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6286
6287         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6288         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6289                 ((filenum--))
6290         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6291                 ((filenum--))
6292
6293         [[ $found -eq $filenum ]] ||
6294                 error "$LFS getstripe --obd: found $found expect $filenum"
6295         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6296                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6297                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6298                 error "$LFS getstripe --obd: should not show file on other obd"
6299         echo "$LFS getstripe --obd passed"
6300 }
6301 run_test 56a "check $LFS getstripe"
6302
6303 test_56b() {
6304         local dir=$DIR/$tdir
6305         local numdirs=3
6306
6307         test_mkdir $dir
6308         for i in $(seq $numdirs); do
6309                 test_mkdir $dir/dir$i
6310         done
6311
6312         # test lfs getdirstripe default mode is non-recursion, which is
6313         # different from lfs getstripe
6314         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6315
6316         [[ $dircnt -eq 1 ]] ||
6317                 error "$LFS getdirstripe: found $dircnt, not 1"
6318         dircnt=$($LFS getdirstripe --recursive $dir |
6319                 grep -c lmv_stripe_count)
6320         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6321                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6322 }
6323 run_test 56b "check $LFS getdirstripe"
6324
6325 test_56c() {
6326         remote_ost_nodsh && skip "remote OST with nodsh"
6327
6328         local ost_idx=0
6329         local ost_name=$(ostname_from_index $ost_idx)
6330         local old_status=$(ost_dev_status $ost_idx)
6331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6332
6333         [[ -z "$old_status" ]] ||
6334                 skip_env "OST $ost_name is in $old_status status"
6335
6336         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6337         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6338                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6339         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6340                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6341                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6342         fi
6343
6344         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6345                 error "$LFS df -v showing inactive devices"
6346         sleep_maxage
6347
6348         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6349
6350         [[ "$new_status" =~ "D" ]] ||
6351                 error "$ost_name status is '$new_status', missing 'D'"
6352         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6353                 [[ "$new_status" =~ "N" ]] ||
6354                         error "$ost_name status is '$new_status', missing 'N'"
6355         fi
6356         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6357                 [[ "$new_status" =~ "f" ]] ||
6358                         error "$ost_name status is '$new_status', missing 'f'"
6359         fi
6360
6361         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6362         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6363                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6364         [[ -z "$p" ]] && restore_lustre_params < $p || true
6365         sleep_maxage
6366
6367         new_status=$(ost_dev_status $ost_idx)
6368         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6369                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6370         # can't check 'f' as devices may actually be on flash
6371 }
6372 run_test 56c "check 'lfs df' showing device status"
6373
6374 test_56d() {
6375         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6376         local osts=$($LFS df -v $MOUNT | grep -c OST)
6377
6378         $LFS df $MOUNT
6379
6380         (( mdts == MDSCOUNT )) ||
6381                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6382         (( osts == OSTCOUNT )) ||
6383                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6384 }
6385 run_test 56d "'lfs df -v' prints only configured devices"
6386
6387 test_56e() {
6388         err_enoent=2 # No such file or directory
6389         err_eopnotsupp=95 # Operation not supported
6390
6391         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6392         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6393
6394         # Check for handling of path not exists
6395         output=$($LFS df $enoent_mnt 2>&1)
6396         ret=$?
6397
6398         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6399         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6400                 error "expect failure $err_enoent, not $ret"
6401
6402         # Check for handling of non-Lustre FS
6403         output=$($LFS df $notsup_mnt)
6404         ret=$?
6405
6406         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6407         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6408                 error "expect success $err_eopnotsupp, not $ret"
6409
6410         # Check for multiple LustreFS argument
6411         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6412         ret=$?
6413
6414         [[ $output -eq 3 && $ret -eq 0 ]] ||
6415                 error "expect success 3, not $output, rc = $ret"
6416
6417         # Check for correct non-Lustre FS handling among multiple
6418         # LustreFS argument
6419         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6420                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6421         ret=$?
6422
6423         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6424                 error "expect success 2, not $output, rc = $ret"
6425 }
6426 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6427
6428 NUMFILES=3
6429 NUMDIRS=3
6430 setup_56() {
6431         local local_tdir="$1"
6432         local local_numfiles="$2"
6433         local local_numdirs="$3"
6434         local dir_params="$4"
6435         local dir_stripe_params="$5"
6436
6437         if [ ! -d "$local_tdir" ] ; then
6438                 test_mkdir -p $dir_stripe_params $local_tdir
6439                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6440                 for i in $(seq $local_numfiles) ; do
6441                         touch $local_tdir/file$i
6442                 done
6443                 for i in $(seq $local_numdirs) ; do
6444                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6445                         for j in $(seq $local_numfiles) ; do
6446                                 touch $local_tdir/dir$i/file$j
6447                         done
6448                 done
6449         fi
6450 }
6451
6452 setup_56_special() {
6453         local local_tdir=$1
6454         local local_numfiles=$2
6455         local local_numdirs=$3
6456
6457         setup_56 $local_tdir $local_numfiles $local_numdirs
6458
6459         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6460                 for i in $(seq $local_numfiles) ; do
6461                         mknod $local_tdir/loop${i}b b 7 $i
6462                         mknod $local_tdir/null${i}c c 1 3
6463                         ln -s $local_tdir/file1 $local_tdir/link${i}
6464                 done
6465                 for i in $(seq $local_numdirs) ; do
6466                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6467                         mknod $local_tdir/dir$i/null${i}c c 1 3
6468                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6469                 done
6470         fi
6471 }
6472
6473 test_56g() {
6474         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6475         local expected=$(($NUMDIRS + 2))
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS
6478
6479         # test lfs find with -name
6480         for i in $(seq $NUMFILES) ; do
6481                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6482
6483                 [ $nums -eq $expected ] ||
6484                         error "lfs find -name '*$i' $dir wrong: "\
6485                               "found $nums, expected $expected"
6486         done
6487 }
6488 run_test 56g "check lfs find -name"
6489
6490 test_56h() {
6491         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6492         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6493
6494         setup_56 $dir $NUMFILES $NUMDIRS
6495
6496         # test lfs find with ! -name
6497         for i in $(seq $NUMFILES) ; do
6498                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6499
6500                 [ $nums -eq $expected ] ||
6501                         error "lfs find ! -name '*$i' $dir wrong: "\
6502                               "found $nums, expected $expected"
6503         done
6504 }
6505 run_test 56h "check lfs find ! -name"
6506
6507 test_56i() {
6508         local dir=$DIR/$tdir
6509
6510         test_mkdir $dir
6511
6512         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6513         local out=$($cmd)
6514
6515         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6516 }
6517 run_test 56i "check 'lfs find -ost UUID' skips directories"
6518
6519 test_56j() {
6520         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6521
6522         setup_56_special $dir $NUMFILES $NUMDIRS
6523
6524         local expected=$((NUMDIRS + 1))
6525         local cmd="$LFS find -type d $dir"
6526         local nums=$($cmd | wc -l)
6527
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530 }
6531 run_test 56j "check lfs find -type d"
6532
6533 test_56k() {
6534         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6535
6536         setup_56_special $dir $NUMFILES $NUMDIRS
6537
6538         local expected=$(((NUMDIRS + 1) * NUMFILES))
6539         local cmd="$LFS find -type f $dir"
6540         local nums=$($cmd | wc -l)
6541
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544 }
6545 run_test 56k "check lfs find -type f"
6546
6547 test_56l() {
6548         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6549
6550         setup_56_special $dir $NUMFILES $NUMDIRS
6551
6552         local expected=$((NUMDIRS + NUMFILES))
6553         local cmd="$LFS find -type b $dir"
6554         local nums=$($cmd | wc -l)
6555
6556         [ $nums -eq $expected ] ||
6557                 error "'$cmd' wrong: found $nums, expected $expected"
6558 }
6559 run_test 56l "check lfs find -type b"
6560
6561 test_56m() {
6562         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6563
6564         setup_56_special $dir $NUMFILES $NUMDIRS
6565
6566         local expected=$((NUMDIRS + NUMFILES))
6567         local cmd="$LFS find -type c $dir"
6568         local nums=$($cmd | wc -l)
6569         [ $nums -eq $expected ] ||
6570                 error "'$cmd' wrong: found $nums, expected $expected"
6571 }
6572 run_test 56m "check lfs find -type c"
6573
6574 test_56n() {
6575         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6576         setup_56_special $dir $NUMFILES $NUMDIRS
6577
6578         local expected=$((NUMDIRS + NUMFILES))
6579         local cmd="$LFS find -type l $dir"
6580         local nums=$($cmd | wc -l)
6581
6582         [ $nums -eq $expected ] ||
6583                 error "'$cmd' wrong: found $nums, expected $expected"
6584 }
6585 run_test 56n "check lfs find -type l"
6586
6587 test_56o() {
6588         local dir=$DIR/$tdir
6589
6590         setup_56 $dir $NUMFILES $NUMDIRS
6591         utime $dir/file1 > /dev/null || error "utime (1)"
6592         utime $dir/file2 > /dev/null || error "utime (2)"
6593         utime $dir/dir1 > /dev/null || error "utime (3)"
6594         utime $dir/dir2 > /dev/null || error "utime (4)"
6595         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6596         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6597
6598         local expected=4
6599         local nums=$($LFS find -mtime +0 $dir | wc -l)
6600
6601         [ $nums -eq $expected ] ||
6602                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6603
6604         expected=12
6605         cmd="$LFS find -mtime 0 $dir"
6606         nums=$($cmd | wc -l)
6607         [ $nums -eq $expected ] ||
6608                 error "'$cmd' wrong: found $nums, expected $expected"
6609 }
6610 run_test 56o "check lfs find -mtime for old files"
6611
6612 test_56ob() {
6613         local dir=$DIR/$tdir
6614         local expected=1
6615         local count=0
6616
6617         # just to make sure there is something that won't be found
6618         test_mkdir $dir
6619         touch $dir/$tfile.now
6620
6621         for age in year week day hour min; do
6622                 count=$((count + 1))
6623
6624                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6625                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6626                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6627
6628                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6629                 local nums=$($cmd | wc -l)
6630                 [ $nums -eq $expected ] ||
6631                         error "'$cmd' wrong: found $nums, expected $expected"
6632
6633                 cmd="$LFS find $dir -atime $count${age:0:1}"
6634                 nums=$($cmd | wc -l)
6635                 [ $nums -eq $expected ] ||
6636                         error "'$cmd' wrong: found $nums, expected $expected"
6637         done
6638
6639         sleep 2
6640         cmd="$LFS find $dir -ctime +1s -type f"
6641         nums=$($cmd | wc -l)
6642         (( $nums == $count * 2 + 1)) ||
6643                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6644 }
6645 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6646
6647 test_newerXY_base() {
6648         local x=$1
6649         local y=$2
6650         local dir=$DIR/$tdir
6651         local ref
6652         local negref
6653
6654         if [ $y == "t" ]; then
6655                 if [ $x == "b" ]; then
6656                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6657                 else
6658                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6659                 fi
6660         else
6661                 ref=$DIR/$tfile.newer.$x$y
6662                 touch $ref || error "touch $ref failed"
6663         fi
6664
6665         echo "before = $ref"
6666         sleep 2
6667         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6668         sleep 2
6669         if [ $y == "t" ]; then
6670                 if [ $x == "b" ]; then
6671                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6672                 else
6673                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6674                 fi
6675         else
6676                 negref=$DIR/$tfile.negnewer.$x$y
6677                 touch $negref || error "touch $negref failed"
6678         fi
6679
6680         echo "after = $negref"
6681         local cmd="$LFS find $dir -newer$x$y $ref"
6682         local nums=$(eval $cmd | wc -l)
6683         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6684
6685         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6686                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6687
6688         cmd="$LFS find $dir ! -newer$x$y $negref"
6689         nums=$(eval $cmd | wc -l)
6690         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6691                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6692
6693         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6694         nums=$(eval $cmd | wc -l)
6695         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6696                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6697
6698         rm -rf $DIR/*
6699 }
6700
6701 test_56oc() {
6702         test_newerXY_base "a" "a"
6703         test_newerXY_base "a" "m"
6704         test_newerXY_base "a" "c"
6705         test_newerXY_base "m" "a"
6706         test_newerXY_base "m" "m"
6707         test_newerXY_base "m" "c"
6708         test_newerXY_base "c" "a"
6709         test_newerXY_base "c" "m"
6710         test_newerXY_base "c" "c"
6711
6712         test_newerXY_base "a" "t"
6713         test_newerXY_base "m" "t"
6714         test_newerXY_base "c" "t"
6715
6716         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6717            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6718                 ! btime_supported && echo "btime unsupported" && return 0
6719
6720         test_newerXY_base "b" "b"
6721         test_newerXY_base "b" "t"
6722 }
6723 run_test 56oc "check lfs find -newerXY work"
6724
6725 btime_supported() {
6726         local dir=$DIR/$tdir
6727         local rc
6728
6729         mkdir -p $dir
6730         touch $dir/$tfile
6731         $LFS find $dir -btime -1d -type f
6732         rc=$?
6733         rm -rf $dir
6734         return $rc
6735 }
6736
6737 test_56od() {
6738         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6739                 ! btime_supported && skip "btime unsupported on MDS"
6740
6741         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6742                 ! btime_supported && skip "btime unsupported on clients"
6743
6744         local dir=$DIR/$tdir
6745         local ref=$DIR/$tfile.ref
6746         local negref=$DIR/$tfile.negref
6747
6748         mkdir $dir || error "mkdir $dir failed"
6749         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6750         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6751         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6752         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6753         touch $ref || error "touch $ref failed"
6754         # sleep 3 seconds at least
6755         sleep 3
6756
6757         local before=$(do_facet mds1 date +%s)
6758         local skew=$(($(date +%s) - before + 1))
6759
6760         if (( skew < 0 && skew > -5 )); then
6761                 sleep $((0 - skew + 1))
6762                 skew=0
6763         fi
6764
6765         # Set the dir stripe params to limit files all on MDT0,
6766         # otherwise we need to calc the max clock skew between
6767         # the client and MDTs.
6768         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6769         sleep 2
6770         touch $negref || error "touch $negref failed"
6771
6772         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6773         local nums=$($cmd | wc -l)
6774         local expected=$(((NUMFILES + 1) * NUMDIRS))
6775
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778
6779         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6780         nums=$($cmd | wc -l)
6781         expected=$((NUMFILES + 1))
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784
6785         [ $skew -lt 0 ] && return
6786
6787         local after=$(do_facet mds1 date +%s)
6788         local age=$((after - before + 1 + skew))
6789
6790         cmd="$LFS find $dir -btime -${age}s -type f"
6791         nums=$($cmd | wc -l)
6792         expected=$(((NUMFILES + 1) * NUMDIRS))
6793
6794         echo "Clock skew between client and server: $skew, age:$age"
6795         [ $nums -eq $expected ] ||
6796                 error "'$cmd' wrong: found $nums, expected $expected"
6797
6798         expected=$(($NUMDIRS + 1))
6799         cmd="$LFS find $dir -btime -${age}s -type d"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803         rm -f $ref $negref || error "Failed to remove $ref $negref"
6804 }
6805 run_test 56od "check lfs find -btime with units"
6806
6807 test_56p() {
6808         [ $RUNAS_ID -eq $UID ] &&
6809                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6810
6811         local dir=$DIR/$tdir
6812
6813         setup_56 $dir $NUMFILES $NUMDIRS
6814         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6815
6816         local expected=$NUMFILES
6817         local cmd="$LFS find -uid $RUNAS_ID $dir"
6818         local nums=$($cmd | wc -l)
6819
6820         [ $nums -eq $expected ] ||
6821                 error "'$cmd' wrong: found $nums, expected $expected"
6822
6823         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6824         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6825         nums=$($cmd | wc -l)
6826         [ $nums -eq $expected ] ||
6827                 error "'$cmd' wrong: found $nums, expected $expected"
6828 }
6829 run_test 56p "check lfs find -uid and ! -uid"
6830
6831 test_56q() {
6832         [ $RUNAS_ID -eq $UID ] &&
6833                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6834
6835         local dir=$DIR/$tdir
6836
6837         setup_56 $dir $NUMFILES $NUMDIRS
6838         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6839
6840         local expected=$NUMFILES
6841         local cmd="$LFS find -gid $RUNAS_GID $dir"
6842         local nums=$($cmd | wc -l)
6843
6844         [ $nums -eq $expected ] ||
6845                 error "'$cmd' wrong: found $nums, expected $expected"
6846
6847         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6848         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6849         nums=$($cmd | wc -l)
6850         [ $nums -eq $expected ] ||
6851                 error "'$cmd' wrong: found $nums, expected $expected"
6852 }
6853 run_test 56q "check lfs find -gid and ! -gid"
6854
6855 test_56r() {
6856         local dir=$DIR/$tdir
6857
6858         setup_56 $dir $NUMFILES $NUMDIRS
6859
6860         local expected=12
6861         local cmd="$LFS find -size 0 -type f -lazy $dir"
6862         local nums=$($cmd | wc -l)
6863
6864         [ $nums -eq $expected ] ||
6865                 error "'$cmd' wrong: found $nums, expected $expected"
6866         cmd="$LFS find -size 0 -type f $dir"
6867         nums=$($cmd | wc -l)
6868         [ $nums -eq $expected ] ||
6869                 error "'$cmd' wrong: found $nums, expected $expected"
6870
6871         expected=0
6872         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6873         nums=$($cmd | wc -l)
6874         [ $nums -eq $expected ] ||
6875                 error "'$cmd' wrong: found $nums, expected $expected"
6876         cmd="$LFS find ! -size 0 -type f $dir"
6877         nums=$($cmd | wc -l)
6878         [ $nums -eq $expected ] ||
6879                 error "'$cmd' wrong: found $nums, expected $expected"
6880
6881         echo "test" > $dir/$tfile
6882         echo "test2" > $dir/$tfile.2 && sync
6883         expected=1
6884         cmd="$LFS find -size 5 -type f -lazy $dir"
6885         nums=$($cmd | wc -l)
6886         [ $nums -eq $expected ] ||
6887                 error "'$cmd' wrong: found $nums, expected $expected"
6888         cmd="$LFS find -size 5 -type f $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892
6893         expected=1
6894         cmd="$LFS find -size +5 -type f -lazy $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898         cmd="$LFS find -size +5 -type f $dir"
6899         nums=$($cmd | wc -l)
6900         [ $nums -eq $expected ] ||
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902
6903         expected=2
6904         cmd="$LFS find -size +0 -type f -lazy $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] ||
6907                 error "'$cmd' wrong: found $nums, expected $expected"
6908         cmd="$LFS find -size +0 -type f $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912
6913         expected=2
6914         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6915         nums=$($cmd | wc -l)
6916         [ $nums -eq $expected ] ||
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918         cmd="$LFS find ! -size -5 -type f $dir"
6919         nums=$($cmd | wc -l)
6920         [ $nums -eq $expected ] ||
6921                 error "'$cmd' wrong: found $nums, expected $expected"
6922
6923         expected=12
6924         cmd="$LFS find -size -5 -type f -lazy $dir"
6925         nums=$($cmd | wc -l)
6926         [ $nums -eq $expected ] ||
6927                 error "'$cmd' wrong: found $nums, expected $expected"
6928         cmd="$LFS find -size -5 -type f $dir"
6929         nums=$($cmd | wc -l)
6930         [ $nums -eq $expected ] ||
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932 }
6933 run_test 56r "check lfs find -size works"
6934
6935 test_56ra_sub() {
6936         local expected=$1
6937         local glimpses=$2
6938         local cmd="$3"
6939
6940         cancel_lru_locks $OSC
6941
6942         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6943         local nums=$($cmd | wc -l)
6944
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6949
6950         if (( rpcs_before + glimpses != rpcs_after )); then
6951                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6952                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6953
6954                 if [[ $glimpses == 0 ]]; then
6955                         error "'$cmd' should not send glimpse RPCs to OST"
6956                 else
6957                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6958                 fi
6959         fi
6960 }
6961
6962 test_56ra() {
6963         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6964                 skip "MDS < 2.12.58 doesn't return LSOM data"
6965         local dir=$DIR/$tdir
6966         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6967
6968         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6969
6970         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6971         $LCTL set_param -n llite.*.statahead_agl=0
6972         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6973
6974         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6975         # open and close all files to ensure LSOM is updated
6976         cancel_lru_locks $OSC
6977         find $dir -type f | xargs cat > /dev/null
6978
6979         #   expect_found  glimpse_rpcs  command_to_run
6980         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6981         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6982         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6983         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6984
6985         echo "test" > $dir/$tfile
6986         echo "test2" > $dir/$tfile.2 && sync
6987         cancel_lru_locks $OSC
6988         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6989
6990         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6991         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6992         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6993         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6994
6995         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6996         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6997         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6998         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6999         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7000         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7001 }
7002 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7003
7004 test_56rb() {
7005         local dir=$DIR/$tdir
7006         local tmp=$TMP/$tfile.log
7007         local mdt_idx;
7008
7009         test_mkdir -p $dir || error "failed to mkdir $dir"
7010         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7011                 error "failed to setstripe $dir/$tfile"
7012         mdt_idx=$($LFS getdirstripe -i $dir)
7013         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7014
7015         stack_trap "rm -f $tmp" EXIT
7016         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7017         ! grep -q obd_uuid $tmp ||
7018                 error "failed to find --size +100K --ost 0 $dir"
7019         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7020         ! grep -q obd_uuid $tmp ||
7021                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7022 }
7023 run_test 56rb "check lfs find --size --ost/--mdt works"
7024
7025 test_56rc() {
7026         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7027         local dir=$DIR/$tdir
7028         local found
7029
7030         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7031         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7032         (( $MDSCOUNT > 2 )) &&
7033                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7034         mkdir $dir/$tdir-{1..10}
7035         touch $dir/$tfile-{1..10}
7036
7037         found=$($LFS find $dir --mdt-count 2 | wc -l)
7038         expect=11
7039         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7040
7041         found=$($LFS find $dir -T +1 | wc -l)
7042         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7043         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7044
7045         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7046         expect=11
7047         (( $found == $expect )) || error "found $found all_char, expect $expect"
7048
7049         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7050         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7051         (( $found == $expect )) || error "found $found all_char, expect $expect"
7052 }
7053 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7054
7055 test_56s() { # LU-611 #LU-9369
7056         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7057
7058         local dir=$DIR/$tdir
7059         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7060
7061         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7062         for i in $(seq $NUMDIRS); do
7063                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7064         done
7065
7066         local expected=$NUMDIRS
7067         local cmd="$LFS find -c $OSTCOUNT $dir"
7068         local nums=$($cmd | wc -l)
7069
7070         [ $nums -eq $expected ] || {
7071                 $LFS getstripe -R $dir
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073         }
7074
7075         expected=$((NUMDIRS + onestripe))
7076         cmd="$LFS find -stripe-count +0 -type f $dir"
7077         nums=$($cmd | wc -l)
7078         [ $nums -eq $expected ] || {
7079                 $LFS getstripe -R $dir
7080                 error "'$cmd' wrong: found $nums, expected $expected"
7081         }
7082
7083         expected=$onestripe
7084         cmd="$LFS find -stripe-count 1 -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] || {
7087                 $LFS getstripe -R $dir
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089         }
7090
7091         cmd="$LFS find -stripe-count -2 -type f $dir"
7092         nums=$($cmd | wc -l)
7093         [ $nums -eq $expected ] || {
7094                 $LFS getstripe -R $dir
7095                 error "'$cmd' wrong: found $nums, expected $expected"
7096         }
7097
7098         expected=0
7099         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7100         nums=$($cmd | wc -l)
7101         [ $nums -eq $expected ] || {
7102                 $LFS getstripe -R $dir
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104         }
7105 }
7106 run_test 56s "check lfs find -stripe-count works"
7107
7108 test_56t() { # LU-611 #LU-9369
7109         local dir=$DIR/$tdir
7110
7111         setup_56 $dir 0 $NUMDIRS
7112         for i in $(seq $NUMDIRS); do
7113                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7114         done
7115
7116         local expected=$NUMDIRS
7117         local cmd="$LFS find -S 8M $dir"
7118         local nums=$($cmd | wc -l)
7119
7120         [ $nums -eq $expected ] || {
7121                 $LFS getstripe -R $dir
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123         }
7124         rm -rf $dir
7125
7126         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7127
7128         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7129
7130         expected=$(((NUMDIRS + 1) * NUMFILES))
7131         cmd="$LFS find -stripe-size 512k -type f $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135
7136         cmd="$LFS find -stripe-size +320k -type f $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140
7141         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7142         cmd="$LFS find -stripe-size +200k -type f $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146
7147         cmd="$LFS find -stripe-size -640k -type f $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151
7152         expected=4
7153         cmd="$LFS find -stripe-size 256k -type f $dir"
7154         nums=$($cmd | wc -l)
7155         [ $nums -eq $expected ] ||
7156                 error "'$cmd' wrong: found $nums, expected $expected"
7157
7158         cmd="$LFS find -stripe-size -320k -type f $dir"
7159         nums=$($cmd | wc -l)
7160         [ $nums -eq $expected ] ||
7161                 error "'$cmd' wrong: found $nums, expected $expected"
7162
7163         expected=0
7164         cmd="$LFS find -stripe-size 1024k -type f $dir"
7165         nums=$($cmd | wc -l)
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168 }
7169 run_test 56t "check lfs find -stripe-size works"
7170
7171 test_56u() { # LU-611
7172         local dir=$DIR/$tdir
7173
7174         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7175
7176         if [[ $OSTCOUNT -gt 1 ]]; then
7177                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7178                 onestripe=4
7179         else
7180                 onestripe=0
7181         fi
7182
7183         local expected=$(((NUMDIRS + 1) * NUMFILES))
7184         local cmd="$LFS find -stripe-index 0 -type f $dir"
7185         local nums=$($cmd | wc -l)
7186
7187         [ $nums -eq $expected ] ||
7188                 error "'$cmd' wrong: found $nums, expected $expected"
7189
7190         expected=$onestripe
7191         cmd="$LFS find -stripe-index 1 -type f $dir"
7192         nums=$($cmd | wc -l)
7193         [ $nums -eq $expected ] ||
7194                 error "'$cmd' wrong: found $nums, expected $expected"
7195
7196         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7197         nums=$($cmd | wc -l)
7198         [ $nums -eq $expected ] ||
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200
7201         expected=0
7202         # This should produce an error and not return any files
7203         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7204         nums=$($cmd 2>/dev/null | wc -l)
7205         [ $nums -eq $expected ] ||
7206                 error "'$cmd' wrong: found $nums, expected $expected"
7207
7208         if [[ $OSTCOUNT -gt 1 ]]; then
7209                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7210                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7211                 nums=$($cmd | wc -l)
7212                 [ $nums -eq $expected ] ||
7213                         error "'$cmd' wrong: found $nums, expected $expected"
7214         fi
7215 }
7216 run_test 56u "check lfs find -stripe-index works"
7217
7218 test_56v() {
7219         local mdt_idx=0
7220         local dir=$DIR/$tdir
7221
7222         setup_56 $dir $NUMFILES $NUMDIRS
7223
7224         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7225         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7226
7227         for file in $($LFS find -m $UUID $dir); do
7228                 file_midx=$($LFS getstripe -m $file)
7229                 [ $file_midx -eq $mdt_idx ] ||
7230                         error "lfs find -m $UUID != getstripe -m $file_midx"
7231         done
7232 }
7233 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7234
7235 test_56w() {
7236         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238
7239         local dir=$DIR/$tdir
7240
7241         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7242
7243         local stripe_size=$($LFS getstripe -S -d $dir) ||
7244                 error "$LFS getstripe -S -d $dir failed"
7245         stripe_size=${stripe_size%% *}
7246
7247         local file_size=$((stripe_size * OSTCOUNT))
7248         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7249         local required_space=$((file_num * file_size))
7250         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7251                            head -n1)
7252         [[ $free_space -le $((required_space / 1024)) ]] &&
7253                 skip_env "need $required_space, have $free_space kbytes"
7254
7255         local dd_bs=65536
7256         local dd_count=$((file_size / dd_bs))
7257
7258         # write data into the files
7259         local i
7260         local j
7261         local file
7262
7263         for i in $(seq $NUMFILES); do
7264                 file=$dir/file$i
7265                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7266                         error "write data into $file failed"
7267         done
7268         for i in $(seq $NUMDIRS); do
7269                 for j in $(seq $NUMFILES); do
7270                         file=$dir/dir$i/file$j
7271                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7272                                 error "write data into $file failed"
7273                 done
7274         done
7275
7276         # $LFS_MIGRATE will fail if hard link migration is unsupported
7277         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7278                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7279                         error "creating links to $dir/dir1/file1 failed"
7280         fi
7281
7282         local expected=-1
7283
7284         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7285
7286         # lfs_migrate file
7287         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7288
7289         echo "$cmd"
7290         eval $cmd || error "$cmd failed"
7291
7292         check_stripe_count $dir/file1 $expected
7293
7294         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7295         then
7296                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7297                 # OST 1 if it is on OST 0. This file is small enough to
7298                 # be on only one stripe.
7299                 file=$dir/migr_1_ost
7300                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7301                         error "write data into $file failed"
7302                 local obdidx=$($LFS getstripe -i $file)
7303                 local oldmd5=$(md5sum $file)
7304                 local newobdidx=0
7305
7306                 [[ $obdidx -eq 0 ]] && newobdidx=1
7307                 cmd="$LFS migrate -i $newobdidx $file"
7308                 echo $cmd
7309                 eval $cmd || error "$cmd failed"
7310
7311                 local realobdix=$($LFS getstripe -i $file)
7312                 local newmd5=$(md5sum $file)
7313
7314                 [[ $newobdidx -ne $realobdix ]] &&
7315                         error "new OST is different (was=$obdidx, "\
7316                               "wanted=$newobdidx, got=$realobdix)"
7317                 [[ "$oldmd5" != "$newmd5" ]] &&
7318                         error "md5sum differ: $oldmd5, $newmd5"
7319         fi
7320
7321         # lfs_migrate dir
7322         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7323         echo "$cmd"
7324         eval $cmd || error "$cmd failed"
7325
7326         for j in $(seq $NUMFILES); do
7327                 check_stripe_count $dir/dir1/file$j $expected
7328         done
7329
7330         # lfs_migrate works with lfs find
7331         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7332              $LFS_MIGRATE -y -c $expected"
7333         echo "$cmd"
7334         eval $cmd || error "$cmd failed"
7335
7336         for i in $(seq 2 $NUMFILES); do
7337                 check_stripe_count $dir/file$i $expected
7338         done
7339         for i in $(seq 2 $NUMDIRS); do
7340                 for j in $(seq $NUMFILES); do
7341                 check_stripe_count $dir/dir$i/file$j $expected
7342                 done
7343         done
7344 }
7345 run_test 56w "check lfs_migrate -c stripe_count works"
7346
7347 test_56wb() {
7348         local file1=$DIR/$tdir/file1
7349         local create_pool=false
7350         local initial_pool=$($LFS getstripe -p $DIR)
7351         local pool_list=()
7352         local pool=""
7353
7354         echo -n "Creating test dir..."
7355         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7356         echo "done."
7357
7358         echo -n "Creating test file..."
7359         touch $file1 || error "cannot create file"
7360         echo "done."
7361
7362         echo -n "Detecting existing pools..."
7363         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7364
7365         if [ ${#pool_list[@]} -gt 0 ]; then
7366                 echo "${pool_list[@]}"
7367                 for thispool in "${pool_list[@]}"; do
7368                         if [[ -z "$initial_pool" ||
7369                               "$initial_pool" != "$thispool" ]]; then
7370                                 pool="$thispool"
7371                                 echo "Using existing pool '$pool'"
7372                                 break
7373                         fi
7374                 done
7375         else
7376                 echo "none detected."
7377         fi
7378         if [ -z "$pool" ]; then
7379                 pool=${POOL:-testpool}
7380                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7381                 echo -n "Creating pool '$pool'..."
7382                 create_pool=true
7383                 pool_add $pool &> /dev/null ||
7384                         error "pool_add failed"
7385                 echo "done."
7386
7387                 echo -n "Adding target to pool..."
7388                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7389                         error "pool_add_targets failed"
7390                 echo "done."
7391         fi
7392
7393         echo -n "Setting pool using -p option..."
7394         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7395                 error "migrate failed rc = $?"
7396         echo "done."
7397
7398         echo -n "Verifying test file is in pool after migrating..."
7399         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7400                 error "file was not migrated to pool $pool"
7401         echo "done."
7402
7403         echo -n "Removing test file from pool '$pool'..."
7404         # "lfs migrate $file" won't remove the file from the pool
7405         # until some striping information is changed.
7406         $LFS migrate -c 1 $file1 &> /dev/null ||
7407                 error "cannot remove from pool"
7408         [ "$($LFS getstripe -p $file1)" ] &&
7409                 error "pool still set"
7410         echo "done."
7411
7412         echo -n "Setting pool using --pool option..."
7413         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7414                 error "migrate failed rc = $?"
7415         echo "done."
7416
7417         # Clean up
7418         rm -f $file1
7419         if $create_pool; then
7420                 destroy_test_pools 2> /dev/null ||
7421                         error "destroy test pools failed"
7422         fi
7423 }
7424 run_test 56wb "check lfs_migrate pool support"
7425
7426 test_56wc() {
7427         local file1="$DIR/$tdir/file1"
7428         local parent_ssize
7429         local parent_scount
7430         local cur_ssize
7431         local cur_scount
7432         local orig_ssize
7433
7434         echo -n "Creating test dir..."
7435         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7436         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7437                 error "cannot set stripe by '-S 1M -c 1'"
7438         echo "done"
7439
7440         echo -n "Setting initial stripe for test file..."
7441         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7442                 error "cannot set stripe"
7443         cur_ssize=$($LFS getstripe -S "$file1")
7444         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7445         echo "done."
7446
7447         # File currently set to -S 512K -c 1
7448
7449         # Ensure -c and -S options are rejected when -R is set
7450         echo -n "Verifying incompatible options are detected..."
7451         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7452                 error "incompatible -c and -R options not detected"
7453         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7454                 error "incompatible -S and -R options not detected"
7455         echo "done."
7456
7457         # Ensure unrecognized options are passed through to 'lfs migrate'
7458         echo -n "Verifying -S option is passed through to lfs migrate..."
7459         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7460                 error "migration failed"
7461         cur_ssize=$($LFS getstripe -S "$file1")
7462         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7463         echo "done."
7464
7465         # File currently set to -S 1M -c 1
7466
7467         # Ensure long options are supported
7468         echo -n "Verifying long options supported..."
7469         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7470                 error "long option without argument not supported"
7471         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7472                 error "long option with argument not supported"
7473         cur_ssize=$($LFS getstripe -S "$file1")
7474         [ $cur_ssize -eq 524288 ] ||
7475                 error "migrate --stripe-size $cur_ssize != 524288"
7476         echo "done."
7477
7478         # File currently set to -S 512K -c 1
7479
7480         if [ "$OSTCOUNT" -gt 1 ]; then
7481                 echo -n "Verifying explicit stripe count can be set..."
7482                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7483                         error "migrate failed"
7484                 cur_scount=$($LFS getstripe -c "$file1")
7485                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7486                 echo "done."
7487         fi
7488
7489         # File currently set to -S 512K -c 1 or -S 512K -c 2
7490
7491         # Ensure parent striping is used if -R is set, and no stripe
7492         # count or size is specified
7493         echo -n "Setting stripe for parent directory..."
7494         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7495                 error "cannot set stripe '-S 2M -c 1'"
7496         echo "done."
7497
7498         echo -n "Verifying restripe option uses parent stripe settings..."
7499         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7500         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7501         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7502                 error "migrate failed"
7503         cur_ssize=$($LFS getstripe -S "$file1")
7504         [ $cur_ssize -eq $parent_ssize ] ||
7505                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7506         cur_scount=$($LFS getstripe -c "$file1")
7507         [ $cur_scount -eq $parent_scount ] ||
7508                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7509         echo "done."
7510
7511         # File currently set to -S 1M -c 1
7512
7513         # Ensure striping is preserved if -R is not set, and no stripe
7514         # count or size is specified
7515         echo -n "Verifying striping size preserved when not specified..."
7516         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7517         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7518                 error "cannot set stripe on parent directory"
7519         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7520                 error "migrate failed"
7521         cur_ssize=$($LFS getstripe -S "$file1")
7522         [ $cur_ssize -eq $orig_ssize ] ||
7523                 error "migrate by default $cur_ssize != $orig_ssize"
7524         echo "done."
7525
7526         # Ensure file name properly detected when final option has no argument
7527         echo -n "Verifying file name properly detected..."
7528         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7529                 error "file name interpreted as option argument"
7530         echo "done."
7531
7532         # Clean up
7533         rm -f "$file1"
7534 }
7535 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7536
7537 test_56wd() {
7538         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7539
7540         local file1=$DIR/$tdir/file1
7541
7542         echo -n "Creating test dir..."
7543         test_mkdir $DIR/$tdir || error "cannot create dir"
7544         echo "done."
7545
7546         echo -n "Creating test file..."
7547         touch $file1
7548         echo "done."
7549
7550         # Ensure 'lfs migrate' will fail by using a non-existent option,
7551         # and make sure rsync is not called to recover
7552         echo -n "Make sure --no-rsync option works..."
7553         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7554                 grep -q 'refusing to fall back to rsync' ||
7555                 error "rsync was called with --no-rsync set"
7556         echo "done."
7557
7558         # Ensure rsync is called without trying 'lfs migrate' first
7559         echo -n "Make sure --rsync option works..."
7560         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7561                 grep -q 'falling back to rsync' &&
7562                 error "lfs migrate was called with --rsync set"
7563         echo "done."
7564
7565         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7566         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7567                 grep -q 'at the same time' ||
7568                 error "--rsync and --no-rsync accepted concurrently"
7569         echo "done."
7570
7571         # Clean up
7572         rm -f $file1
7573 }
7574 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7575
7576 test_56we() {
7577         local td=$DIR/$tdir
7578         local tf=$td/$tfile
7579
7580         test_mkdir $td || error "cannot create $td"
7581         touch $tf || error "cannot touch $tf"
7582
7583         echo -n "Make sure --non-direct|-D works..."
7584         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7585                 grep -q "lfs migrate --non-direct" ||
7586                 error "--non-direct option cannot work correctly"
7587         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7588                 grep -q "lfs migrate -D" ||
7589                 error "-D option cannot work correctly"
7590         echo "done."
7591 }
7592 run_test 56we "check lfs_migrate --non-direct|-D support"
7593
7594 test_56x() {
7595         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7596         check_swap_layouts_support
7597
7598         local dir=$DIR/$tdir
7599         local ref1=/etc/passwd
7600         local file1=$dir/file1
7601
7602         test_mkdir $dir || error "creating dir $dir"
7603         $LFS setstripe -c 2 $file1
7604         cp $ref1 $file1
7605         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7606         stripe=$($LFS getstripe -c $file1)
7607         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7608         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7609
7610         # clean up
7611         rm -f $file1
7612 }
7613 run_test 56x "lfs migration support"
7614
7615 test_56xa() {
7616         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7617         check_swap_layouts_support
7618
7619         local dir=$DIR/$tdir/$testnum
7620
7621         test_mkdir -p $dir
7622
7623         local ref1=/etc/passwd
7624         local file1=$dir/file1
7625
7626         $LFS setstripe -c 2 $file1
7627         cp $ref1 $file1
7628         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7629
7630         local stripe=$($LFS getstripe -c $file1)
7631
7632         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7633         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7634
7635         # clean up
7636         rm -f $file1
7637 }
7638 run_test 56xa "lfs migration --block support"
7639
7640 check_migrate_links() {
7641         local dir="$1"
7642         local file1="$dir/file1"
7643         local begin="$2"
7644         local count="$3"
7645         local runas="$4"
7646         local total_count=$(($begin + $count - 1))
7647         local symlink_count=10
7648         local uniq_count=10
7649
7650         if [ ! -f "$file1" ]; then
7651                 echo -n "creating initial file..."
7652                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7653                         error "cannot setstripe initial file"
7654                 echo "done"
7655
7656                 echo -n "creating symlinks..."
7657                 for s in $(seq 1 $symlink_count); do
7658                         ln -s "$file1" "$dir/slink$s" ||
7659                                 error "cannot create symlinks"
7660                 done
7661                 echo "done"
7662
7663                 echo -n "creating nonlinked files..."
7664                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7665                         error "cannot create nonlinked files"
7666                 echo "done"
7667         fi
7668
7669         # create hard links
7670         if [ ! -f "$dir/file$total_count" ]; then
7671                 echo -n "creating hard links $begin:$total_count..."
7672                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7673                         /dev/null || error "cannot create hard links"
7674                 echo "done"
7675         fi
7676
7677         echo -n "checking number of hard links listed in xattrs..."
7678         local fid=$($LFS getstripe -F "$file1")
7679         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7680
7681         echo "${#paths[*]}"
7682         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7683                         skip "hard link list has unexpected size, skipping test"
7684         fi
7685         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7686                         error "link names should exceed xattrs size"
7687         fi
7688
7689         echo -n "migrating files..."
7690         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7691         local rc=$?
7692         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7693         echo "done"
7694
7695         # make sure all links have been properly migrated
7696         echo -n "verifying files..."
7697         fid=$($LFS getstripe -F "$file1") ||
7698                 error "cannot get fid for file $file1"
7699         for i in $(seq 2 $total_count); do
7700                 local fid2=$($LFS getstripe -F $dir/file$i)
7701
7702                 [ "$fid2" == "$fid" ] ||
7703                         error "migrated hard link has mismatched FID"
7704         done
7705
7706         # make sure hard links were properly detected, and migration was
7707         # performed only once for the entire link set; nonlinked files should
7708         # also be migrated
7709         local actual=$(grep -c 'done' <<< "$migrate_out")
7710         local expected=$(($uniq_count + 1))
7711
7712         [ "$actual" -eq  "$expected" ] ||
7713                 error "hard links individually migrated ($actual != $expected)"
7714
7715         # make sure the correct number of hard links are present
7716         local hardlinks=$(stat -c '%h' "$file1")
7717
7718         [ $hardlinks -eq $total_count ] ||
7719                 error "num hard links $hardlinks != $total_count"
7720         echo "done"
7721
7722         return 0
7723 }
7724
7725 test_56xb() {
7726         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7727                 skip "Need MDS version at least 2.10.55"
7728
7729         local dir="$DIR/$tdir"
7730
7731         test_mkdir "$dir" || error "cannot create dir $dir"
7732
7733         echo "testing lfs migrate mode when all links fit within xattrs"
7734         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7735
7736         echo "testing rsync mode when all links fit within xattrs"
7737         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7738
7739         echo "testing lfs migrate mode when all links do not fit within xattrs"
7740         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7741
7742         echo "testing rsync mode when all links do not fit within xattrs"
7743         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7744
7745         chown -R $RUNAS_ID $dir
7746         echo "testing non-root lfs migrate mode when not all links are in xattr"
7747         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7748
7749         # clean up
7750         rm -rf $dir
7751 }
7752 run_test 56xb "lfs migration hard link support"
7753
7754 test_56xc() {
7755         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7756
7757         local dir="$DIR/$tdir"
7758
7759         test_mkdir "$dir" || error "cannot create dir $dir"
7760
7761         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7762         echo -n "Setting initial stripe for 20MB test file..."
7763         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7764                 error "cannot setstripe 20MB file"
7765         echo "done"
7766         echo -n "Sizing 20MB test file..."
7767         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7768         echo "done"
7769         echo -n "Verifying small file autostripe count is 1..."
7770         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7771                 error "cannot migrate 20MB file"
7772         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7773                 error "cannot get stripe for $dir/20mb"
7774         [ $stripe_count -eq 1 ] ||
7775                 error "unexpected stripe count $stripe_count for 20MB file"
7776         rm -f "$dir/20mb"
7777         echo "done"
7778
7779         # Test 2: File is small enough to fit within the available space on
7780         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7781         # have at least an additional 1KB for each desired stripe for test 3
7782         echo -n "Setting stripe for 1GB test file..."
7783         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7784         echo "done"
7785         echo -n "Sizing 1GB test file..."
7786         # File size is 1GB + 3KB
7787         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7788         echo "done"
7789
7790         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7791         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7792         if (( avail > 524288 * OSTCOUNT )); then
7793                 echo -n "Migrating 1GB file..."
7794                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7795                         error "cannot migrate 1GB file"
7796                 echo "done"
7797                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7798                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7799                         error "cannot getstripe for 1GB file"
7800                 [ $stripe_count -eq 2 ] ||
7801                         error "unexpected stripe count $stripe_count != 2"
7802                 echo "done"
7803         fi
7804
7805         # Test 3: File is too large to fit within the available space on
7806         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7807         if [ $OSTCOUNT -ge 3 ]; then
7808                 # The required available space is calculated as
7809                 # file size (1GB + 3KB) / OST count (3).
7810                 local kb_per_ost=349526
7811
7812                 echo -n "Migrating 1GB file with limit..."
7813                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7814                         error "cannot migrate 1GB file with limit"
7815                 echo "done"
7816
7817                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7818                 echo -n "Verifying 1GB autostripe count with limited space..."
7819                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7820                         error "unexpected stripe count $stripe_count (min 3)"
7821                 echo "done"
7822         fi
7823
7824         # clean up
7825         rm -rf $dir
7826 }
7827 run_test 56xc "lfs migration autostripe"
7828
7829 test_56xd() {
7830         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7831
7832         local dir=$DIR/$tdir
7833         local f_mgrt=$dir/$tfile.mgrt
7834         local f_yaml=$dir/$tfile.yaml
7835         local f_copy=$dir/$tfile.copy
7836         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7837         local layout_copy="-c 2 -S 2M -i 1"
7838         local yamlfile=$dir/yamlfile
7839         local layout_before;
7840         local layout_after;
7841
7842         test_mkdir "$dir" || error "cannot create dir $dir"
7843         $LFS setstripe $layout_yaml $f_yaml ||
7844                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7845         $LFS getstripe --yaml $f_yaml > $yamlfile
7846         $LFS setstripe $layout_copy $f_copy ||
7847                 error "cannot setstripe $f_copy with layout $layout_copy"
7848         touch $f_mgrt
7849         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7850
7851         # 1. test option --yaml
7852         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7853                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7854         layout_before=$(get_layout_param $f_yaml)
7855         layout_after=$(get_layout_param $f_mgrt)
7856         [ "$layout_after" == "$layout_before" ] ||
7857                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7858
7859         # 2. test option --copy
7860         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7861                 error "cannot migrate $f_mgrt with --copy $f_copy"
7862         layout_before=$(get_layout_param $f_copy)
7863         layout_after=$(get_layout_param $f_mgrt)
7864         [ "$layout_after" == "$layout_before" ] ||
7865                 error "lfs_migrate --copy: $layout_after != $layout_before"
7866 }
7867 run_test 56xd "check lfs_migrate --yaml and --copy support"
7868
7869 test_56xe() {
7870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7871
7872         local dir=$DIR/$tdir
7873         local f_comp=$dir/$tfile
7874         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7875         local layout_before=""
7876         local layout_after=""
7877
7878         test_mkdir "$dir" || error "cannot create dir $dir"
7879         $LFS setstripe $layout $f_comp ||
7880                 error "cannot setstripe $f_comp with layout $layout"
7881         layout_before=$(get_layout_param $f_comp)
7882         dd if=/dev/zero of=$f_comp bs=1M count=4
7883
7884         # 1. migrate a comp layout file by lfs_migrate
7885         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7886         layout_after=$(get_layout_param $f_comp)
7887         [ "$layout_before" == "$layout_after" ] ||
7888                 error "lfs_migrate: $layout_before != $layout_after"
7889
7890         # 2. migrate a comp layout file by lfs migrate
7891         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7892         layout_after=$(get_layout_param $f_comp)
7893         [ "$layout_before" == "$layout_after" ] ||
7894                 error "lfs migrate: $layout_before != $layout_after"
7895 }
7896 run_test 56xe "migrate a composite layout file"
7897
7898 test_56xf() {
7899         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7900
7901         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7902                 skip "Need server version at least 2.13.53"
7903
7904         local dir=$DIR/$tdir
7905         local f_comp=$dir/$tfile
7906         local layout="-E 1M -c1 -E -1 -c2"
7907         local fid_before=""
7908         local fid_after=""
7909
7910         test_mkdir "$dir" || error "cannot create dir $dir"
7911         $LFS setstripe $layout $f_comp ||
7912                 error "cannot setstripe $f_comp with layout $layout"
7913         fid_before=$($LFS getstripe --fid $f_comp)
7914         dd if=/dev/zero of=$f_comp bs=1M count=4
7915
7916         # 1. migrate a comp layout file to a comp layout
7917         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7918         fid_after=$($LFS getstripe --fid $f_comp)
7919         [ "$fid_before" == "$fid_after" ] ||
7920                 error "comp-to-comp migrate: $fid_before != $fid_after"
7921
7922         # 2. migrate a comp layout file to a plain layout
7923         $LFS migrate -c2 $f_comp ||
7924                 error "cannot migrate $f_comp by lfs migrate"
7925         fid_after=$($LFS getstripe --fid $f_comp)
7926         [ "$fid_before" == "$fid_after" ] ||
7927                 error "comp-to-plain migrate: $fid_before != $fid_after"
7928
7929         # 3. migrate a plain layout file to a comp layout
7930         $LFS migrate $layout $f_comp ||
7931                 error "cannot migrate $f_comp by lfs migrate"
7932         fid_after=$($LFS getstripe --fid $f_comp)
7933         [ "$fid_before" == "$fid_after" ] ||
7934                 error "plain-to-comp migrate: $fid_before != $fid_after"
7935 }
7936 run_test 56xf "FID is not lost during migration of a composite layout file"
7937
7938 check_file_ost_range() {
7939         local file="$1"
7940         shift
7941         local range="$*"
7942         local -a file_range
7943         local idx
7944
7945         file_range=($($LFS getstripe -y "$file" |
7946                 awk '/l_ost_idx:/ { print $NF }'))
7947
7948         if [[ "${#file_range[@]}" = 0 ]]; then
7949                 echo "No osts found for $file"
7950                 return 1
7951         fi
7952
7953         for idx in "${file_range[@]}"; do
7954                 [[ " $range " =~ " $idx " ]] ||
7955                         return 1
7956         done
7957
7958         return 0
7959 }
7960
7961 sub_test_56xg() {
7962         local stripe_opt="$1"
7963         local pool="$2"
7964         shift 2
7965         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7966
7967         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7968                 error "Fail to migrate $tfile on $pool"
7969         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7970                 error "$tfile is not in pool $pool"
7971         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7972                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7973 }
7974
7975 test_56xg() {
7976         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7977         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7978         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7979                 skip "Need MDS version newer than 2.14.52"
7980
7981         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7982         local -a pool_ranges=("0 0" "1 1" "0 1")
7983
7984         # init pools
7985         for i in "${!pool_names[@]}"; do
7986                 pool_add ${pool_names[$i]} ||
7987                         error "pool_add failed (pool: ${pool_names[$i]})"
7988                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7989                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7990         done
7991
7992         # init the file to migrate
7993         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7994                 error "Unable to create $tfile on OST1"
7995         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7996                 error "Unable to write on $tfile"
7997
7998         echo "1. migrate $tfile on pool ${pool_names[0]}"
7999         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8000
8001         echo "2. migrate $tfile on pool ${pool_names[2]}"
8002         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8003
8004         echo "3. migrate $tfile on pool ${pool_names[1]}"
8005         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8006
8007         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8008         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8009         echo
8010
8011         # Clean pools
8012         destroy_test_pools ||
8013                 error "pool_destroy failed"
8014 }
8015 run_test 56xg "lfs migrate pool support"
8016
8017 test_56y() {
8018         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8019                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8020
8021         local res=""
8022         local dir=$DIR/$tdir
8023         local f1=$dir/file1
8024         local f2=$dir/file2
8025
8026         test_mkdir -p $dir || error "creating dir $dir"
8027         touch $f1 || error "creating std file $f1"
8028         $MULTIOP $f2 H2c || error "creating released file $f2"
8029
8030         # a directory can be raid0, so ask only for files
8031         res=$($LFS find $dir -L raid0 -type f | wc -l)
8032         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8033
8034         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8035         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8036
8037         # only files can be released, so no need to force file search
8038         res=$($LFS find $dir -L released)
8039         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8040
8041         res=$($LFS find $dir -type f \! -L released)
8042         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8043 }
8044 run_test 56y "lfs find -L raid0|released"
8045
8046 test_56z() { # LU-4824
8047         # This checks to make sure 'lfs find' continues after errors
8048         # There are two classes of errors that should be caught:
8049         # - If multiple paths are provided, all should be searched even if one
8050         #   errors out
8051         # - If errors are encountered during the search, it should not terminate
8052         #   early
8053         local dir=$DIR/$tdir
8054         local i
8055
8056         test_mkdir $dir
8057         for i in d{0..9}; do
8058                 test_mkdir $dir/$i
8059                 touch $dir/$i/$tfile
8060         done
8061         $LFS find $DIR/non_existent_dir $dir &&
8062                 error "$LFS find did not return an error"
8063         # Make a directory unsearchable. This should NOT be the last entry in
8064         # directory order.  Arbitrarily pick the 6th entry
8065         chmod 700 $($LFS find $dir -type d | sed '6!d')
8066
8067         $RUNAS $LFS find $DIR/non_existent $dir
8068         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8069
8070         # The user should be able to see 10 directories and 9 files
8071         (( count == 19 )) ||
8072                 error "$LFS find found $count != 19 entries after error"
8073 }
8074 run_test 56z "lfs find should continue after an error"
8075
8076 test_56aa() { # LU-5937
8077         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8078
8079         local dir=$DIR/$tdir
8080
8081         mkdir $dir
8082         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8083
8084         createmany -o $dir/striped_dir/${tfile}- 1024
8085         local dirs=$($LFS find --size +8k $dir/)
8086
8087         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8088 }
8089 run_test 56aa "lfs find --size under striped dir"
8090
8091 test_56ab() { # LU-10705
8092         test_mkdir $DIR/$tdir
8093         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8094         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8095         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8096         # Flush writes to ensure valid blocks.  Need to be more thorough for
8097         # ZFS, since blocks are not allocated/returned to client immediately.
8098         sync_all_data
8099         wait_zfs_commit ost1 2
8100         cancel_lru_locks osc
8101         ls -ls $DIR/$tdir
8102
8103         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8104
8105         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8106
8107         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8108         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8109
8110         rm -f $DIR/$tdir/$tfile.[123]
8111 }
8112 run_test 56ab "lfs find --blocks"
8113
8114 # LU-11188
8115 test_56aca() {
8116         local dir="$DIR/$tdir"
8117         local perms=(001 002 003 004 005 006 007
8118                      010 020 030 040 050 060 070
8119                      100 200 300 400 500 600 700
8120                      111 222 333 444 555 666 777)
8121         local perm_minus=(8 8 4 8 4 4 2
8122                           8 8 4 8 4 4 2
8123                           8 8 4 8 4 4 2
8124                           4 4 2 4 2 2 1)
8125         local perm_slash=(8  8 12  8 12 12 14
8126                           8  8 12  8 12 12 14
8127                           8  8 12  8 12 12 14
8128                          16 16 24 16 24 24 28)
8129
8130         test_mkdir "$dir"
8131         for perm in ${perms[*]}; do
8132                 touch "$dir/$tfile.$perm"
8133                 chmod $perm "$dir/$tfile.$perm"
8134         done
8135
8136         for ((i = 0; i < ${#perms[*]}; i++)); do
8137                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8138                 (( $num == 1 )) ||
8139                         error "lfs find -perm ${perms[i]}:"\
8140                               "$num != 1"
8141
8142                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8143                 (( $num == ${perm_minus[i]} )) ||
8144                         error "lfs find -perm -${perms[i]}:"\
8145                               "$num != ${perm_minus[i]}"
8146
8147                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8148                 (( $num == ${perm_slash[i]} )) ||
8149                         error "lfs find -perm /${perms[i]}:"\
8150                               "$num != ${perm_slash[i]}"
8151         done
8152 }
8153 run_test 56aca "check lfs find -perm with octal representation"
8154
8155 test_56acb() {
8156         local dir=$DIR/$tdir
8157         # p is the permission of write and execute for user, group and other
8158         # without the umask. It is used to test +wx.
8159         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8160         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8161         local symbolic=(+t  a+t u+t g+t o+t
8162                         g+s u+s o+s +s o+sr
8163                         o=r,ug+o,u+w
8164                         u+ g+ o+ a+ ugo+
8165                         u- g- o- a- ugo-
8166                         u= g= o= a= ugo=
8167                         o=r,ug+o,u+w u=r,a+u,u+w
8168                         g=r,ugo=g,u+w u+x,+X +X
8169                         u+x,u+X u+X u+x,g+X o+r,+X
8170                         u+x,go+X +wx +rwx)
8171
8172         test_mkdir $dir
8173         for perm in ${perms[*]}; do
8174                 touch "$dir/$tfile.$perm"
8175                 chmod $perm "$dir/$tfile.$perm"
8176         done
8177
8178         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8179                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8180
8181                 (( $num == 1 )) ||
8182                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8183         done
8184 }
8185 run_test 56acb "check lfs find -perm with symbolic representation"
8186
8187 test_56acc() {
8188         local dir=$DIR/$tdir
8189         local tests="17777 787 789 abcd
8190                 ug=uu ug=a ug=gu uo=ou urw
8191                 u+xg+x a=r,u+x,"
8192
8193         test_mkdir $dir
8194         for err in $tests; do
8195                 if $LFS find $dir -perm $err 2>/dev/null; then
8196                         error "lfs find -perm $err: parsing should have failed"
8197                 fi
8198         done
8199 }
8200 run_test 56acc "check parsing error for lfs find -perm"
8201
8202 test_56ba() {
8203         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8204                 skip "Need MDS version at least 2.10.50"
8205
8206         # Create composite files with one component
8207         local dir=$DIR/$tdir
8208
8209         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8210         # Create composite files with three components
8211         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8212         # Create non-composite files
8213         createmany -o $dir/${tfile}- 10
8214
8215         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8216
8217         [[ $nfiles == 10 ]] ||
8218                 error "lfs find -E 1M found $nfiles != 10 files"
8219
8220         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8221         [[ $nfiles == 25 ]] ||
8222                 error "lfs find ! -E 1M found $nfiles != 25 files"
8223
8224         # All files have a component that starts at 0
8225         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8226         [[ $nfiles == 35 ]] ||
8227                 error "lfs find --component-start 0 - $nfiles != 35 files"
8228
8229         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8230         [[ $nfiles == 15 ]] ||
8231                 error "lfs find --component-start 2M - $nfiles != 15 files"
8232
8233         # All files created here have a componenet that does not starts at 2M
8234         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8235         [[ $nfiles == 35 ]] ||
8236                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8237
8238         # Find files with a specified number of components
8239         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8240         [[ $nfiles == 15 ]] ||
8241                 error "lfs find --component-count 3 - $nfiles != 15 files"
8242
8243         # Remember non-composite files have a component count of zero
8244         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8245         [[ $nfiles == 10 ]] ||
8246                 error "lfs find --component-count 0 - $nfiles != 10 files"
8247
8248         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8249         [[ $nfiles == 20 ]] ||
8250                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8251
8252         # All files have a flag called "init"
8253         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8254         [[ $nfiles == 35 ]] ||
8255                 error "lfs find --component-flags init - $nfiles != 35 files"
8256
8257         # Multi-component files will have a component not initialized
8258         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8259         [[ $nfiles == 15 ]] ||
8260                 error "lfs find !--component-flags init - $nfiles != 15 files"
8261
8262         rm -rf $dir
8263
8264 }
8265 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8266
8267 test_56ca() {
8268         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8269                 skip "Need MDS version at least 2.10.57"
8270
8271         local td=$DIR/$tdir
8272         local tf=$td/$tfile
8273         local dir
8274         local nfiles
8275         local cmd
8276         local i
8277         local j
8278
8279         # create mirrored directories and mirrored files
8280         mkdir $td || error "mkdir $td failed"
8281         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8282         createmany -o $tf- 10 || error "create $tf- failed"
8283
8284         for i in $(seq 2); do
8285                 dir=$td/dir$i
8286                 mkdir $dir || error "mkdir $dir failed"
8287                 $LFS mirror create -N$((3 + i)) $dir ||
8288                         error "create mirrored dir $dir failed"
8289                 createmany -o $dir/$tfile- 10 ||
8290                         error "create $dir/$tfile- failed"
8291         done
8292
8293         # change the states of some mirrored files
8294         echo foo > $tf-6
8295         for i in $(seq 2); do
8296                 dir=$td/dir$i
8297                 for j in $(seq 4 9); do
8298                         echo foo > $dir/$tfile-$j
8299                 done
8300         done
8301
8302         # find mirrored files with specific mirror count
8303         cmd="$LFS find --mirror-count 3 --type f $td"
8304         nfiles=$($cmd | wc -l)
8305         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8306
8307         cmd="$LFS find ! --mirror-count 3 --type f $td"
8308         nfiles=$($cmd | wc -l)
8309         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8310
8311         cmd="$LFS find --mirror-count +2 --type f $td"
8312         nfiles=$($cmd | wc -l)
8313         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8314
8315         cmd="$LFS find --mirror-count -6 --type f $td"
8316         nfiles=$($cmd | wc -l)
8317         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8318
8319         # find mirrored files with specific file state
8320         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8321         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8322
8323         cmd="$LFS find --mirror-state=ro --type f $td"
8324         nfiles=$($cmd | wc -l)
8325         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8326
8327         cmd="$LFS find ! --mirror-state=ro --type f $td"
8328         nfiles=$($cmd | wc -l)
8329         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8330
8331         cmd="$LFS find --mirror-state=wp --type f $td"
8332         nfiles=$($cmd | wc -l)
8333         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8334
8335         cmd="$LFS find ! --mirror-state=sp --type f $td"
8336         nfiles=$($cmd | wc -l)
8337         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8338 }
8339 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8340
8341 test_56da() { # LU-14179
8342         local path=$DIR/$tdir
8343
8344         test_mkdir $path
8345         cd $path
8346
8347         local longdir=$(str_repeat 'a' 255)
8348
8349         for i in {1..15}; do
8350                 path=$path/$longdir
8351                 test_mkdir $longdir
8352                 cd $longdir
8353         done
8354
8355         local len=${#path}
8356         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8357
8358         test_mkdir $lastdir
8359         cd $lastdir
8360         # PATH_MAX-1
8361         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8362
8363         # NAME_MAX
8364         touch $(str_repeat 'f' 255)
8365
8366         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8367                 error "lfs find reported an error"
8368
8369         rm -rf $DIR/$tdir
8370 }
8371 run_test 56da "test lfs find with long paths"
8372
8373 test_56ea() { #LU-10378
8374         local path=$DIR/$tdir
8375         local pool=$TESTNAME
8376
8377         # Create ost pool
8378         pool_add $pool || error "pool_add $pool failed"
8379         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8380                 error "adding targets to $pool failed"
8381
8382         # Set default pool on directory before creating file
8383         mkdir $path || error "mkdir $path failed"
8384         $LFS setstripe -p $pool $path ||
8385                 error "set OST pool on $pool failed"
8386         touch $path/$tfile || error "touch $path/$tfile failed"
8387
8388         # Compare basic file attributes from -printf and stat
8389         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8390         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8391
8392         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8393                 error "Attrs from lfs find and stat don't match"
8394
8395         # Compare Lustre attributes from lfs find and lfs getstripe
8396         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8397         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8398         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8399         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8400         local fpool=$($LFS getstripe --pool $path/$tfile)
8401         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8402
8403         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8404                 error "Attrs from lfs find and lfs getstripe don't match"
8405
8406         # Verify behavior for unknown escape/format sequences
8407         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8408
8409         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8410                 error "Escape/format codes don't match"
8411 }
8412 run_test 56ea "test lfs find -printf option"
8413
8414 test_57a() {
8415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8416         # note test will not do anything if MDS is not local
8417         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8418                 skip_env "ldiskfs only test"
8419         fi
8420         remote_mds_nodsh && skip "remote MDS with nodsh"
8421
8422         local MNTDEV="osd*.*MDT*.mntdev"
8423         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8424         [ -z "$DEV" ] && error "can't access $MNTDEV"
8425         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8426                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8427                         error "can't access $DEV"
8428                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8429                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8430                 rm $TMP/t57a.dump
8431         done
8432 }
8433 run_test 57a "verify MDS filesystem created with large inodes =="
8434
8435 test_57b() {
8436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8437         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8438                 skip_env "ldiskfs only test"
8439         fi
8440         remote_mds_nodsh && skip "remote MDS with nodsh"
8441
8442         local dir=$DIR/$tdir
8443         local filecount=100
8444         local file1=$dir/f1
8445         local fileN=$dir/f$filecount
8446
8447         rm -rf $dir || error "removing $dir"
8448         test_mkdir -c1 $dir
8449         local mdtidx=$($LFS getstripe -m $dir)
8450         local mdtname=MDT$(printf %04x $mdtidx)
8451         local facet=mds$((mdtidx + 1))
8452
8453         echo "mcreating $filecount files"
8454         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8455
8456         # verify that files do not have EAs yet
8457         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8458                 error "$file1 has an EA"
8459         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8460                 error "$fileN has an EA"
8461
8462         sync
8463         sleep 1
8464         df $dir  #make sure we get new statfs data
8465         local mdsfree=$(do_facet $facet \
8466                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8467         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8468         local file
8469
8470         echo "opening files to create objects/EAs"
8471         for file in $(seq -f $dir/f%g 1 $filecount); do
8472                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8473                         error "opening $file"
8474         done
8475
8476         # verify that files have EAs now
8477         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8478         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8479
8480         sleep 1  #make sure we get new statfs data
8481         df $dir
8482         local mdsfree2=$(do_facet $facet \
8483                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8484         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8485
8486         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8487                 if [ "$mdsfree" != "$mdsfree2" ]; then
8488                         error "MDC before $mdcfree != after $mdcfree2"
8489                 else
8490                         echo "MDC before $mdcfree != after $mdcfree2"
8491                         echo "unable to confirm if MDS has large inodes"
8492                 fi
8493         fi
8494         rm -rf $dir
8495 }
8496 run_test 57b "default LOV EAs are stored inside large inodes ==="
8497
8498 test_58() {
8499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8500         [ -z "$(which wiretest 2>/dev/null)" ] &&
8501                         skip_env "could not find wiretest"
8502
8503         wiretest
8504 }
8505 run_test 58 "verify cross-platform wire constants =============="
8506
8507 test_59() {
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509
8510         echo "touch 130 files"
8511         createmany -o $DIR/f59- 130
8512         echo "rm 130 files"
8513         unlinkmany $DIR/f59- 130
8514         sync
8515         # wait for commitment of removal
8516         wait_delete_completed
8517 }
8518 run_test 59 "verify cancellation of llog records async ========="
8519
8520 TEST60_HEAD="test_60 run $RANDOM"
8521 test_60a() {
8522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8523         remote_mgs_nodsh && skip "remote MGS with nodsh"
8524         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8525                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8526                         skip_env "missing subtest run-llog.sh"
8527
8528         log "$TEST60_HEAD - from kernel mode"
8529         do_facet mgs "$LCTL dk > /dev/null"
8530         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8531         do_facet mgs $LCTL dk > $TMP/$tfile
8532
8533         # LU-6388: test llog_reader
8534         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8535         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8536         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8537                         skip_env "missing llog_reader"
8538         local fstype=$(facet_fstype mgs)
8539         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8540                 skip_env "Only for ldiskfs or zfs type mgs"
8541
8542         local mntpt=$(facet_mntpt mgs)
8543         local mgsdev=$(mgsdevname 1)
8544         local fid_list
8545         local fid
8546         local rec_list
8547         local rec
8548         local rec_type
8549         local obj_file
8550         local path
8551         local seq
8552         local oid
8553         local pass=true
8554
8555         #get fid and record list
8556         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8557                 tail -n 4))
8558         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8559                 tail -n 4))
8560         #remount mgs as ldiskfs or zfs type
8561         stop mgs || error "stop mgs failed"
8562         mount_fstype mgs || error "remount mgs failed"
8563         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8564                 fid=${fid_list[i]}
8565                 rec=${rec_list[i]}
8566                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8567                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8568                 oid=$((16#$oid))
8569
8570                 case $fstype in
8571                         ldiskfs )
8572                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8573                         zfs )
8574                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8575                 esac
8576                 echo "obj_file is $obj_file"
8577                 do_facet mgs $llog_reader $obj_file
8578
8579                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8580                         awk '{ print $3 }' | sed -e "s/^type=//g")
8581                 if [ $rec_type != $rec ]; then
8582                         echo "FAILED test_60a wrong record type $rec_type," \
8583                               "should be $rec"
8584                         pass=false
8585                         break
8586                 fi
8587
8588                 #check obj path if record type is LLOG_LOGID_MAGIC
8589                 if [ "$rec" == "1064553b" ]; then
8590                         path=$(do_facet mgs $llog_reader $obj_file |
8591                                 grep "path=" | awk '{ print $NF }' |
8592                                 sed -e "s/^path=//g")
8593                         if [ $obj_file != $mntpt/$path ]; then
8594                                 echo "FAILED test_60a wrong obj path" \
8595                                       "$montpt/$path, should be $obj_file"
8596                                 pass=false
8597                                 break
8598                         fi
8599                 fi
8600         done
8601         rm -f $TMP/$tfile
8602         #restart mgs before "error", otherwise it will block the next test
8603         stop mgs || error "stop mgs failed"
8604         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8605         $pass || error "test failed, see FAILED test_60a messages for specifics"
8606 }
8607 run_test 60a "llog_test run from kernel module and test llog_reader"
8608
8609 test_60b() { # bug 6411
8610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8611
8612         dmesg > $DIR/$tfile
8613         LLOG_COUNT=$(do_facet mgs dmesg |
8614                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8615                           /llog_[a-z]*.c:[0-9]/ {
8616                                 if (marker)
8617                                         from_marker++
8618                                 from_begin++
8619                           }
8620                           END {
8621                                 if (marker)
8622                                         print from_marker
8623                                 else
8624                                         print from_begin
8625                           }")
8626
8627         [[ $LLOG_COUNT -gt 120 ]] &&
8628                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8629 }
8630 run_test 60b "limit repeated messages from CERROR/CWARN"
8631
8632 test_60c() {
8633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8634
8635         echo "create 5000 files"
8636         createmany -o $DIR/f60c- 5000
8637 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8638         lctl set_param fail_loc=0x80000137
8639         unlinkmany $DIR/f60c- 5000
8640         lctl set_param fail_loc=0
8641 }
8642 run_test 60c "unlink file when mds full"
8643
8644 test_60d() {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646
8647         SAVEPRINTK=$(lctl get_param -n printk)
8648         # verify "lctl mark" is even working"
8649         MESSAGE="test message ID $RANDOM $$"
8650         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8651         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8652
8653         lctl set_param printk=0 || error "set lnet.printk failed"
8654         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8655         MESSAGE="new test message ID $RANDOM $$"
8656         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8657         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8658         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8659
8660         lctl set_param -n printk="$SAVEPRINTK"
8661 }
8662 run_test 60d "test printk console message masking"
8663
8664 test_60e() {
8665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8666         remote_mds_nodsh && skip "remote MDS with nodsh"
8667
8668         touch $DIR/$tfile
8669 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8670         do_facet mds1 lctl set_param fail_loc=0x15b
8671         rm $DIR/$tfile
8672 }
8673 run_test 60e "no space while new llog is being created"
8674
8675 test_60f() {
8676         local old_path=$($LCTL get_param -n debug_path)
8677
8678         stack_trap "$LCTL set_param debug_path=$old_path"
8679         stack_trap "rm -f $TMP/$tfile*"
8680         rm -f $TMP/$tfile* 2> /dev/null
8681         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8682         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8683         test_mkdir $DIR/$tdir
8684         # retry in case the open is cached and not released
8685         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8686                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8687                 sleep 0.1
8688         done
8689         ls $TMP/$tfile*
8690         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8691 }
8692 run_test 60f "change debug_path works"
8693
8694 test_60g() {
8695         local pid
8696         local i
8697
8698         test_mkdir -c $MDSCOUNT $DIR/$tdir
8699
8700         (
8701                 local index=0
8702                 while true; do
8703                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8704                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8705                                 2>/dev/null
8706                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8707                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8708                         index=$((index + 1))
8709                 done
8710         ) &
8711
8712         pid=$!
8713
8714         for i in {0..100}; do
8715                 # define OBD_FAIL_OSD_TXN_START    0x19a
8716                 local index=$((i % MDSCOUNT + 1))
8717
8718                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8719                         > /dev/null
8720                 sleep 0.01
8721         done
8722
8723         kill -9 $pid
8724
8725         for i in $(seq $MDSCOUNT); do
8726                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8727         done
8728
8729         mkdir $DIR/$tdir/new || error "mkdir failed"
8730         rmdir $DIR/$tdir/new || error "rmdir failed"
8731
8732         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8733                 -t namespace
8734         for i in $(seq $MDSCOUNT); do
8735                 wait_update_facet mds$i "$LCTL get_param -n \
8736                         mdd.$(facet_svc mds$i).lfsck_namespace |
8737                         awk '/^status/ { print \\\$2 }'" "completed"
8738         done
8739
8740         ls -R $DIR/$tdir
8741         rm -rf $DIR/$tdir || error "rmdir failed"
8742 }
8743 run_test 60g "transaction abort won't cause MDT hung"
8744
8745 test_60h() {
8746         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8747                 skip "Need MDS version at least 2.12.52"
8748         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8749
8750         local f
8751
8752         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8753         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8754         for fail_loc in 0x80000188 0x80000189; do
8755                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8756                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8757                         error "mkdir $dir-$fail_loc failed"
8758                 for i in {0..10}; do
8759                         # create may fail on missing stripe
8760                         echo $i > $DIR/$tdir-$fail_loc/$i
8761                 done
8762                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8763                         error "getdirstripe $tdir-$fail_loc failed"
8764                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8765                         error "migrate $tdir-$fail_loc failed"
8766                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8767                         error "getdirstripe $tdir-$fail_loc failed"
8768                 pushd $DIR/$tdir-$fail_loc
8769                 for f in *; do
8770                         echo $f | cmp $f - || error "$f data mismatch"
8771                 done
8772                 popd
8773                 rm -rf $DIR/$tdir-$fail_loc
8774         done
8775 }
8776 run_test 60h "striped directory with missing stripes can be accessed"
8777
8778 function t60i_load() {
8779         mkdir $DIR/$tdir
8780         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8781         $LCTL set_param fail_loc=0x131c fail_val=1
8782         for ((i=0; i<5000; i++)); do
8783                 touch $DIR/$tdir/f$i
8784         done
8785 }
8786
8787 test_60i() {
8788         changelog_register || error "changelog_register failed"
8789         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8790         changelog_users $SINGLEMDS | grep -q $cl_user ||
8791                 error "User $cl_user not found in changelog_users"
8792         changelog_chmask "ALL"
8793         t60i_load &
8794         local PID=$!
8795         for((i=0; i<100; i++)); do
8796                 changelog_dump >/dev/null ||
8797                         error "can't read changelog"
8798         done
8799         kill $PID
8800         wait $PID
8801         changelog_deregister || error "changelog_deregister failed"
8802         $LCTL set_param fail_loc=0
8803 }
8804 run_test 60i "llog: new record vs reader race"
8805
8806 test_60j() {
8807         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8808                 skip "need MDS version at least 2.15.50"
8809         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8810         remote_mds_nodsh && skip "remote MDS with nodsh"
8811         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8812
8813         changelog_users $SINGLEMDS | grep "^cl" &&
8814                 skip "active changelog user"
8815
8816         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8817
8818         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8819                 skip_env "missing llog_reader"
8820
8821         mkdir_on_mdt0 $DIR/$tdir
8822
8823         local f=$DIR/$tdir/$tfile
8824         local mdt_dev
8825         local tmpfile
8826         local plain
8827
8828         changelog_register || error "cannot register changelog user"
8829
8830         # set changelog_mask to ALL
8831         changelog_chmask "ALL"
8832         changelog_clear
8833
8834         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8835         unlinkmany ${f}- 100 || error "unlinkmany failed"
8836
8837         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8838         mdt_dev=$(facet_device $SINGLEMDS)
8839
8840         do_facet $SINGLEMDS sync
8841         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8842                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8843                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8844
8845         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8846
8847         # if $tmpfile is not on EXT3 filesystem for some reason
8848         [[ ${plain:0:1} == 'O' ]] ||
8849                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8850
8851         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8852                 $mdt_dev; stat -c %s $tmpfile")
8853         echo "Truncate llog from $size to $((size - size % 8192))"
8854         size=$((size - size % 8192))
8855         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8856         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8857                 grep -c 'in bitmap only')
8858         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8859
8860         size=$((size - 9000))
8861         echo "Corrupt llog in the middle at $size"
8862         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8863                 count=333 conv=notrunc
8864         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8865                 grep -c 'next chunk')
8866         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
8867 }
8868 run_test 60j "llog_reader reports corruptions"
8869
8870 test_61a() {
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872
8873         f="$DIR/f61"
8874         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8875         cancel_lru_locks osc
8876         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8877         sync
8878 }
8879 run_test 61a "mmap() writes don't make sync hang ================"
8880
8881 test_61b() {
8882         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8883 }
8884 run_test 61b "mmap() of unstriped file is successful"
8885
8886 # bug 2330 - insufficient obd_match error checking causes LBUG
8887 test_62() {
8888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8889
8890         f="$DIR/f62"
8891         echo foo > $f
8892         cancel_lru_locks osc
8893         lctl set_param fail_loc=0x405
8894         cat $f && error "cat succeeded, expect -EIO"
8895         lctl set_param fail_loc=0
8896 }
8897 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8898 # match every page all of the time.
8899 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8900
8901 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8902 # Though this test is irrelevant anymore, it helped to reveal some
8903 # other grant bugs (LU-4482), let's keep it.
8904 test_63a() {   # was test_63
8905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8906
8907         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8908
8909         for i in `seq 10` ; do
8910                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8911                 sleep 5
8912                 kill $!
8913                 sleep 1
8914         done
8915
8916         rm -f $DIR/f63 || true
8917 }
8918 run_test 63a "Verify oig_wait interruption does not crash ======="
8919
8920 # bug 2248 - async write errors didn't return to application on sync
8921 # bug 3677 - async write errors left page locked
8922 test_63b() {
8923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8924
8925         debugsave
8926         lctl set_param debug=-1
8927
8928         # ensure we have a grant to do async writes
8929         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8930         rm $DIR/$tfile
8931
8932         sync    # sync lest earlier test intercept the fail_loc
8933
8934         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8935         lctl set_param fail_loc=0x80000406
8936         $MULTIOP $DIR/$tfile Owy && \
8937                 error "sync didn't return ENOMEM"
8938         sync; sleep 2; sync     # do a real sync this time to flush page
8939         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8940                 error "locked page left in cache after async error" || true
8941         debugrestore
8942 }
8943 run_test 63b "async write errors should be returned to fsync ==="
8944
8945 test_64a () {
8946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8947
8948         lfs df $DIR
8949         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8950 }
8951 run_test 64a "verify filter grant calculations (in kernel) ====="
8952
8953 test_64b () {
8954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8955
8956         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8957 }
8958 run_test 64b "check out-of-space detection on client"
8959
8960 test_64c() {
8961         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8962 }
8963 run_test 64c "verify grant shrink"
8964
8965 import_param() {
8966         local tgt=$1
8967         local param=$2
8968
8969         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8970 }
8971
8972 # this does exactly what osc_request.c:osc_announce_cached() does in
8973 # order to calculate max amount of grants to ask from server
8974 want_grant() {
8975         local tgt=$1
8976
8977         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8978         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8979
8980         ((rpc_in_flight++));
8981         nrpages=$((nrpages * rpc_in_flight))
8982
8983         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8984
8985         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8986
8987         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8988         local undirty=$((nrpages * PAGE_SIZE))
8989
8990         local max_extent_pages
8991         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8992         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8993         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8994         local grant_extent_tax
8995         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8996
8997         undirty=$((undirty + nrextents * grant_extent_tax))
8998
8999         echo $undirty
9000 }
9001
9002 # this is size of unit for grant allocation. It should be equal to
9003 # what tgt_grant.c:tgt_grant_chunk() calculates
9004 grant_chunk() {
9005         local tgt=$1
9006         local max_brw_size
9007         local grant_extent_tax
9008
9009         max_brw_size=$(import_param $tgt max_brw_size)
9010
9011         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9012
9013         echo $(((max_brw_size + grant_extent_tax) * 2))
9014 }
9015
9016 test_64d() {
9017         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9018                 skip "OST < 2.10.55 doesn't limit grants enough"
9019
9020         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9021
9022         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9023                 skip "no grant_param connect flag"
9024
9025         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9026
9027         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9028         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9029
9030
9031         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9032         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9033
9034         $LFS setstripe $DIR/$tfile -i 0 -c 1
9035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9036         ddpid=$!
9037
9038         while kill -0 $ddpid; do
9039                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9040
9041                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9042                         kill $ddpid
9043                         error "cur_grant $cur_grant > $max_cur_granted"
9044                 fi
9045
9046                 sleep 1
9047         done
9048 }
9049 run_test 64d "check grant limit exceed"
9050
9051 check_grants() {
9052         local tgt=$1
9053         local expected=$2
9054         local msg=$3
9055         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9056
9057         ((cur_grants == expected)) ||
9058                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9059 }
9060
9061 round_up_p2() {
9062         echo $((($1 + $2 - 1) & ~($2 - 1)))
9063 }
9064
9065 test_64e() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9068                 skip "Need OSS version at least 2.11.56"
9069
9070         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9071         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9072         $LCTL set_param debug=+cache
9073
9074         # Remount client to reset grant
9075         remount_client $MOUNT || error "failed to remount client"
9076         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9077
9078         local init_grants=$(import_param $osc_tgt initial_grant)
9079
9080         check_grants $osc_tgt $init_grants "init grants"
9081
9082         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9083         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9084         local gbs=$(import_param $osc_tgt grant_block_size)
9085
9086         # write random number of bytes from max_brw_size / 4 to max_brw_size
9087         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9088         # align for direct io
9089         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9090         # round to grant consumption unit
9091         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9092
9093         local grants=$((wb_round_up + extent_tax))
9094
9095         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9096
9097         # define OBD_FAIL_TGT_NO_GRANT 0x725
9098         # make the server not grant more back
9099         do_facet ost1 $LCTL set_param fail_loc=0x725
9100         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9101
9102         do_facet ost1 $LCTL set_param fail_loc=0
9103
9104         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9105
9106         rm -f $DIR/$tfile || error "rm failed"
9107
9108         # Remount client to reset grant
9109         remount_client $MOUNT || error "failed to remount client"
9110         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9111
9112         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9113
9114         # define OBD_FAIL_TGT_NO_GRANT 0x725
9115         # make the server not grant more back
9116         do_facet ost1 $LCTL set_param fail_loc=0x725
9117         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9118         do_facet ost1 $LCTL set_param fail_loc=0
9119
9120         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9121 }
9122 run_test 64e "check grant consumption (no grant allocation)"
9123
9124 test_64f() {
9125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9126
9127         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9128         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9129         $LCTL set_param debug=+cache
9130
9131         # Remount client to reset grant
9132         remount_client $MOUNT || error "failed to remount client"
9133         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9134
9135         local init_grants=$(import_param $osc_tgt initial_grant)
9136         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9137         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9138         local gbs=$(import_param $osc_tgt grant_block_size)
9139         local chunk=$(grant_chunk $osc_tgt)
9140
9141         # write random number of bytes from max_brw_size / 4 to max_brw_size
9142         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9143         # align for direct io
9144         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9145         # round to grant consumption unit
9146         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9147
9148         local grants=$((wb_round_up + extent_tax))
9149
9150         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9151         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9152                 error "error writing to $DIR/$tfile"
9153
9154         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9155                 "direct io with grant allocation"
9156
9157         rm -f $DIR/$tfile || error "rm failed"
9158
9159         # Remount client to reset grant
9160         remount_client $MOUNT || error "failed to remount client"
9161         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9162
9163         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9164
9165         local cmd="oO_WRONLY:w${write_bytes}_yc"
9166
9167         $MULTIOP $DIR/$tfile $cmd &
9168         MULTIPID=$!
9169         sleep 1
9170
9171         check_grants $osc_tgt $((init_grants - grants)) \
9172                 "buffered io, not write rpc"
9173
9174         kill -USR1 $MULTIPID
9175         wait
9176
9177         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9178                 "buffered io, one RPC"
9179 }
9180 run_test 64f "check grant consumption (with grant allocation)"
9181
9182 test_64g() {
9183         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9184                 skip "Need MDS version at least 2.14.56"
9185
9186         local mdts=$(comma_list $(mdts_nodes))
9187
9188         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9189                         tr '\n' ' ')
9190         stack_trap "$LCTL set_param $old"
9191
9192         # generate dirty pages and increase dirty granted on MDT
9193         stack_trap "rm -f $DIR/$tfile-*"
9194         for (( i = 0; i < 10; i++)); do
9195                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9196                         error "can't set stripe"
9197                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9198                         error "can't dd"
9199                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9200                         $LFS getstripe $DIR/$tfile-$i
9201                         error "not DoM file"
9202                 }
9203         done
9204
9205         # flush dirty pages
9206         sync
9207
9208         # wait until grant shrink reset grant dirty on MDTs
9209         for ((i = 0; i < 120; i++)); do
9210                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9211                         awk '{sum=sum+$1} END {print sum}')
9212                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9213                 echo "$grant_dirty grants, $vm_dirty pages"
9214                 (( grant_dirty + vm_dirty == 0 )) && break
9215                 (( i == 3 )) && sync &&
9216                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9217                 sleep 1
9218         done
9219
9220         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9221                 awk '{sum=sum+$1} END {print sum}')
9222         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9223 }
9224 run_test 64g "grant shrink on MDT"
9225
9226 test_64h() {
9227         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9228                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9229
9230         local instance=$($LFS getname -i $DIR)
9231         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9232         local num_exps=$(do_facet ost1 \
9233             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9234         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9235         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9236         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9237
9238         # 10MiB is for file to be written, max_brw_size * 16 *
9239         # num_exps is space reserve so that tgt_grant_shrink() decided
9240         # to not shrink
9241         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9242         (( avail * 1024 < expect )) &&
9243                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9244
9245         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9246         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9247         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9248         $LCTL set_param osc.*OST0000*.grant_shrink=1
9249         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9250
9251         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9253
9254         # drop cache so that coming read would do rpc
9255         cancel_lru_locks osc
9256
9257         # shrink interval is set to 10, pause for 7 seconds so that
9258         # grant thread did not wake up yet but coming read entered
9259         # shrink mode for rpc (osc_should_shrink_grant())
9260         sleep 7
9261
9262         declare -a cur_grant_bytes
9263         declare -a tot_granted
9264         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9265         tot_granted[0]=$(do_facet ost1 \
9266             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9267
9268         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9269
9270         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9271         tot_granted[1]=$(do_facet ost1 \
9272             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9273
9274         # grant change should be equal on both sides
9275         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9276                 tot_granted[0] - tot_granted[1])) ||
9277                 error "grant change mismatch, "                                \
9278                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9279                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9280 }
9281 run_test 64h "grant shrink on read"
9282
9283 test_64i() {
9284         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9285                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9286
9287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9288         remote_ost_nodsh && skip "remote OSTs with nodsh"
9289
9290         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9291
9292         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9293
9294         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9295         local instance=$($LFS getname -i $DIR)
9296
9297         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9298         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9299
9300         # shrink grants and simulate rpc loss
9301         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9302         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9303         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9304
9305         fail ost1
9306
9307         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9308
9309         local testid=$(echo $TESTNAME | tr '_' ' ')
9310
9311         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9312                 grep "GRANT, real grant" &&
9313                 error "client has more grants then it owns" || true
9314 }
9315 run_test 64i "shrink on reconnect"
9316
9317 # bug 1414 - set/get directories' stripe info
9318 test_65a() {
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320
9321         test_mkdir $DIR/$tdir
9322         touch $DIR/$tdir/f1
9323         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9324 }
9325 run_test 65a "directory with no stripe info"
9326
9327 test_65b() {
9328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9329
9330         test_mkdir $DIR/$tdir
9331         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9332
9333         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9334                                                 error "setstripe"
9335         touch $DIR/$tdir/f2
9336         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9337 }
9338 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9339
9340 test_65c() {
9341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9342         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9343
9344         test_mkdir $DIR/$tdir
9345         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9346
9347         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9348                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9349         touch $DIR/$tdir/f3
9350         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9351 }
9352 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9353
9354 test_65d() {
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356
9357         test_mkdir $DIR/$tdir
9358         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9359         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9360
9361         if [[ $STRIPECOUNT -le 0 ]]; then
9362                 sc=1
9363         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9364                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9365                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9366         else
9367                 sc=$(($STRIPECOUNT - 1))
9368         fi
9369         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9370         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9371         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9372                 error "lverify failed"
9373 }
9374 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9375
9376 test_65e() {
9377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9378
9379         test_mkdir $DIR/$tdir
9380
9381         $LFS setstripe $DIR/$tdir || error "setstripe"
9382         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9383                                         error "no stripe info failed"
9384         touch $DIR/$tdir/f6
9385         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9386 }
9387 run_test 65e "directory setstripe defaults"
9388
9389 test_65f() {
9390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9391
9392         test_mkdir $DIR/${tdir}f
9393         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9394                 error "setstripe succeeded" || true
9395 }
9396 run_test 65f "dir setstripe permission (should return error) ==="
9397
9398 test_65g() {
9399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9400
9401         test_mkdir $DIR/$tdir
9402         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9403
9404         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9405                 error "setstripe -S failed"
9406         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9407         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9408                 error "delete default stripe failed"
9409 }
9410 run_test 65g "directory setstripe -d"
9411
9412 test_65h() {
9413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9414
9415         test_mkdir $DIR/$tdir
9416         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9417
9418         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9419                 error "setstripe -S failed"
9420         test_mkdir $DIR/$tdir/dd1
9421         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9422                 error "stripe info inherit failed"
9423 }
9424 run_test 65h "directory stripe info inherit ===================="
9425
9426 test_65i() {
9427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9428
9429         save_layout_restore_at_exit $MOUNT
9430
9431         # bug6367: set non-default striping on root directory
9432         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9433
9434         # bug12836: getstripe on -1 default directory striping
9435         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9436
9437         # bug12836: getstripe -v on -1 default directory striping
9438         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9439
9440         # bug12836: new find on -1 default directory striping
9441         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9442 }
9443 run_test 65i "various tests to set root directory striping"
9444
9445 test_65j() { # bug6367
9446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9447
9448         sync; sleep 1
9449
9450         # if we aren't already remounting for each test, do so for this test
9451         if [ "$I_MOUNTED" = "yes" ]; then
9452                 cleanup || error "failed to unmount"
9453                 setup
9454         fi
9455
9456         save_layout_restore_at_exit $MOUNT
9457
9458         $LFS setstripe -d $MOUNT || error "setstripe failed"
9459 }
9460 run_test 65j "set default striping on root directory (bug 6367)="
9461
9462 cleanup_65k() {
9463         rm -rf $DIR/$tdir
9464         wait_delete_completed
9465         do_facet $SINGLEMDS "lctl set_param -n \
9466                 osp.$ost*MDT0000.max_create_count=$max_count"
9467         do_facet $SINGLEMDS "lctl set_param -n \
9468                 osp.$ost*MDT0000.create_count=$count"
9469         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9470         echo $INACTIVE_OSC "is Activate"
9471
9472         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9473 }
9474
9475 test_65k() { # bug11679
9476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9477         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9478         remote_mds_nodsh && skip "remote MDS with nodsh"
9479
9480         local disable_precreate=true
9481         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9482                 disable_precreate=false
9483
9484         echo "Check OST status: "
9485         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9486                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9487
9488         for OSC in $MDS_OSCS; do
9489                 echo $OSC "is active"
9490                 do_facet $SINGLEMDS lctl --device %$OSC activate
9491         done
9492
9493         for INACTIVE_OSC in $MDS_OSCS; do
9494                 local ost=$(osc_to_ost $INACTIVE_OSC)
9495                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9496                                lov.*md*.target_obd |
9497                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9498
9499                 mkdir -p $DIR/$tdir
9500                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9501                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9502
9503                 echo "Deactivate: " $INACTIVE_OSC
9504                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9505
9506                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9507                               osp.$ost*MDT0000.create_count")
9508                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9509                                   osp.$ost*MDT0000.max_create_count")
9510                 $disable_precreate &&
9511                         do_facet $SINGLEMDS "lctl set_param -n \
9512                                 osp.$ost*MDT0000.max_create_count=0"
9513
9514                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9515                         [ -f $DIR/$tdir/$idx ] && continue
9516                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9517                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9518                                 { cleanup_65k;
9519                                   error "setstripe $idx should succeed"; }
9520                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9521                 done
9522                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9523                 rmdir $DIR/$tdir
9524
9525                 do_facet $SINGLEMDS "lctl set_param -n \
9526                         osp.$ost*MDT0000.max_create_count=$max_count"
9527                 do_facet $SINGLEMDS "lctl set_param -n \
9528                         osp.$ost*MDT0000.create_count=$count"
9529                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9530                 echo $INACTIVE_OSC "is Activate"
9531
9532                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9533         done
9534 }
9535 run_test 65k "validate manual striping works properly with deactivated OSCs"
9536
9537 test_65l() { # bug 12836
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539
9540         test_mkdir -p $DIR/$tdir/test_dir
9541         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9542         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9543 }
9544 run_test 65l "lfs find on -1 stripe dir ========================"
9545
9546 test_65m() {
9547         local layout=$(save_layout $MOUNT)
9548         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9549                 restore_layout $MOUNT $layout
9550                 error "setstripe should fail by non-root users"
9551         }
9552         true
9553 }
9554 run_test 65m "normal user can't set filesystem default stripe"
9555
9556 test_65n() {
9557         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9558         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9559                 skip "Need MDS version at least 2.12.50"
9560         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9561
9562         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9563         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9564         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9565
9566         save_layout_restore_at_exit $MOUNT
9567
9568         # new subdirectory under root directory should not inherit
9569         # the default layout from root
9570         local dir1=$MOUNT/$tdir-1
9571         mkdir $dir1 || error "mkdir $dir1 failed"
9572         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9573                 error "$dir1 shouldn't have LOV EA"
9574
9575         # delete the default layout on root directory
9576         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9577
9578         local dir2=$MOUNT/$tdir-2
9579         mkdir $dir2 || error "mkdir $dir2 failed"
9580         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9581                 error "$dir2 shouldn't have LOV EA"
9582
9583         # set a new striping pattern on root directory
9584         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9585         local new_def_stripe_size=$((def_stripe_size * 2))
9586         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9587                 error "set stripe size on $MOUNT failed"
9588
9589         # new file created in $dir2 should inherit the new stripe size from
9590         # the filesystem default
9591         local file2=$dir2/$tfile-2
9592         touch $file2 || error "touch $file2 failed"
9593
9594         local file2_stripe_size=$($LFS getstripe -S $file2)
9595         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9596         {
9597                 echo "file2_stripe_size: '$file2_stripe_size'"
9598                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9599                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9600         }
9601
9602         local dir3=$MOUNT/$tdir-3
9603         mkdir $dir3 || error "mkdir $dir3 failed"
9604         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9605         # the root layout, which is the actual default layout that will be used
9606         # when new files are created in $dir3.
9607         local dir3_layout=$(get_layout_param $dir3)
9608         local root_dir_layout=$(get_layout_param $MOUNT)
9609         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9610         {
9611                 echo "dir3_layout: '$dir3_layout'"
9612                 echo "root_dir_layout: '$root_dir_layout'"
9613                 error "$dir3 should show the default layout from $MOUNT"
9614         }
9615
9616         # set OST pool on root directory
9617         local pool=$TESTNAME
9618         pool_add $pool || error "add $pool failed"
9619         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9620                 error "add targets to $pool failed"
9621
9622         $LFS setstripe -p $pool $MOUNT ||
9623                 error "set OST pool on $MOUNT failed"
9624
9625         # new file created in $dir3 should inherit the pool from
9626         # the filesystem default
9627         local file3=$dir3/$tfile-3
9628         touch $file3 || error "touch $file3 failed"
9629
9630         local file3_pool=$($LFS getstripe -p $file3)
9631         [[ "$file3_pool" = "$pool" ]] ||
9632                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9633
9634         local dir4=$MOUNT/$tdir-4
9635         mkdir $dir4 || error "mkdir $dir4 failed"
9636         local dir4_layout=$(get_layout_param $dir4)
9637         root_dir_layout=$(get_layout_param $MOUNT)
9638         echo "$LFS getstripe -d $dir4"
9639         $LFS getstripe -d $dir4
9640         echo "$LFS getstripe -d $MOUNT"
9641         $LFS getstripe -d $MOUNT
9642         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9643         {
9644                 echo "dir4_layout: '$dir4_layout'"
9645                 echo "root_dir_layout: '$root_dir_layout'"
9646                 error "$dir4 should show the default layout from $MOUNT"
9647         }
9648
9649         # new file created in $dir4 should inherit the pool from
9650         # the filesystem default
9651         local file4=$dir4/$tfile-4
9652         touch $file4 || error "touch $file4 failed"
9653
9654         local file4_pool=$($LFS getstripe -p $file4)
9655         [[ "$file4_pool" = "$pool" ]] ||
9656                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9657
9658         # new subdirectory under non-root directory should inherit
9659         # the default layout from its parent directory
9660         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9661                 error "set directory layout on $dir4 failed"
9662
9663         local dir5=$dir4/$tdir-5
9664         mkdir $dir5 || error "mkdir $dir5 failed"
9665
9666         dir4_layout=$(get_layout_param $dir4)
9667         local dir5_layout=$(get_layout_param $dir5)
9668         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9669         {
9670                 echo "dir4_layout: '$dir4_layout'"
9671                 echo "dir5_layout: '$dir5_layout'"
9672                 error "$dir5 should inherit the default layout from $dir4"
9673         }
9674
9675         # though subdir under ROOT doesn't inherit default layout, but
9676         # its sub dir/file should be created with default layout.
9677         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9678         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9679                 skip "Need MDS version at least 2.12.59"
9680
9681         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9682         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9683         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9684
9685         if [ $default_lmv_hash == "none" ]; then
9686                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9687         else
9688                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9689                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9690         fi
9691
9692         $LFS setdirstripe -D -c 2 $MOUNT ||
9693                 error "setdirstripe -D -c 2 failed"
9694         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9695         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9696         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9697
9698         # $dir4 layout includes pool
9699         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9700         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9701                 error "pool lost on setstripe"
9702         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9703         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9704                 error "pool lost on compound layout setstripe"
9705 }
9706 run_test 65n "don't inherit default layout from root for new subdirectories"
9707
9708 test_65o() {
9709         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9710                 skip "need MDS version at least 2.14.57"
9711
9712         # set OST pool on root directory
9713         local pool=$TESTNAME
9714
9715         pool_add $pool || error "add $pool failed"
9716         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9717                 error "add targets to $pool failed"
9718
9719         local dir1=$MOUNT/$tdir
9720
9721         mkdir $dir1 || error "mkdir $dir1 failed"
9722
9723         # set a new striping pattern on root directory
9724         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9725
9726         $LFS setstripe -p $pool $dir1 ||
9727                 error "set directory layout on $dir1 failed"
9728
9729         # $dir1 layout includes pool
9730         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9731         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9732                 error "pool lost on setstripe"
9733         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9734         $LFS getstripe $dir1
9735         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9736                 error "pool lost on compound layout setstripe"
9737
9738         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9739                 error "setdirstripe failed on sub-dir with inherited pool"
9740         $LFS getstripe $dir1/dir2
9741         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9742                 error "pool lost on compound layout setdirstripe"
9743
9744         $LFS setstripe -E -1 -c 1 $dir1
9745         $LFS getstripe -d $dir1
9746         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9747                 error "pool lost on setstripe"
9748 }
9749 run_test 65o "pool inheritance for mdt component"
9750
9751 test_65p () { # LU-16152
9752         local src_dir=$DIR/$tdir/src_dir
9753         local dst_dir=$DIR/$tdir/dst_dir
9754         local yaml_file=$DIR/$tdir/layout.yaml
9755         local border
9756
9757         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9758                 skip "Need at least version 2.15.51"
9759
9760         test_mkdir -p $src_dir
9761         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9762                 error "failed to setstripe"
9763         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9764                 error "failed to getstripe"
9765
9766         test_mkdir -p $dst_dir
9767         $LFS setstripe --yaml $yaml_file $dst_dir ||
9768                 error "failed to setstripe with yaml file"
9769         border=$($LFS getstripe -d $dst_dir |
9770                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9771                 error "failed to getstripe"
9772
9773         # 2048M is 0x80000000, or 2147483648
9774         (( $border == 2147483648 )) ||
9775                 error "failed to handle huge number in yaml layout"
9776 }
9777 run_test 65p "setstripe with yaml file and huge number"
9778
9779 # bug 2543 - update blocks count on client
9780 test_66() {
9781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9782
9783         local COUNT=${COUNT:-8}
9784         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9785         sync; sync_all_data; sync; sync_all_data
9786         cancel_lru_locks osc
9787         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9788         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9789 }
9790 run_test 66 "update inode blocks count on client ==============="
9791
9792 meminfo() {
9793         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9794 }
9795
9796 swap_used() {
9797         swapon -s | awk '($1 == "'$1'") { print $4 }'
9798 }
9799
9800 # bug5265, obdfilter oa2dentry return -ENOENT
9801 # #define OBD_FAIL_SRV_ENOENT 0x217
9802 test_69() {
9803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9804         remote_ost_nodsh && skip "remote OST with nodsh"
9805
9806         f="$DIR/$tfile"
9807         $LFS setstripe -c 1 -i 0 $f
9808
9809         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9810
9811         do_facet ost1 lctl set_param fail_loc=0x217
9812         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9813         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9814
9815         do_facet ost1 lctl set_param fail_loc=0
9816         $DIRECTIO write $f 0 2 || error "write error"
9817
9818         cancel_lru_locks osc
9819         $DIRECTIO read $f 0 1 || error "read error"
9820
9821         do_facet ost1 lctl set_param fail_loc=0x217
9822         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9823
9824         do_facet ost1 lctl set_param fail_loc=0
9825         rm -f $f
9826 }
9827 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9828
9829 test_71() {
9830         test_mkdir $DIR/$tdir
9831         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9832         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9833 }
9834 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9835
9836 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9838         [ "$RUNAS_ID" = "$UID" ] &&
9839                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9840         # Check that testing environment is properly set up. Skip if not
9841         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9842                 skip_env "User $RUNAS_ID does not exist - skipping"
9843
9844         touch $DIR/$tfile
9845         chmod 777 $DIR/$tfile
9846         chmod ug+s $DIR/$tfile
9847         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9848                 error "$RUNAS dd $DIR/$tfile failed"
9849         # See if we are still setuid/sgid
9850         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9851                 error "S/gid is not dropped on write"
9852         # Now test that MDS is updated too
9853         cancel_lru_locks mdc
9854         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9855                 error "S/gid is not dropped on MDS"
9856         rm -f $DIR/$tfile
9857 }
9858 run_test 72a "Test that remove suid works properly (bug5695) ===="
9859
9860 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9861         local perm
9862
9863         [ "$RUNAS_ID" = "$UID" ] &&
9864                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9865         [ "$RUNAS_ID" -eq 0 ] &&
9866                 skip_env "RUNAS_ID = 0 -- skipping"
9867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9868         # Check that testing environment is properly set up. Skip if not
9869         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9870                 skip_env "User $RUNAS_ID does not exist - skipping"
9871
9872         touch $DIR/${tfile}-f{g,u}
9873         test_mkdir $DIR/${tfile}-dg
9874         test_mkdir $DIR/${tfile}-du
9875         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9876         chmod g+s $DIR/${tfile}-{f,d}g
9877         chmod u+s $DIR/${tfile}-{f,d}u
9878         for perm in 777 2777 4777; do
9879                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9880                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9881                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9882                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9883         done
9884         true
9885 }
9886 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9887
9888 # bug 3462 - multiple simultaneous MDC requests
9889 test_73() {
9890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9891
9892         test_mkdir $DIR/d73-1
9893         test_mkdir $DIR/d73-2
9894         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9895         pid1=$!
9896
9897         lctl set_param fail_loc=0x80000129
9898         $MULTIOP $DIR/d73-1/f73-2 Oc &
9899         sleep 1
9900         lctl set_param fail_loc=0
9901
9902         $MULTIOP $DIR/d73-2/f73-3 Oc &
9903         pid3=$!
9904
9905         kill -USR1 $pid1
9906         wait $pid1 || return 1
9907
9908         sleep 25
9909
9910         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9911         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9912         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9913
9914         rm -rf $DIR/d73-*
9915 }
9916 run_test 73 "multiple MDC requests (should not deadlock)"
9917
9918 test_74a() { # bug 6149, 6184
9919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9920
9921         touch $DIR/f74a
9922         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9923         #
9924         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9925         # will spin in a tight reconnection loop
9926         $LCTL set_param fail_loc=0x8000030e
9927         # get any lock that won't be difficult - lookup works.
9928         ls $DIR/f74a
9929         $LCTL set_param fail_loc=0
9930         rm -f $DIR/f74a
9931         true
9932 }
9933 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9934
9935 test_74b() { # bug 13310
9936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9937
9938         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9939         #
9940         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9941         # will spin in a tight reconnection loop
9942         $LCTL set_param fail_loc=0x8000030e
9943         # get a "difficult" lock
9944         touch $DIR/f74b
9945         $LCTL set_param fail_loc=0
9946         rm -f $DIR/f74b
9947         true
9948 }
9949 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9950
9951 test_74c() {
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953
9954         #define OBD_FAIL_LDLM_NEW_LOCK
9955         $LCTL set_param fail_loc=0x319
9956         touch $DIR/$tfile && error "touch successful"
9957         $LCTL set_param fail_loc=0
9958         true
9959 }
9960 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9961
9962 slab_lic=/sys/kernel/slab/lustre_inode_cache
9963 num_objects() {
9964         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9965         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9966                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9967 }
9968
9969 test_76a() { # Now for b=20433, added originally in b=1443
9970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9971
9972         cancel_lru_locks osc
9973         # there may be some slab objects cached per core
9974         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9975         local before=$(num_objects)
9976         local count=$((512 * cpus))
9977         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9978         local margin=$((count / 10))
9979         if [[ -f $slab_lic/aliases ]]; then
9980                 local aliases=$(cat $slab_lic/aliases)
9981                 (( aliases > 0 )) && margin=$((margin * aliases))
9982         fi
9983
9984         echo "before slab objects: $before"
9985         for i in $(seq $count); do
9986                 touch $DIR/$tfile
9987                 rm -f $DIR/$tfile
9988         done
9989         cancel_lru_locks osc
9990         local after=$(num_objects)
9991         echo "created: $count, after slab objects: $after"
9992         # shared slab counts are not very accurate, allow significant margin
9993         # the main goal is that the cache growth is not permanently > $count
9994         while (( after > before + margin )); do
9995                 sleep 1
9996                 after=$(num_objects)
9997                 wait=$((wait + 1))
9998                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9999                 if (( wait > 60 )); then
10000                         error "inode slab grew from $before+$margin to $after"
10001                 fi
10002         done
10003 }
10004 run_test 76a "confirm clients recycle inodes properly ===="
10005
10006 test_76b() {
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10009
10010         local count=512
10011         local before=$(num_objects)
10012
10013         for i in $(seq $count); do
10014                 mkdir $DIR/$tdir
10015                 rmdir $DIR/$tdir
10016         done
10017
10018         local after=$(num_objects)
10019         local wait=0
10020
10021         while (( after > before )); do
10022                 sleep 1
10023                 after=$(num_objects)
10024                 wait=$((wait + 1))
10025                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10026                 if (( wait > 60 )); then
10027                         error "inode slab grew from $before to $after"
10028                 fi
10029         done
10030
10031         echo "slab objects before: $before, after: $after"
10032 }
10033 run_test 76b "confirm clients recycle directory inodes properly ===="
10034
10035 export ORIG_CSUM=""
10036 set_checksums()
10037 {
10038         # Note: in sptlrpc modes which enable its own bulk checksum, the
10039         # original crc32_le bulk checksum will be automatically disabled,
10040         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10041         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10042         # In this case set_checksums() will not be no-op, because sptlrpc
10043         # bulk checksum will be enabled all through the test.
10044
10045         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10046         lctl set_param -n osc.*.checksums $1
10047         return 0
10048 }
10049
10050 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10051                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10052 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10053                              tr -d [] | head -n1)}
10054 set_checksum_type()
10055 {
10056         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10057         rc=$?
10058         log "set checksum type to $1, rc = $rc"
10059         return $rc
10060 }
10061
10062 get_osc_checksum_type()
10063 {
10064         # arugment 1: OST name, like OST0000
10065         ost=$1
10066         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10067                         sed 's/.*\[\(.*\)\].*/\1/g')
10068         rc=$?
10069         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10070         echo $checksum_type
10071 }
10072
10073 F77_TMP=$TMP/f77-temp
10074 F77SZ=8
10075 setup_f77() {
10076         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10077                 error "error writing to $F77_TMP"
10078 }
10079
10080 test_77a() { # bug 10889
10081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10082         $GSS && skip_env "could not run with gss"
10083
10084         [ ! -f $F77_TMP ] && setup_f77
10085         set_checksums 1
10086         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10087         set_checksums 0
10088         rm -f $DIR/$tfile
10089 }
10090 run_test 77a "normal checksum read/write operation"
10091
10092 test_77b() { # bug 10889
10093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10094         $GSS && skip_env "could not run with gss"
10095
10096         [ ! -f $F77_TMP ] && setup_f77
10097         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10098         $LCTL set_param fail_loc=0x80000409
10099         set_checksums 1
10100
10101         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10102                 error "dd error: $?"
10103         $LCTL set_param fail_loc=0
10104
10105         for algo in $CKSUM_TYPES; do
10106                 cancel_lru_locks osc
10107                 set_checksum_type $algo
10108                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10109                 $LCTL set_param fail_loc=0x80000408
10110                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10111                 $LCTL set_param fail_loc=0
10112         done
10113         set_checksums 0
10114         set_checksum_type $ORIG_CSUM_TYPE
10115         rm -f $DIR/$tfile
10116 }
10117 run_test 77b "checksum error on client write, read"
10118
10119 cleanup_77c() {
10120         trap 0
10121         set_checksums 0
10122         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10123         $check_ost &&
10124                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10125         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10126         $check_ost && [ -n "$ost_file_prefix" ] &&
10127                 do_facet ost1 rm -f ${ost_file_prefix}\*
10128 }
10129
10130 test_77c() {
10131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10132         $GSS && skip_env "could not run with gss"
10133         remote_ost_nodsh && skip "remote OST with nodsh"
10134
10135         local bad1
10136         local osc_file_prefix
10137         local osc_file
10138         local check_ost=false
10139         local ost_file_prefix
10140         local ost_file
10141         local orig_cksum
10142         local dump_cksum
10143         local fid
10144
10145         # ensure corruption will occur on first OSS/OST
10146         $LFS setstripe -i 0 $DIR/$tfile
10147
10148         [ ! -f $F77_TMP ] && setup_f77
10149         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10150                 error "dd write error: $?"
10151         fid=$($LFS path2fid $DIR/$tfile)
10152
10153         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10154         then
10155                 check_ost=true
10156                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10157                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10158         else
10159                 echo "OSS do not support bulk pages dump upon error"
10160         fi
10161
10162         osc_file_prefix=$($LCTL get_param -n debug_path)
10163         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10164
10165         trap cleanup_77c EXIT
10166
10167         set_checksums 1
10168         # enable bulk pages dump upon error on Client
10169         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10170         # enable bulk pages dump upon error on OSS
10171         $check_ost &&
10172                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10173
10174         # flush Client cache to allow next read to reach OSS
10175         cancel_lru_locks osc
10176
10177         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10178         $LCTL set_param fail_loc=0x80000408
10179         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10180         $LCTL set_param fail_loc=0
10181
10182         rm -f $DIR/$tfile
10183
10184         # check cksum dump on Client
10185         osc_file=$(ls ${osc_file_prefix}*)
10186         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10187         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10188         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10189         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10190         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10191                      cksum)
10192         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10193         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10194                 error "dump content does not match on Client"
10195
10196         $check_ost || skip "No need to check cksum dump on OSS"
10197
10198         # check cksum dump on OSS
10199         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10200         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10201         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10202         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10203         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10204                 error "dump content does not match on OSS"
10205
10206         cleanup_77c
10207 }
10208 run_test 77c "checksum error on client read with debug"
10209
10210 test_77d() { # bug 10889
10211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10212         $GSS && skip_env "could not run with gss"
10213
10214         stack_trap "rm -f $DIR/$tfile"
10215         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10216         $LCTL set_param fail_loc=0x80000409
10217         set_checksums 1
10218         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10219                 error "direct write: rc=$?"
10220         $LCTL set_param fail_loc=0
10221         set_checksums 0
10222
10223         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10224         $LCTL set_param fail_loc=0x80000408
10225         set_checksums 1
10226         cancel_lru_locks osc
10227         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10228                 error "direct read: rc=$?"
10229         $LCTL set_param fail_loc=0
10230         set_checksums 0
10231 }
10232 run_test 77d "checksum error on OST direct write, read"
10233
10234 test_77f() { # bug 10889
10235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10236         $GSS && skip_env "could not run with gss"
10237
10238         set_checksums 1
10239         stack_trap "rm -f $DIR/$tfile"
10240         for algo in $CKSUM_TYPES; do
10241                 cancel_lru_locks osc
10242                 set_checksum_type $algo
10243                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10244                 $LCTL set_param fail_loc=0x409
10245                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10246                         error "direct write succeeded"
10247                 $LCTL set_param fail_loc=0
10248         done
10249         set_checksum_type $ORIG_CSUM_TYPE
10250         set_checksums 0
10251 }
10252 run_test 77f "repeat checksum error on write (expect error)"
10253
10254 test_77g() { # bug 10889
10255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10256         $GSS && skip_env "could not run with gss"
10257         remote_ost_nodsh && skip "remote OST with nodsh"
10258
10259         [ ! -f $F77_TMP ] && setup_f77
10260
10261         local file=$DIR/$tfile
10262         stack_trap "rm -f $file" EXIT
10263
10264         $LFS setstripe -c 1 -i 0 $file
10265         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10266         do_facet ost1 lctl set_param fail_loc=0x8000021a
10267         set_checksums 1
10268         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10269                 error "write error: rc=$?"
10270         do_facet ost1 lctl set_param fail_loc=0
10271         set_checksums 0
10272
10273         cancel_lru_locks osc
10274         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10275         do_facet ost1 lctl set_param fail_loc=0x8000021b
10276         set_checksums 1
10277         cmp $F77_TMP $file || error "file compare failed"
10278         do_facet ost1 lctl set_param fail_loc=0
10279         set_checksums 0
10280 }
10281 run_test 77g "checksum error on OST write, read"
10282
10283 test_77k() { # LU-10906
10284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10285         $GSS && skip_env "could not run with gss"
10286
10287         local cksum_param="osc.$FSNAME*.checksums"
10288         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10289         local checksum
10290         local i
10291
10292         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10293         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10294         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10295
10296         for i in 0 1; do
10297                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10298                         error "failed to set checksum=$i on MGS"
10299                 wait_update $HOSTNAME "$get_checksum" $i
10300                 #remount
10301                 echo "remount client, checksum should be $i"
10302                 remount_client $MOUNT || error "failed to remount client"
10303                 checksum=$(eval $get_checksum)
10304                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10305         done
10306         # remove persistent param to avoid races with checksum mountopt below
10307         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10308                 error "failed to delete checksum on MGS"
10309
10310         for opt in "checksum" "nochecksum"; do
10311                 #remount with mount option
10312                 echo "remount client with option $opt, checksum should be $i"
10313                 umount_client $MOUNT || error "failed to umount client"
10314                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10315                         error "failed to mount client with option '$opt'"
10316                 checksum=$(eval $get_checksum)
10317                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10318                 i=$((i - 1))
10319         done
10320
10321         remount_client $MOUNT || error "failed to remount client"
10322 }
10323 run_test 77k "enable/disable checksum correctly"
10324
10325 test_77l() {
10326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10327         $GSS && skip_env "could not run with gss"
10328
10329         set_checksums 1
10330         stack_trap "set_checksums $ORIG_CSUM" EXIT
10331         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10332
10333         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10334
10335         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10336         for algo in $CKSUM_TYPES; do
10337                 set_checksum_type $algo || error "fail to set checksum type $algo"
10338                 osc_algo=$(get_osc_checksum_type OST0000)
10339                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10340
10341                 # no locks, no reqs to let the connection idle
10342                 cancel_lru_locks osc
10343                 lru_resize_disable osc
10344                 wait_osc_import_state client ost1 IDLE
10345
10346                 # ensure ost1 is connected
10347                 stat $DIR/$tfile >/dev/null || error "can't stat"
10348                 wait_osc_import_state client ost1 FULL
10349
10350                 osc_algo=$(get_osc_checksum_type OST0000)
10351                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10352         done
10353         return 0
10354 }
10355 run_test 77l "preferred checksum type is remembered after reconnected"
10356
10357 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10358 rm -f $F77_TMP
10359 unset F77_TMP
10360
10361 test_77m() {
10362         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10363                 skip "Need at least version 2.14.52"
10364         local param=checksum_speed
10365
10366         $LCTL get_param $param || error "reading $param failed"
10367
10368         csum_speeds=$($LCTL get_param -n $param)
10369
10370         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10371                 error "known checksum types are missing"
10372 }
10373 run_test 77m "Verify checksum_speed is correctly read"
10374
10375 check_filefrag_77n() {
10376         local nr_ext=0
10377         local starts=()
10378         local ends=()
10379
10380         while read extidx a b start end rest; do
10381                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10382                         nr_ext=$(( $nr_ext + 1 ))
10383                         starts+=( ${start%..} )
10384                         ends+=( ${end%:} )
10385                 fi
10386         done < <( filefrag -sv $1 )
10387
10388         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10389         return 1
10390 }
10391
10392 test_77n() {
10393         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10394
10395         touch $DIR/$tfile
10396         $TRUNCATE $DIR/$tfile 0
10397         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10398         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10399         check_filefrag_77n $DIR/$tfile ||
10400                 skip "$tfile blocks not contiguous around hole"
10401
10402         set_checksums 1
10403         stack_trap "set_checksums $ORIG_CSUM" EXIT
10404         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10405         stack_trap "rm -f $DIR/$tfile"
10406
10407         for algo in $CKSUM_TYPES; do
10408                 if [[ "$algo" =~ ^t10 ]]; then
10409                         set_checksum_type $algo ||
10410                                 error "fail to set checksum type $algo"
10411                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10412                                 error "fail to read $tfile with $algo"
10413                 fi
10414         done
10415         rm -f $DIR/$tfile
10416         return 0
10417 }
10418 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10419
10420 test_77o() {
10421         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10422                 skip "Need MDS version at least 2.14.55"
10423         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10424                 skip "Need OST version at least 2.14.55"
10425         local ofd=obdfilter
10426         local mdt=mdt
10427
10428         # print OST checksum_type
10429         echo "$ofd.$FSNAME-*.checksum_type:"
10430         do_nodes $(comma_list $(osts_nodes)) \
10431                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10432
10433         # print MDT checksum_type
10434         echo "$mdt.$FSNAME-*.checksum_type:"
10435         do_nodes $(comma_list $(mdts_nodes)) \
10436                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10437
10438         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10439                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10440
10441         (( $o_count == $OSTCOUNT )) ||
10442                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10443
10444         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10445                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10446
10447         (( $m_count == $MDSCOUNT )) ||
10448                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10449 }
10450 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10451
10452 cleanup_test_78() {
10453         trap 0
10454         rm -f $DIR/$tfile
10455 }
10456
10457 test_78() { # bug 10901
10458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10459         remote_ost || skip_env "local OST"
10460
10461         NSEQ=5
10462         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10463         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10464         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10465         echo "MemTotal: $MEMTOTAL"
10466
10467         # reserve 256MB of memory for the kernel and other running processes,
10468         # and then take 1/2 of the remaining memory for the read/write buffers.
10469         if [ $MEMTOTAL -gt 512 ] ;then
10470                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10471         else
10472                 # for those poor memory-starved high-end clusters...
10473                 MEMTOTAL=$((MEMTOTAL / 2))
10474         fi
10475         echo "Mem to use for directio: $MEMTOTAL"
10476
10477         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10478         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10479         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10480         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10481                 head -n1)
10482         echo "Smallest OST: $SMALLESTOST"
10483         [[ $SMALLESTOST -lt 10240 ]] &&
10484                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10485
10486         trap cleanup_test_78 EXIT
10487
10488         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10489                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10490
10491         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10492         echo "File size: $F78SIZE"
10493         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10494         for i in $(seq 1 $NSEQ); do
10495                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10496                 echo directIO rdwr round $i of $NSEQ
10497                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10498         done
10499
10500         cleanup_test_78
10501 }
10502 run_test 78 "handle large O_DIRECT writes correctly ============"
10503
10504 test_79() { # bug 12743
10505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10506
10507         wait_delete_completed
10508
10509         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10510         BKFREE=$(calc_osc_kbytes kbytesfree)
10511         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10512
10513         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10514         DFTOTAL=`echo $STRING | cut -d, -f1`
10515         DFUSED=`echo $STRING  | cut -d, -f2`
10516         DFAVAIL=`echo $STRING | cut -d, -f3`
10517         DFFREE=$(($DFTOTAL - $DFUSED))
10518
10519         ALLOWANCE=$((64 * $OSTCOUNT))
10520
10521         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10522            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10523                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10524         fi
10525         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10526            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10527                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10528         fi
10529         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10530            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10531                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10532         fi
10533 }
10534 run_test 79 "df report consistency check ======================="
10535
10536 test_80() { # bug 10718
10537         remote_ost_nodsh && skip "remote OST with nodsh"
10538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10539
10540         # relax strong synchronous semantics for slow backends like ZFS
10541         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10542                 local soc="obdfilter.*.sync_lock_cancel"
10543                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10544
10545                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10546                 if [ -z "$save" ]; then
10547                         soc="obdfilter.*.sync_on_lock_cancel"
10548                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10549                 fi
10550
10551                 if [ "$save" != "never" ]; then
10552                         local hosts=$(comma_list $(osts_nodes))
10553
10554                         do_nodes $hosts $LCTL set_param $soc=never
10555                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10556                 fi
10557         fi
10558
10559         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10560         sync; sleep 1; sync
10561         local before=$(date +%s)
10562         cancel_lru_locks osc
10563         local after=$(date +%s)
10564         local diff=$((after - before))
10565         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10566
10567         rm -f $DIR/$tfile
10568 }
10569 run_test 80 "Page eviction is equally fast at high offsets too"
10570
10571 test_81a() { # LU-456
10572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10573         remote_ost_nodsh && skip "remote OST with nodsh"
10574
10575         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10576         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10577         do_facet ost1 lctl set_param fail_loc=0x80000228
10578
10579         # write should trigger a retry and success
10580         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10581         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10582         RC=$?
10583         if [ $RC -ne 0 ] ; then
10584                 error "write should success, but failed for $RC"
10585         fi
10586 }
10587 run_test 81a "OST should retry write when get -ENOSPC ==============="
10588
10589 test_81b() { # LU-456
10590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10591         remote_ost_nodsh && skip "remote OST with nodsh"
10592
10593         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10594         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10595         do_facet ost1 lctl set_param fail_loc=0x228
10596
10597         # write should retry several times and return -ENOSPC finally
10598         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10599         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10600         RC=$?
10601         ENOSPC=28
10602         if [ $RC -ne $ENOSPC ] ; then
10603                 error "dd should fail for -ENOSPC, but succeed."
10604         fi
10605 }
10606 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10607
10608 test_99() {
10609         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10610
10611         test_mkdir $DIR/$tdir.cvsroot
10612         chown $RUNAS_ID $DIR/$tdir.cvsroot
10613
10614         cd $TMP
10615         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10616
10617         cd /etc/init.d
10618         # some versions of cvs import exit(1) when asked to import links or
10619         # files they can't read.  ignore those files.
10620         local toignore=$(find . -type l -printf '-I %f\n' -o \
10621                          ! -perm /4 -printf '-I %f\n')
10622         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10623                 $tdir.reposname vtag rtag
10624
10625         cd $DIR
10626         test_mkdir $DIR/$tdir.reposname
10627         chown $RUNAS_ID $DIR/$tdir.reposname
10628         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10629
10630         cd $DIR/$tdir.reposname
10631         $RUNAS touch foo99
10632         $RUNAS cvs add -m 'addmsg' foo99
10633         $RUNAS cvs update
10634         $RUNAS cvs commit -m 'nomsg' foo99
10635         rm -fr $DIR/$tdir.cvsroot
10636 }
10637 run_test 99 "cvs strange file/directory operations"
10638
10639 test_100() {
10640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10641         [[ "$NETTYPE" =~ tcp ]] ||
10642                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10643         remote_ost_nodsh && skip "remote OST with nodsh"
10644         remote_mds_nodsh && skip "remote MDS with nodsh"
10645         remote_servers ||
10646                 skip "useless for local single node setup"
10647
10648         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10649                 [ "$PROT" != "tcp" ] && continue
10650                 RPORT=$(echo $REMOTE | cut -d: -f2)
10651                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10652
10653                 rc=0
10654                 LPORT=`echo $LOCAL | cut -d: -f2`
10655                 if [ $LPORT -ge 1024 ]; then
10656                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10657                         netstat -tna
10658                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10659                 fi
10660         done
10661         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10662 }
10663 run_test 100 "check local port using privileged port ==========="
10664
10665 function get_named_value()
10666 {
10667     local tag=$1
10668
10669     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10670 }
10671
10672 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10673                    awk '/^max_cached_mb/ { print $2 }')
10674
10675 cleanup_101a() {
10676         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10677         trap 0
10678 }
10679
10680 test_101a() {
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682
10683         local s
10684         local discard
10685         local nreads=10000
10686         local cache_limit=32
10687
10688         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10689         trap cleanup_101a EXIT
10690         $LCTL set_param -n llite.*.read_ahead_stats=0
10691         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10692
10693         #
10694         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10695         #
10696         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10697         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10698
10699         discard=0
10700         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10701                    get_named_value 'read.but.discarded'); do
10702                         discard=$(($discard + $s))
10703         done
10704         cleanup_101a
10705
10706         $LCTL get_param osc.*-osc*.rpc_stats
10707         $LCTL get_param llite.*.read_ahead_stats
10708
10709         # Discard is generally zero, but sometimes a few random reads line up
10710         # and trigger larger readahead, which is wasted & leads to discards.
10711         if [[ $(($discard)) -gt $nreads ]]; then
10712                 error "too many ($discard) discarded pages"
10713         fi
10714         rm -f $DIR/$tfile || true
10715 }
10716 run_test 101a "check read-ahead for random reads"
10717
10718 setup_test101bc() {
10719         test_mkdir $DIR/$tdir
10720         local ssize=$1
10721         local FILE_LENGTH=$2
10722         STRIPE_OFFSET=0
10723
10724         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10725
10726         local list=$(comma_list $(osts_nodes))
10727         set_osd_param $list '' read_cache_enable 0
10728         set_osd_param $list '' writethrough_cache_enable 0
10729
10730         trap cleanup_test101bc EXIT
10731         # prepare the read-ahead file
10732         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10733
10734         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10735                                 count=$FILE_SIZE_MB 2> /dev/null
10736
10737 }
10738
10739 cleanup_test101bc() {
10740         trap 0
10741         rm -rf $DIR/$tdir
10742         rm -f $DIR/$tfile
10743
10744         local list=$(comma_list $(osts_nodes))
10745         set_osd_param $list '' read_cache_enable 1
10746         set_osd_param $list '' writethrough_cache_enable 1
10747 }
10748
10749 calc_total() {
10750         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10751 }
10752
10753 ra_check_101() {
10754         local read_size=$1
10755         local stripe_size=$2
10756         local stride_length=$((stripe_size / read_size))
10757         local stride_width=$((stride_length * OSTCOUNT))
10758         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10759                                 (stride_width - stride_length) ))
10760         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10761                   get_named_value 'read.but.discarded' | calc_total)
10762
10763         if [[ $discard -gt $discard_limit ]]; then
10764                 $LCTL get_param llite.*.read_ahead_stats
10765                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10766         else
10767                 echo "Read-ahead success for size ${read_size}"
10768         fi
10769 }
10770
10771 test_101b() {
10772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10774
10775         local STRIPE_SIZE=1048576
10776         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10777
10778         if [ $SLOW == "yes" ]; then
10779                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10780         else
10781                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10782         fi
10783
10784         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10785
10786         # prepare the read-ahead file
10787         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10788         cancel_lru_locks osc
10789         for BIDX in 2 4 8 16 32 64 128 256
10790         do
10791                 local BSIZE=$((BIDX*4096))
10792                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10793                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10794                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10795                 $LCTL set_param -n llite.*.read_ahead_stats=0
10796                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10797                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10798                 cancel_lru_locks osc
10799                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10800         done
10801         cleanup_test101bc
10802         true
10803 }
10804 run_test 101b "check stride-io mode read-ahead ================="
10805
10806 test_101c() {
10807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10808
10809         local STRIPE_SIZE=1048576
10810         local FILE_LENGTH=$((STRIPE_SIZE*100))
10811         local nreads=10000
10812         local rsize=65536
10813         local osc_rpc_stats
10814
10815         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10816
10817         cancel_lru_locks osc
10818         $LCTL set_param osc.*.rpc_stats=0
10819         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10820         $LCTL get_param osc.*.rpc_stats
10821         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10822                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10823                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10824                 local size
10825
10826                 if [ $lines -le 20 ]; then
10827                         echo "continue debug"
10828                         continue
10829                 fi
10830                 for size in 1 2 4 8; do
10831                         local rpc=$(echo "$stats" |
10832                                     awk '($1 == "'$size':") {print $2; exit; }')
10833                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10834                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10835                 done
10836                 echo "$osc_rpc_stats check passed!"
10837         done
10838         cleanup_test101bc
10839         true
10840 }
10841 run_test 101c "check stripe_size aligned read-ahead"
10842
10843 test_101d() {
10844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10845
10846         local file=$DIR/$tfile
10847         local sz_MB=${FILESIZE_101d:-80}
10848         local ra_MB=${READAHEAD_MB:-40}
10849
10850         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10851         [ $free_MB -lt $sz_MB ] &&
10852                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10853
10854         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10855         $LFS setstripe -c -1 $file || error "setstripe failed"
10856
10857         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10858         echo Cancel LRU locks on lustre client to flush the client cache
10859         cancel_lru_locks osc
10860
10861         echo Disable read-ahead
10862         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10863         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10864         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10865         $LCTL get_param -n llite.*.max_read_ahead_mb
10866
10867         echo "Reading the test file $file with read-ahead disabled"
10868         local sz_KB=$((sz_MB * 1024 / 4))
10869         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10870         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10871         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10872                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10873
10874         echo "Cancel LRU locks on lustre client to flush the client cache"
10875         cancel_lru_locks osc
10876         echo Enable read-ahead with ${ra_MB}MB
10877         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10878
10879         echo "Reading the test file $file with read-ahead enabled"
10880         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10881                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10882
10883         echo "read-ahead disabled time read $raOFF"
10884         echo "read-ahead enabled time read $raON"
10885
10886         rm -f $file
10887         wait_delete_completed
10888
10889         # use awk for this check instead of bash because it handles decimals
10890         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10891                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10892 }
10893 run_test 101d "file read with and without read-ahead enabled"
10894
10895 test_101e() {
10896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10897
10898         local file=$DIR/$tfile
10899         local size_KB=500  #KB
10900         local count=100
10901         local bsize=1024
10902
10903         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10904         local need_KB=$((count * size_KB))
10905         [[ $free_KB -le $need_KB ]] &&
10906                 skip_env "Need free space $need_KB, have $free_KB"
10907
10908         echo "Creating $count ${size_KB}K test files"
10909         for ((i = 0; i < $count; i++)); do
10910                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10911         done
10912
10913         echo "Cancel LRU locks on lustre client to flush the client cache"
10914         cancel_lru_locks $OSC
10915
10916         echo "Reset readahead stats"
10917         $LCTL set_param -n llite.*.read_ahead_stats=0
10918
10919         for ((i = 0; i < $count; i++)); do
10920                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10921         done
10922
10923         $LCTL get_param llite.*.max_cached_mb
10924         $LCTL get_param llite.*.read_ahead_stats
10925         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10926                      get_named_value 'misses' | calc_total)
10927
10928         for ((i = 0; i < $count; i++)); do
10929                 rm -rf $file.$i 2>/dev/null
10930         done
10931
10932         #10000 means 20% reads are missing in readahead
10933         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10934 }
10935 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10936
10937 test_101f() {
10938         which iozone || skip_env "no iozone installed"
10939
10940         local old_debug=$($LCTL get_param debug)
10941         old_debug=${old_debug#*=}
10942         $LCTL set_param debug="reada mmap"
10943
10944         # create a test file
10945         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10946
10947         echo Cancel LRU locks on lustre client to flush the client cache
10948         cancel_lru_locks osc
10949
10950         echo Reset readahead stats
10951         $LCTL set_param -n llite.*.read_ahead_stats=0
10952
10953         echo mmap read the file with small block size
10954         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10955                 > /dev/null 2>&1
10956
10957         echo checking missing pages
10958         $LCTL get_param llite.*.read_ahead_stats
10959         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10960                         get_named_value 'misses' | calc_total)
10961
10962         $LCTL set_param debug="$old_debug"
10963         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10964         rm -f $DIR/$tfile
10965 }
10966 run_test 101f "check mmap read performance"
10967
10968 test_101g_brw_size_test() {
10969         local mb=$1
10970         local pages=$((mb * 1048576 / PAGE_SIZE))
10971         local file=$DIR/$tfile
10972
10973         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10974                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10975         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10976                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10977                         return 2
10978         done
10979
10980         stack_trap "rm -f $file" EXIT
10981         $LCTL set_param -n osc.*.rpc_stats=0
10982
10983         # 10 RPCs should be enough for the test
10984         local count=10
10985         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10986                 { error "dd write ${mb} MB blocks failed"; return 3; }
10987         cancel_lru_locks osc
10988         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10989                 { error "dd write ${mb} MB blocks failed"; return 4; }
10990
10991         # calculate number of full-sized read and write RPCs
10992         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10993                 sed -n '/pages per rpc/,/^$/p' |
10994                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10995                 END { print reads,writes }'))
10996         # allow one extra full-sized read RPC for async readahead
10997         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10998                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10999         [[ ${rpcs[1]} == $count ]] ||
11000                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11001 }
11002
11003 test_101g() {
11004         remote_ost_nodsh && skip "remote OST with nodsh"
11005
11006         local rpcs
11007         local osts=$(get_facets OST)
11008         local list=$(comma_list $(osts_nodes))
11009         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11010         local brw_size="obdfilter.*.brw_size"
11011
11012         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11013
11014         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11015
11016         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11017                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11018                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11019            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11020                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11021                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11022
11023                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11024                         suffix="M"
11025
11026                 if [[ $orig_mb -lt 16 ]]; then
11027                         save_lustre_params $osts "$brw_size" > $p
11028                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11029                                 error "set 16MB RPC size failed"
11030
11031                         echo "remount client to enable new RPC size"
11032                         remount_client $MOUNT || error "remount_client failed"
11033                 fi
11034
11035                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11036                 # should be able to set brw_size=12, but no rpc_stats for that
11037                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11038         fi
11039
11040         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11041
11042         if [[ $orig_mb -lt 16 ]]; then
11043                 restore_lustre_params < $p
11044                 remount_client $MOUNT || error "remount_client restore failed"
11045         fi
11046
11047         rm -f $p $DIR/$tfile
11048 }
11049 run_test 101g "Big bulk(4/16 MiB) readahead"
11050
11051 test_101h() {
11052         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11053
11054         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11055                 error "dd 70M file failed"
11056         echo Cancel LRU locks on lustre client to flush the client cache
11057         cancel_lru_locks osc
11058
11059         echo "Reset readahead stats"
11060         $LCTL set_param -n llite.*.read_ahead_stats 0
11061
11062         echo "Read 10M of data but cross 64M bundary"
11063         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11064         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11065                      get_named_value 'misses' | calc_total)
11066         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11067         rm -f $p $DIR/$tfile
11068 }
11069 run_test 101h "Readahead should cover current read window"
11070
11071 test_101i() {
11072         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11073                 error "dd 10M file failed"
11074
11075         local max_per_file_mb=$($LCTL get_param -n \
11076                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11077         cancel_lru_locks osc
11078         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11079         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11080                 error "set max_read_ahead_per_file_mb to 1 failed"
11081
11082         echo "Reset readahead stats"
11083         $LCTL set_param llite.*.read_ahead_stats=0
11084
11085         dd if=$DIR/$tfile of=/dev/null bs=2M
11086
11087         $LCTL get_param llite.*.read_ahead_stats
11088         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11089                      awk '/misses/ { print $2 }')
11090         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11091         rm -f $DIR/$tfile
11092 }
11093 run_test 101i "allow current readahead to exceed reservation"
11094
11095 test_101j() {
11096         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11097                 error "setstripe $DIR/$tfile failed"
11098         local file_size=$((1048576 * 16))
11099         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11100         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11101
11102         echo Disable read-ahead
11103         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11104
11105         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11106         for blk in $PAGE_SIZE 1048576 $file_size; do
11107                 cancel_lru_locks osc
11108                 echo "Reset readahead stats"
11109                 $LCTL set_param -n llite.*.read_ahead_stats=0
11110                 local count=$(($file_size / $blk))
11111                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11112                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11113                              get_named_value 'failed.to.fast.read' | calc_total)
11114                 $LCTL get_param -n llite.*.read_ahead_stats
11115                 [ $miss -eq $count ] || error "expected $count got $miss"
11116         done
11117
11118         rm -f $p $DIR/$tfile
11119 }
11120 run_test 101j "A complete read block should be submitted when no RA"
11121
11122 setup_test102() {
11123         test_mkdir $DIR/$tdir
11124         chown $RUNAS_ID $DIR/$tdir
11125         STRIPE_SIZE=65536
11126         STRIPE_OFFSET=1
11127         STRIPE_COUNT=$OSTCOUNT
11128         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11129
11130         trap cleanup_test102 EXIT
11131         cd $DIR
11132         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11133         cd $DIR/$tdir
11134         for num in 1 2 3 4; do
11135                 for count in $(seq 1 $STRIPE_COUNT); do
11136                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11137                                 local size=`expr $STRIPE_SIZE \* $num`
11138                                 local file=file"$num-$idx-$count"
11139                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11140                         done
11141                 done
11142         done
11143
11144         cd $DIR
11145         $1 tar cf $TMP/f102.tar $tdir --xattrs
11146 }
11147
11148 cleanup_test102() {
11149         trap 0
11150         rm -f $TMP/f102.tar
11151         rm -rf $DIR/d0.sanity/d102
11152 }
11153
11154 test_102a() {
11155         [ "$UID" != 0 ] && skip "must run as root"
11156         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11157                 skip_env "must have user_xattr"
11158
11159         [ -z "$(which setfattr 2>/dev/null)" ] &&
11160                 skip_env "could not find setfattr"
11161
11162         local testfile=$DIR/$tfile
11163
11164         touch $testfile
11165         echo "set/get xattr..."
11166         setfattr -n trusted.name1 -v value1 $testfile ||
11167                 error "setfattr -n trusted.name1=value1 $testfile failed"
11168         getfattr -n trusted.name1 $testfile 2> /dev/null |
11169           grep "trusted.name1=.value1" ||
11170                 error "$testfile missing trusted.name1=value1"
11171
11172         setfattr -n user.author1 -v author1 $testfile ||
11173                 error "setfattr -n user.author1=author1 $testfile failed"
11174         getfattr -n user.author1 $testfile 2> /dev/null |
11175           grep "user.author1=.author1" ||
11176                 error "$testfile missing trusted.author1=author1"
11177
11178         echo "listxattr..."
11179         setfattr -n trusted.name2 -v value2 $testfile ||
11180                 error "$testfile unable to set trusted.name2"
11181         setfattr -n trusted.name3 -v value3 $testfile ||
11182                 error "$testfile unable to set trusted.name3"
11183         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11184             grep "trusted.name" | wc -l) -eq 3 ] ||
11185                 error "$testfile missing 3 trusted.name xattrs"
11186
11187         setfattr -n user.author2 -v author2 $testfile ||
11188                 error "$testfile unable to set user.author2"
11189         setfattr -n user.author3 -v author3 $testfile ||
11190                 error "$testfile unable to set user.author3"
11191         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11192             grep "user.author" | wc -l) -eq 3 ] ||
11193                 error "$testfile missing 3 user.author xattrs"
11194
11195         echo "remove xattr..."
11196         setfattr -x trusted.name1 $testfile ||
11197                 error "$testfile error deleting trusted.name1"
11198         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11199                 error "$testfile did not delete trusted.name1 xattr"
11200
11201         setfattr -x user.author1 $testfile ||
11202                 error "$testfile error deleting user.author1"
11203         echo "set lustre special xattr ..."
11204         $LFS setstripe -c1 $testfile
11205         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11206                 awk -F "=" '/trusted.lov/ { print $2 }' )
11207         setfattr -n "trusted.lov" -v $lovea $testfile ||
11208                 error "$testfile doesn't ignore setting trusted.lov again"
11209         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11210                 error "$testfile allow setting invalid trusted.lov"
11211         rm -f $testfile
11212 }
11213 run_test 102a "user xattr test =================================="
11214
11215 check_102b_layout() {
11216         local layout="$*"
11217         local testfile=$DIR/$tfile
11218
11219         echo "test layout '$layout'"
11220         $LFS setstripe $layout $testfile || error "setstripe failed"
11221         $LFS getstripe -y $testfile
11222
11223         echo "get/set/list trusted.lov xattr ..." # b=10930
11224         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11225         [[ "$value" =~ "trusted.lov" ]] ||
11226                 error "can't get trusted.lov from $testfile"
11227         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11228                 error "getstripe failed"
11229
11230         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11231
11232         value=$(cut -d= -f2 <<<$value)
11233         # LU-13168: truncated xattr should fail if short lov_user_md header
11234         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11235                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11236         for len in $lens; do
11237                 echo "setfattr $len $testfile.2"
11238                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11239                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11240         done
11241         local stripe_size=$($LFS getstripe -S $testfile.2)
11242         local stripe_count=$($LFS getstripe -c $testfile.2)
11243         [[ $stripe_size -eq 65536 ]] ||
11244                 error "stripe size $stripe_size != 65536"
11245         [[ $stripe_count -eq $stripe_count_orig ]] ||
11246                 error "stripe count $stripe_count != $stripe_count_orig"
11247         rm $testfile $testfile.2
11248 }
11249
11250 test_102b() {
11251         [ -z "$(which setfattr 2>/dev/null)" ] &&
11252                 skip_env "could not find setfattr"
11253         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11254
11255         # check plain layout
11256         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11257
11258         # and also check composite layout
11259         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11260
11261 }
11262 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11263
11264 test_102c() {
11265         [ -z "$(which setfattr 2>/dev/null)" ] &&
11266                 skip_env "could not find setfattr"
11267         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11268
11269         # b10930: get/set/list lustre.lov xattr
11270         echo "get/set/list lustre.lov xattr ..."
11271         test_mkdir $DIR/$tdir
11272         chown $RUNAS_ID $DIR/$tdir
11273         local testfile=$DIR/$tdir/$tfile
11274         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11275                 error "setstripe failed"
11276         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11277                 error "getstripe failed"
11278         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11279         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11280
11281         local testfile2=${testfile}2
11282         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11283                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11284
11285         $RUNAS $MCREATE $testfile2
11286         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11287         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11288         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11289         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11290         [ $stripe_count -eq $STRIPECOUNT ] ||
11291                 error "stripe count $stripe_count != $STRIPECOUNT"
11292 }
11293 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11294
11295 compare_stripe_info1() {
11296         local stripe_index_all_zero=true
11297
11298         for num in 1 2 3 4; do
11299                 for count in $(seq 1 $STRIPE_COUNT); do
11300                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11301                                 local size=$((STRIPE_SIZE * num))
11302                                 local file=file"$num-$offset-$count"
11303                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11304                                 [[ $stripe_size -ne $size ]] &&
11305                                     error "$file: size $stripe_size != $size"
11306                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11307                                 # allow fewer stripes to be created, ORI-601
11308                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11309                                     error "$file: count $stripe_count != $count"
11310                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11311                                 [[ $stripe_index -ne 0 ]] &&
11312                                         stripe_index_all_zero=false
11313                         done
11314                 done
11315         done
11316         $stripe_index_all_zero &&
11317                 error "all files are being extracted starting from OST index 0"
11318         return 0
11319 }
11320
11321 have_xattrs_include() {
11322         tar --help | grep -q xattrs-include &&
11323                 echo --xattrs-include="lustre.*"
11324 }
11325
11326 test_102d() {
11327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11328         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11329
11330         XINC=$(have_xattrs_include)
11331         setup_test102
11332         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11333         cd $DIR/$tdir/$tdir
11334         compare_stripe_info1
11335 }
11336 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11337
11338 test_102f() {
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11341
11342         XINC=$(have_xattrs_include)
11343         setup_test102
11344         test_mkdir $DIR/$tdir.restore
11345         cd $DIR
11346         tar cf - --xattrs $tdir | tar xf - \
11347                 -C $DIR/$tdir.restore --xattrs $XINC
11348         cd $DIR/$tdir.restore/$tdir
11349         compare_stripe_info1
11350 }
11351 run_test 102f "tar copy files, not keep osts"
11352
11353 grow_xattr() {
11354         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11355                 skip "must have user_xattr"
11356         [ -z "$(which setfattr 2>/dev/null)" ] &&
11357                 skip_env "could not find setfattr"
11358         [ -z "$(which getfattr 2>/dev/null)" ] &&
11359                 skip_env "could not find getfattr"
11360
11361         local xsize=${1:-1024}  # in bytes
11362         local file=$DIR/$tfile
11363         local value="$(generate_string $xsize)"
11364         local xbig=trusted.big
11365         local toobig=$2
11366
11367         touch $file
11368         log "save $xbig on $file"
11369         if [ -z "$toobig" ]
11370         then
11371                 setfattr -n $xbig -v $value $file ||
11372                         error "saving $xbig on $file failed"
11373         else
11374                 setfattr -n $xbig -v $value $file &&
11375                         error "saving $xbig on $file succeeded"
11376                 return 0
11377         fi
11378
11379         local orig=$(get_xattr_value $xbig $file)
11380         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11381
11382         local xsml=trusted.sml
11383         log "save $xsml on $file"
11384         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11385
11386         local new=$(get_xattr_value $xbig $file)
11387         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11388
11389         log "grow $xsml on $file"
11390         setfattr -n $xsml -v "$value" $file ||
11391                 error "growing $xsml on $file failed"
11392
11393         new=$(get_xattr_value $xbig $file)
11394         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11395         log "$xbig still valid after growing $xsml"
11396
11397         rm -f $file
11398 }
11399
11400 test_102h() { # bug 15777
11401         grow_xattr 1024
11402 }
11403 run_test 102h "grow xattr from inside inode to external block"
11404
11405 test_102ha() {
11406         large_xattr_enabled || skip_env "ea_inode feature disabled"
11407
11408         echo "setting xattr of max xattr size: $(max_xattr_size)"
11409         grow_xattr $(max_xattr_size)
11410
11411         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11412         echo "This should fail:"
11413         grow_xattr $(($(max_xattr_size) + 10)) 1
11414 }
11415 run_test 102ha "grow xattr from inside inode to external inode"
11416
11417 test_102i() { # bug 17038
11418         [ -z "$(which getfattr 2>/dev/null)" ] &&
11419                 skip "could not find getfattr"
11420
11421         touch $DIR/$tfile
11422         ln -s $DIR/$tfile $DIR/${tfile}link
11423         getfattr -n trusted.lov $DIR/$tfile ||
11424                 error "lgetxattr on $DIR/$tfile failed"
11425         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11426                 grep -i "no such attr" ||
11427                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11428         rm -f $DIR/$tfile $DIR/${tfile}link
11429 }
11430 run_test 102i "lgetxattr test on symbolic link ============"
11431
11432 test_102j() {
11433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11434         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11435
11436         XINC=$(have_xattrs_include)
11437         setup_test102 "$RUNAS"
11438         chown $RUNAS_ID $DIR/$tdir
11439         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11440         cd $DIR/$tdir/$tdir
11441         compare_stripe_info1 "$RUNAS"
11442 }
11443 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11444
11445 test_102k() {
11446         [ -z "$(which setfattr 2>/dev/null)" ] &&
11447                 skip "could not find setfattr"
11448
11449         touch $DIR/$tfile
11450         # b22187 just check that does not crash for regular file.
11451         setfattr -n trusted.lov $DIR/$tfile
11452         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11453         local test_kdir=$DIR/$tdir
11454         test_mkdir $test_kdir
11455         local default_size=$($LFS getstripe -S $test_kdir)
11456         local default_count=$($LFS getstripe -c $test_kdir)
11457         local default_offset=$($LFS getstripe -i $test_kdir)
11458         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11459                 error 'dir setstripe failed'
11460         setfattr -n trusted.lov $test_kdir
11461         local stripe_size=$($LFS getstripe -S $test_kdir)
11462         local stripe_count=$($LFS getstripe -c $test_kdir)
11463         local stripe_offset=$($LFS getstripe -i $test_kdir)
11464         [ $stripe_size -eq $default_size ] ||
11465                 error "stripe size $stripe_size != $default_size"
11466         [ $stripe_count -eq $default_count ] ||
11467                 error "stripe count $stripe_count != $default_count"
11468         [ $stripe_offset -eq $default_offset ] ||
11469                 error "stripe offset $stripe_offset != $default_offset"
11470         rm -rf $DIR/$tfile $test_kdir
11471 }
11472 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11473
11474 test_102l() {
11475         [ -z "$(which getfattr 2>/dev/null)" ] &&
11476                 skip "could not find getfattr"
11477
11478         # LU-532 trusted. xattr is invisible to non-root
11479         local testfile=$DIR/$tfile
11480
11481         touch $testfile
11482
11483         echo "listxattr as user..."
11484         chown $RUNAS_ID $testfile
11485         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11486             grep -q "trusted" &&
11487                 error "$testfile trusted xattrs are user visible"
11488
11489         return 0;
11490 }
11491 run_test 102l "listxattr size test =================================="
11492
11493 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11494         local path=$DIR/$tfile
11495         touch $path
11496
11497         listxattr_size_check $path || error "listattr_size_check $path failed"
11498 }
11499 run_test 102m "Ensure listxattr fails on small bufffer ========"
11500
11501 cleanup_test102
11502
11503 getxattr() { # getxattr path name
11504         # Return the base64 encoding of the value of xattr name on path.
11505         local path=$1
11506         local name=$2
11507
11508         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11509         # file: $path
11510         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11511         #
11512         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11513
11514         getfattr --absolute-names --encoding=base64 --name=$name $path |
11515                 awk -F= -v name=$name '$1 == name {
11516                         print substr($0, index($0, "=") + 1);
11517         }'
11518 }
11519
11520 test_102n() { # LU-4101 mdt: protect internal xattrs
11521         [ -z "$(which setfattr 2>/dev/null)" ] &&
11522                 skip "could not find setfattr"
11523         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11524         then
11525                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11526         fi
11527
11528         local file0=$DIR/$tfile.0
11529         local file1=$DIR/$tfile.1
11530         local xattr0=$TMP/$tfile.0
11531         local xattr1=$TMP/$tfile.1
11532         local namelist="lov lma lmv link fid version som hsm"
11533         local name
11534         local value
11535
11536         rm -rf $file0 $file1 $xattr0 $xattr1
11537         touch $file0 $file1
11538
11539         # Get 'before' xattrs of $file1.
11540         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11541
11542         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11543                 namelist+=" lfsck_namespace"
11544         for name in $namelist; do
11545                 # Try to copy xattr from $file0 to $file1.
11546                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11547
11548                 setfattr --name=trusted.$name --value="$value" $file1 ||
11549                         error "setxattr 'trusted.$name' failed"
11550
11551                 # Try to set a garbage xattr.
11552                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11553
11554                 if [[ x$name == "xlov" ]]; then
11555                         setfattr --name=trusted.lov --value="$value" $file1 &&
11556                         error "setxattr invalid 'trusted.lov' success"
11557                 else
11558                         setfattr --name=trusted.$name --value="$value" $file1 ||
11559                                 error "setxattr invalid 'trusted.$name' failed"
11560                 fi
11561
11562                 # Try to remove the xattr from $file1. We don't care if this
11563                 # appears to succeed or fail, we just don't want there to be
11564                 # any changes or crashes.
11565                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11566         done
11567
11568         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11569         then
11570                 name="lfsck_ns"
11571                 # Try to copy xattr from $file0 to $file1.
11572                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11573
11574                 setfattr --name=trusted.$name --value="$value" $file1 ||
11575                         error "setxattr 'trusted.$name' failed"
11576
11577                 # Try to set a garbage xattr.
11578                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11579
11580                 setfattr --name=trusted.$name --value="$value" $file1 ||
11581                         error "setxattr 'trusted.$name' failed"
11582
11583                 # Try to remove the xattr from $file1. We don't care if this
11584                 # appears to succeed or fail, we just don't want there to be
11585                 # any changes or crashes.
11586                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11587         fi
11588
11589         # Get 'after' xattrs of file1.
11590         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11591
11592         if ! diff $xattr0 $xattr1; then
11593                 error "before and after xattrs of '$file1' differ"
11594         fi
11595
11596         rm -rf $file0 $file1 $xattr0 $xattr1
11597
11598         return 0
11599 }
11600 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11601
11602 test_102p() { # LU-4703 setxattr did not check ownership
11603         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11604                 skip "MDS needs to be at least 2.5.56"
11605
11606         local testfile=$DIR/$tfile
11607
11608         touch $testfile
11609
11610         echo "setfacl as user..."
11611         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11612         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11613
11614         echo "setfattr as user..."
11615         setfacl -m "u:$RUNAS_ID:---" $testfile
11616         $RUNAS setfattr -x system.posix_acl_access $testfile
11617         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11618 }
11619 run_test 102p "check setxattr(2) correctly fails without permission"
11620
11621 test_102q() {
11622         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11623                 skip "MDS needs to be at least 2.6.92"
11624
11625         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11626 }
11627 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11628
11629 test_102r() {
11630         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11631                 skip "MDS needs to be at least 2.6.93"
11632
11633         touch $DIR/$tfile || error "touch"
11634         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11635         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11636         rm $DIR/$tfile || error "rm"
11637
11638         #normal directory
11639         mkdir -p $DIR/$tdir || error "mkdir"
11640         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11641         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11642         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11643                 error "$testfile error deleting user.author1"
11644         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11645                 grep "user.$(basename $tdir)" &&
11646                 error "$tdir did not delete user.$(basename $tdir)"
11647         rmdir $DIR/$tdir || error "rmdir"
11648
11649         #striped directory
11650         test_mkdir $DIR/$tdir
11651         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11652         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11653         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11654                 error "$testfile error deleting user.author1"
11655         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11656                 grep "user.$(basename $tdir)" &&
11657                 error "$tdir did not delete user.$(basename $tdir)"
11658         rmdir $DIR/$tdir || error "rm striped dir"
11659 }
11660 run_test 102r "set EAs with empty values"
11661
11662 test_102s() {
11663         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11664                 skip "MDS needs to be at least 2.11.52"
11665
11666         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11667
11668         save_lustre_params client "llite.*.xattr_cache" > $save
11669
11670         for cache in 0 1; do
11671                 lctl set_param llite.*.xattr_cache=$cache
11672
11673                 rm -f $DIR/$tfile
11674                 touch $DIR/$tfile || error "touch"
11675                 for prefix in lustre security system trusted user; do
11676                         # Note getxattr() may fail with 'Operation not
11677                         # supported' or 'No such attribute' depending
11678                         # on prefix and cache.
11679                         getfattr -n $prefix.n102s $DIR/$tfile &&
11680                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11681                 done
11682         done
11683
11684         restore_lustre_params < $save
11685 }
11686 run_test 102s "getting nonexistent xattrs should fail"
11687
11688 test_102t() {
11689         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11690                 skip "MDS needs to be at least 2.11.52"
11691
11692         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11693
11694         save_lustre_params client "llite.*.xattr_cache" > $save
11695
11696         for cache in 0 1; do
11697                 lctl set_param llite.*.xattr_cache=$cache
11698
11699                 for buf_size in 0 256; do
11700                         rm -f $DIR/$tfile
11701                         touch $DIR/$tfile || error "touch"
11702                         setfattr -n user.multiop $DIR/$tfile
11703                         $MULTIOP $DIR/$tfile oa$buf_size ||
11704                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11705                 done
11706         done
11707
11708         restore_lustre_params < $save
11709 }
11710 run_test 102t "zero length xattr values handled correctly"
11711
11712 run_acl_subtest()
11713 {
11714         local test=$LUSTRE/tests/acl/$1.test
11715         local tmp=$(mktemp -t $1-XXXXXX).test
11716         local bin=$2
11717         local dmn=$3
11718         local grp=$4
11719         local nbd=$5
11720         export LANG=C
11721
11722
11723         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11724         local sedgroups="-e s/:users/:$grp/g"
11725         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11726
11727         sed $sedusers $sedgroups < $test > $tmp
11728         stack_trap "rm -f $tmp"
11729         [[ -s $tmp ]] || error "sed failed to create test script"
11730
11731         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11732         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11733 }
11734
11735 test_103a() {
11736         [ "$UID" != 0 ] && skip "must run as root"
11737         $GSS && skip_env "could not run under gss"
11738         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11739                 skip_env "must have acl enabled"
11740         which setfacl || skip_env "could not find setfacl"
11741         remote_mds_nodsh && skip "remote MDS with nodsh"
11742
11743         ACLBIN=${ACLBIN:-"bin"}
11744         ACLDMN=${ACLDMN:-"daemon"}
11745         ACLGRP=${ACLGRP:-"users"}
11746         ACLNBD=${ACLNBD:-"nobody"}
11747
11748         if ! id $ACLBIN ||
11749            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11750                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11751                 ACLBIN=$USER0
11752                 if ! id $ACLBIN ; then
11753                         cat /etc/passwd
11754                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11755                 fi
11756         fi
11757         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11758            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11759                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11760                 ACLDMN=$USER1
11761                 if ! id $ACLDMN ; then
11762                         cat /etc/passwd
11763                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11764                 fi
11765         fi
11766         if ! getent group $ACLGRP; then
11767                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11768                 ACLGRP="$TSTUSR"
11769                 if ! getent group $ACLGRP; then
11770                         echo "cannot find group '$ACLGRP', adding it"
11771                         cat /etc/group
11772                         add_group 60000 $ACLGRP
11773                 fi
11774         fi
11775
11776         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11777         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11778         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11779
11780         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11781                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11782                 ACLGRP="$TSTUSR"
11783                 if ! getent group $ACLGRP; then
11784                         echo "cannot find group '$ACLGRP', adding it"
11785                         cat /etc/group
11786                         add_group 60000 $ACLGRP
11787                 fi
11788                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11789                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11790                         cat /etc/group
11791                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11792                 fi
11793         fi
11794
11795         gpasswd -a $ACLDMN $ACLBIN ||
11796                 error "setting client group failed"             # LU-5641
11797         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11798                 error "setting MDS group failed"                # LU-5641
11799
11800         declare -a identity_old
11801
11802         for num in $(seq $MDSCOUNT); do
11803                 switch_identity $num true || identity_old[$num]=$?
11804         done
11805
11806         SAVE_UMASK=$(umask)
11807         umask 0022
11808         mkdir -p $DIR/$tdir
11809         cd $DIR/$tdir
11810
11811         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11812         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11813         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11814         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11815         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11816         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11817         if ! id -u $ACLNBD ||
11818            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11819                 ACLNBD="nfsnobody"
11820                 if ! id -u $ACLNBD; then
11821                         ACLNBD=""
11822                 fi
11823         fi
11824         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11825                 add_group $(id -u $ACLNBD) $ACLNBD
11826                 if ! getent group $ACLNBD; then
11827                         ACLNBD=""
11828                 fi
11829         fi
11830         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11831            [[ -n "$ACLNBD" ]] && which setfattr; then
11832                 run_acl_subtest permissions_xattr \
11833                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11834         elif [[ -z "$ACLNBD" ]]; then
11835                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11836         else
11837                 echo "skip 'permission_xattr' test - missing setfattr command"
11838         fi
11839         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11840
11841         # inheritance test got from HP
11842         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11843         chmod +x make-tree || error "chmod +x failed"
11844         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11845         rm -f make-tree
11846
11847         echo "LU-974 ignore umask when acl is enabled..."
11848         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11849         if [ $MDSCOUNT -ge 2 ]; then
11850                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11851         fi
11852
11853         echo "LU-2561 newly created file is same size as directory..."
11854         if [ "$mds1_FSTYPE" != "zfs" ]; then
11855                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11856         else
11857                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11858         fi
11859
11860         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11861
11862         cd $SAVE_PWD
11863         umask $SAVE_UMASK
11864
11865         for num in $(seq $MDSCOUNT); do
11866                 if [ "${identity_old[$num]}" = 1 ]; then
11867                         switch_identity $num false || identity_old[$num]=$?
11868                 fi
11869         done
11870 }
11871 run_test 103a "acl test"
11872
11873 test_103b() {
11874         declare -a pids
11875         local U
11876
11877         for U in {0..511}; do
11878                 {
11879                 local O=$(printf "%04o" $U)
11880
11881                 umask $(printf "%04o" $((511 ^ $O)))
11882                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11883                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11884
11885                 (( $S == ($O & 0666) )) ||
11886                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11887
11888                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11889                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11890                 (( $S == ($O & 0666) )) ||
11891                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11892
11893                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11894                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11895                 (( $S == ($O & 0666) )) ||
11896                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11897                 rm -f $DIR/$tfile.[smp]$0
11898                 } &
11899                 local pid=$!
11900
11901                 # limit the concurrently running threads to 64. LU-11878
11902                 local idx=$((U % 64))
11903                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11904                 pids[idx]=$pid
11905         done
11906         wait
11907 }
11908 run_test 103b "umask lfs setstripe"
11909
11910 test_103c() {
11911         mkdir -p $DIR/$tdir
11912         cp -rp $DIR/$tdir $DIR/$tdir.bak
11913
11914         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11915                 error "$DIR/$tdir shouldn't contain default ACL"
11916         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11917                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11918         true
11919 }
11920 run_test 103c "'cp -rp' won't set empty acl"
11921
11922 test_103e() {
11923         local numacl
11924         local fileacl
11925         local saved_debug=$($LCTL get_param -n debug)
11926
11927         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11928                 skip "MDS needs to be at least 2.14.52"
11929
11930         large_xattr_enabled || skip_env "ea_inode feature disabled"
11931
11932         mkdir -p $DIR/$tdir
11933         # add big LOV EA to cause reply buffer overflow earlier
11934         $LFS setstripe -C 1000 $DIR/$tdir
11935         lctl set_param mdc.*-mdc*.stats=clear
11936
11937         $LCTL set_param debug=0
11938         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11939         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11940
11941         # add a large number of default ACLs (expect 8000+ for 2.13+)
11942         for U in {2..7000}; do
11943                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11944                         error "Able to add just $U default ACLs"
11945         done
11946         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11947         echo "$numacl default ACLs created"
11948
11949         stat $DIR/$tdir || error "Cannot stat directory"
11950         # check file creation
11951         touch $DIR/$tdir/$tfile ||
11952                 error "failed to create $tfile with $numacl default ACLs"
11953         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11954         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11955         echo "$fileacl ACLs were inherited"
11956         (( $fileacl == $numacl )) ||
11957                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11958         # check that new ACLs creation adds new ACLs to inherited ACLs
11959         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11960                 error "Cannot set new ACL"
11961         numacl=$((numacl + 1))
11962         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11963         (( $fileacl == $numacl )) ||
11964                 error "failed to add new ACL: $fileacl != $numacl as expected"
11965         # adds more ACLs to a file to reach their maximum at 8000+
11966         numacl=0
11967         for U in {20000..25000}; do
11968                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11969                 numacl=$((numacl + 1))
11970         done
11971         echo "Added $numacl more ACLs to the file"
11972         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11973         echo "Total $fileacl ACLs in file"
11974         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11975         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11976         rmdir $DIR/$tdir || error "Cannot remove directory"
11977 }
11978 run_test 103e "inheritance of big amount of default ACLs"
11979
11980 test_103f() {
11981         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11982                 skip "MDS needs to be at least 2.14.51"
11983
11984         large_xattr_enabled || skip_env "ea_inode feature disabled"
11985
11986         # enable changelog to consume more internal MDD buffers
11987         changelog_register
11988
11989         mkdir -p $DIR/$tdir
11990         # add big LOV EA
11991         $LFS setstripe -C 1000 $DIR/$tdir
11992         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11993         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11994         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11995         rmdir $DIR/$tdir || error "Cannot remove directory"
11996 }
11997 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11998
11999 test_104a() {
12000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12001
12002         touch $DIR/$tfile
12003         lfs df || error "lfs df failed"
12004         lfs df -ih || error "lfs df -ih failed"
12005         lfs df -h $DIR || error "lfs df -h $DIR failed"
12006         lfs df -i $DIR || error "lfs df -i $DIR failed"
12007         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12008         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12009
12010         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12011         lctl --device %$OSC deactivate
12012         lfs df || error "lfs df with deactivated OSC failed"
12013         lctl --device %$OSC activate
12014         # wait the osc back to normal
12015         wait_osc_import_ready client ost
12016
12017         lfs df || error "lfs df with reactivated OSC failed"
12018         rm -f $DIR/$tfile
12019 }
12020 run_test 104a "lfs df [-ih] [path] test ========================="
12021
12022 test_104b() {
12023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12024         [ $RUNAS_ID -eq $UID ] &&
12025                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12026
12027         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12028                         grep "Permission denied" | wc -l)))
12029         if [ $denied_cnt -ne 0 ]; then
12030                 error "lfs check servers test failed"
12031         fi
12032 }
12033 run_test 104b "$RUNAS lfs check servers test ===================="
12034
12035 #
12036 # Verify $1 is within range of $2.
12037 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12038 # $1 is <= 2% of $2. Else Fail.
12039 #
12040 value_in_range() {
12041         # Strip all units (M, G, T)
12042         actual=$(echo $1 | tr -d A-Z)
12043         expect=$(echo $2 | tr -d A-Z)
12044
12045         expect_lo=$(($expect * 98 / 100)) # 2% below
12046         expect_hi=$(($expect * 102 / 100)) # 2% above
12047
12048         # permit 2% drift above and below
12049         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12050 }
12051
12052 test_104c() {
12053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12054         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12055
12056         local ost_param="osd-zfs.$FSNAME-OST0000."
12057         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12058         local ofacets=$(get_facets OST)
12059         local mfacets=$(get_facets MDS)
12060         local saved_ost_blocks=
12061         local saved_mdt_blocks=
12062
12063         echo "Before recordsize change"
12064         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12065         df=($(df -h | grep "$MOUNT"$))
12066
12067         # For checking.
12068         echo "lfs output : ${lfs_df[*]}"
12069         echo "df  output : ${df[*]}"
12070
12071         for facet in ${ofacets//,/ }; do
12072                 if [ -z $saved_ost_blocks ]; then
12073                         saved_ost_blocks=$(do_facet $facet \
12074                                 lctl get_param -n $ost_param.blocksize)
12075                         echo "OST Blocksize: $saved_ost_blocks"
12076                 fi
12077                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12078                 do_facet $facet zfs set recordsize=32768 $ost
12079         done
12080
12081         # BS too small. Sufficient for functional testing.
12082         for facet in ${mfacets//,/ }; do
12083                 if [ -z $saved_mdt_blocks ]; then
12084                         saved_mdt_blocks=$(do_facet $facet \
12085                                 lctl get_param -n $mdt_param.blocksize)
12086                         echo "MDT Blocksize: $saved_mdt_blocks"
12087                 fi
12088                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12089                 do_facet $facet zfs set recordsize=32768 $mdt
12090         done
12091
12092         # Give new values chance to reflect change
12093         sleep 2
12094
12095         echo "After recordsize change"
12096         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12097         df_after=($(df -h | grep "$MOUNT"$))
12098
12099         # For checking.
12100         echo "lfs output : ${lfs_df_after[*]}"
12101         echo "df  output : ${df_after[*]}"
12102
12103         # Verify lfs df
12104         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12105                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12106         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12107                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12108         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12109                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12110
12111         # Verify df
12112         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12113                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12114         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12115                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12116         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12117                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12118
12119         # Restore MDT recordize back to original
12120         for facet in ${mfacets//,/ }; do
12121                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12122                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12123         done
12124
12125         # Restore OST recordize back to original
12126         for facet in ${ofacets//,/ }; do
12127                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12128                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12129         done
12130
12131         return 0
12132 }
12133 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12134
12135 test_104d() {
12136         (( $RUNAS_ID != $UID )) ||
12137                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12138
12139         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12140                 skip "lustre version doesn't support lctl dl with non-root"
12141
12142         # debugfs only allows root users to access files, so the
12143         # previous move of the "devices" file to debugfs broke
12144         # "lctl dl" for non-root users. The LU-9680 Netlink
12145         # interface again allows non-root users to list devices.
12146         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12147                 error "lctl dl doesn't work for non root"
12148
12149         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12150         [ "$ost_count" -eq $OSTCOUNT ]  ||
12151                 error "lctl dl reports wrong number of OST devices"
12152
12153         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12154         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12155                 error "lctl dl reports wrong number of MDT devices"
12156 }
12157 run_test 104d "$RUNAS lctl dl test"
12158
12159 test_105a() {
12160         # doesn't work on 2.4 kernels
12161         touch $DIR/$tfile
12162         if $(flock_is_enabled); then
12163                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12164         else
12165                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12166         fi
12167         rm -f $DIR/$tfile
12168 }
12169 run_test 105a "flock when mounted without -o flock test ========"
12170
12171 test_105b() {
12172         touch $DIR/$tfile
12173         if $(flock_is_enabled); then
12174                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12175         else
12176                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12177         fi
12178         rm -f $DIR/$tfile
12179 }
12180 run_test 105b "fcntl when mounted without -o flock test ========"
12181
12182 test_105c() {
12183         touch $DIR/$tfile
12184         if $(flock_is_enabled); then
12185                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12186         else
12187                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12188         fi
12189         rm -f $DIR/$tfile
12190 }
12191 run_test 105c "lockf when mounted without -o flock test"
12192
12193 test_105d() { # bug 15924
12194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12195
12196         test_mkdir $DIR/$tdir
12197         flock_is_enabled || skip_env "mount w/o flock enabled"
12198         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12199         $LCTL set_param fail_loc=0x80000315
12200         flocks_test 2 $DIR/$tdir
12201 }
12202 run_test 105d "flock race (should not freeze) ========"
12203
12204 test_105e() { # bug 22660 && 22040
12205         flock_is_enabled || skip_env "mount w/o flock enabled"
12206
12207         touch $DIR/$tfile
12208         flocks_test 3 $DIR/$tfile
12209 }
12210 run_test 105e "Two conflicting flocks from same process"
12211
12212 test_106() { #bug 10921
12213         test_mkdir $DIR/$tdir
12214         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12215         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12216 }
12217 run_test 106 "attempt exec of dir followed by chown of that dir"
12218
12219 test_107() {
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221
12222         CDIR=`pwd`
12223         local file=core
12224
12225         cd $DIR
12226         rm -f $file
12227
12228         local save_pattern=$(sysctl -n kernel.core_pattern)
12229         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12230         sysctl -w kernel.core_pattern=$file
12231         sysctl -w kernel.core_uses_pid=0
12232
12233         ulimit -c unlimited
12234         sleep 60 &
12235         SLEEPPID=$!
12236
12237         sleep 1
12238
12239         kill -s 11 $SLEEPPID
12240         wait $SLEEPPID
12241         if [ -e $file ]; then
12242                 size=`stat -c%s $file`
12243                 [ $size -eq 0 ] && error "Fail to create core file $file"
12244         else
12245                 error "Fail to create core file $file"
12246         fi
12247         rm -f $file
12248         sysctl -w kernel.core_pattern=$save_pattern
12249         sysctl -w kernel.core_uses_pid=$save_uses_pid
12250         cd $CDIR
12251 }
12252 run_test 107 "Coredump on SIG"
12253
12254 test_110() {
12255         test_mkdir $DIR/$tdir
12256         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12257         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12258                 error "mkdir with 256 char should fail, but did not"
12259         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12260                 error "create with 255 char failed"
12261         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12262                 error "create with 256 char should fail, but did not"
12263
12264         ls -l $DIR/$tdir
12265         rm -rf $DIR/$tdir
12266 }
12267 run_test 110 "filename length checking"
12268
12269 test_116a() { # was previously test_116()
12270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12271         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12272         remote_mds_nodsh && skip "remote MDS with nodsh"
12273
12274         echo -n "Free space priority "
12275         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12276                 head -n1
12277         declare -a AVAIL
12278         free_min_max
12279
12280         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12281         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12282         stack_trap simple_cleanup_common
12283
12284         # Check if we need to generate uneven OSTs
12285         test_mkdir -p $DIR/$tdir/OST${MINI}
12286         local FILL=$((MINV / 4))
12287         local DIFF=$((MAXV - MINV))
12288         local DIFF2=$((DIFF * 100 / MINV))
12289
12290         local threshold=$(do_facet $SINGLEMDS \
12291                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12292         threshold=${threshold%%%}
12293         echo -n "Check for uneven OSTs: "
12294         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12295
12296         if [[ $DIFF2 -gt $threshold ]]; then
12297                 echo "ok"
12298                 echo "Don't need to fill OST$MINI"
12299         else
12300                 # generate uneven OSTs. Write 2% over the QOS threshold value
12301                 echo "no"
12302                 DIFF=$((threshold - DIFF2 + 2))
12303                 DIFF2=$((MINV * DIFF / 100))
12304                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12305                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12306                         error "setstripe failed"
12307                 DIFF=$((DIFF2 / 2048))
12308                 i=0
12309                 while [ $i -lt $DIFF ]; do
12310                         i=$((i + 1))
12311                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12312                                 bs=2M count=1 2>/dev/null
12313                         echo -n .
12314                 done
12315                 echo .
12316                 sync
12317                 sleep_maxage
12318                 free_min_max
12319         fi
12320
12321         DIFF=$((MAXV - MINV))
12322         DIFF2=$((DIFF * 100 / MINV))
12323         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12324         if [ $DIFF2 -gt $threshold ]; then
12325                 echo "ok"
12326         else
12327                 skip "QOS imbalance criteria not met"
12328         fi
12329
12330         MINI1=$MINI
12331         MINV1=$MINV
12332         MAXI1=$MAXI
12333         MAXV1=$MAXV
12334
12335         # now fill using QOS
12336         $LFS setstripe -c 1 $DIR/$tdir
12337         FILL=$((FILL / 200))
12338         if [ $FILL -gt 600 ]; then
12339                 FILL=600
12340         fi
12341         echo "writing $FILL files to QOS-assigned OSTs"
12342         i=0
12343         while [ $i -lt $FILL ]; do
12344                 i=$((i + 1))
12345                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12346                         count=1 2>/dev/null
12347                 echo -n .
12348         done
12349         echo "wrote $i 200k files"
12350         sync
12351         sleep_maxage
12352
12353         echo "Note: free space may not be updated, so measurements might be off"
12354         free_min_max
12355         DIFF2=$((MAXV - MINV))
12356         echo "free space delta: orig $DIFF final $DIFF2"
12357         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12358         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12359         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12360         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12361         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12362         if [[ $DIFF -gt 0 ]]; then
12363                 FILL=$((DIFF2 * 100 / DIFF - 100))
12364                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12365         fi
12366
12367         # Figure out which files were written where
12368         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12369                awk '/'$MINI1': / {print $2; exit}')
12370         echo $UUID
12371         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12372         echo "$MINC files created on smaller OST $MINI1"
12373         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12374                awk '/'$MAXI1': / {print $2; exit}')
12375         echo $UUID
12376         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12377         echo "$MAXC files created on larger OST $MAXI1"
12378         if [[ $MINC -gt 0 ]]; then
12379                 FILL=$((MAXC * 100 / MINC - 100))
12380                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12381         fi
12382         [[ $MAXC -gt $MINC ]] ||
12383                 error_ignore LU-9 "stripe QOS didn't balance free space"
12384 }
12385 run_test 116a "stripe QOS: free space balance ==================="
12386
12387 test_116b() { # LU-2093
12388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12389         remote_mds_nodsh && skip "remote MDS with nodsh"
12390
12391 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12392         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12393                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12394         [ -z "$old_rr" ] && skip "no QOS"
12395         do_facet $SINGLEMDS lctl set_param \
12396                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12397         mkdir -p $DIR/$tdir
12398         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12399         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12400         do_facet $SINGLEMDS lctl set_param fail_loc=0
12401         rm -rf $DIR/$tdir
12402         do_facet $SINGLEMDS lctl set_param \
12403                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12404 }
12405 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12406
12407 test_117() # bug 10891
12408 {
12409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12410
12411         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12412         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12413         lctl set_param fail_loc=0x21e
12414         > $DIR/$tfile || error "truncate failed"
12415         lctl set_param fail_loc=0
12416         echo "Truncate succeeded."
12417         rm -f $DIR/$tfile
12418 }
12419 run_test 117 "verify osd extend =========="
12420
12421 NO_SLOW_RESENDCOUNT=4
12422 export OLD_RESENDCOUNT=""
12423 set_resend_count () {
12424         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12425         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12426         lctl set_param -n $PROC_RESENDCOUNT $1
12427         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12428 }
12429
12430 # for reduce test_118* time (b=14842)
12431 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12432
12433 # Reset async IO behavior after error case
12434 reset_async() {
12435         FILE=$DIR/reset_async
12436
12437         # Ensure all OSCs are cleared
12438         $LFS setstripe -c -1 $FILE
12439         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12440         sync
12441         rm $FILE
12442 }
12443
12444 test_118a() #bug 11710
12445 {
12446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12447
12448         reset_async
12449
12450         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12451         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12452         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12453
12454         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12455                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12456                 return 1;
12457         fi
12458         rm -f $DIR/$tfile
12459 }
12460 run_test 118a "verify O_SYNC works =========="
12461
12462 test_118b()
12463 {
12464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12465         remote_ost_nodsh && skip "remote OST with nodsh"
12466
12467         reset_async
12468
12469         #define OBD_FAIL_SRV_ENOENT 0x217
12470         set_nodes_failloc "$(osts_nodes)" 0x217
12471         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12472         RC=$?
12473         set_nodes_failloc "$(osts_nodes)" 0
12474         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12475         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12476                     grep -c writeback)
12477
12478         if [[ $RC -eq 0 ]]; then
12479                 error "Must return error due to dropped pages, rc=$RC"
12480                 return 1;
12481         fi
12482
12483         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12484                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12485                 return 1;
12486         fi
12487
12488         echo "Dirty pages not leaked on ENOENT"
12489
12490         # Due to the above error the OSC will issue all RPCs syncronously
12491         # until a subsequent RPC completes successfully without error.
12492         $MULTIOP $DIR/$tfile Ow4096yc
12493         rm -f $DIR/$tfile
12494
12495         return 0
12496 }
12497 run_test 118b "Reclaim dirty pages on fatal error =========="
12498
12499 test_118c()
12500 {
12501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12502
12503         # for 118c, restore the original resend count, LU-1940
12504         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12505                                 set_resend_count $OLD_RESENDCOUNT
12506         remote_ost_nodsh && skip "remote OST with nodsh"
12507
12508         reset_async
12509
12510         #define OBD_FAIL_OST_EROFS               0x216
12511         set_nodes_failloc "$(osts_nodes)" 0x216
12512
12513         # multiop should block due to fsync until pages are written
12514         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12515         MULTIPID=$!
12516         sleep 1
12517
12518         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12519                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12520         fi
12521
12522         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12523                     grep -c writeback)
12524         if [[ $WRITEBACK -eq 0 ]]; then
12525                 error "No page in writeback, writeback=$WRITEBACK"
12526         fi
12527
12528         set_nodes_failloc "$(osts_nodes)" 0
12529         wait $MULTIPID
12530         RC=$?
12531         if [[ $RC -ne 0 ]]; then
12532                 error "Multiop fsync failed, rc=$RC"
12533         fi
12534
12535         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12536         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12537                     grep -c writeback)
12538         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12539                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12540         fi
12541
12542         rm -f $DIR/$tfile
12543         echo "Dirty pages flushed via fsync on EROFS"
12544         return 0
12545 }
12546 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12547
12548 # continue to use small resend count to reduce test_118* time (b=14842)
12549 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12550
12551 test_118d()
12552 {
12553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12554         remote_ost_nodsh && skip "remote OST with nodsh"
12555
12556         reset_async
12557
12558         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12559         set_nodes_failloc "$(osts_nodes)" 0x214
12560         # multiop should block due to fsync until pages are written
12561         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12562         MULTIPID=$!
12563         sleep 1
12564
12565         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12566                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12567         fi
12568
12569         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12570                     grep -c writeback)
12571         if [[ $WRITEBACK -eq 0 ]]; then
12572                 error "No page in writeback, writeback=$WRITEBACK"
12573         fi
12574
12575         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12576         set_nodes_failloc "$(osts_nodes)" 0
12577
12578         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12579         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12580                     grep -c writeback)
12581         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12582                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12583         fi
12584
12585         rm -f $DIR/$tfile
12586         echo "Dirty pages gaurenteed flushed via fsync"
12587         return 0
12588 }
12589 run_test 118d "Fsync validation inject a delay of the bulk =========="
12590
12591 test_118f() {
12592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12593
12594         reset_async
12595
12596         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12597         lctl set_param fail_loc=0x8000040a
12598
12599         # Should simulate EINVAL error which is fatal
12600         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12601         RC=$?
12602         if [[ $RC -eq 0 ]]; then
12603                 error "Must return error due to dropped pages, rc=$RC"
12604         fi
12605
12606         lctl set_param fail_loc=0x0
12607
12608         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12609         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12610         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12611                     grep -c writeback)
12612         if [[ $LOCKED -ne 0 ]]; then
12613                 error "Locked pages remain in cache, locked=$LOCKED"
12614         fi
12615
12616         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12617                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12618         fi
12619
12620         rm -f $DIR/$tfile
12621         echo "No pages locked after fsync"
12622
12623         reset_async
12624         return 0
12625 }
12626 run_test 118f "Simulate unrecoverable OSC side error =========="
12627
12628 test_118g() {
12629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12630
12631         reset_async
12632
12633         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12634         lctl set_param fail_loc=0x406
12635
12636         # simulate local -ENOMEM
12637         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12638         RC=$?
12639
12640         lctl set_param fail_loc=0
12641         if [[ $RC -eq 0 ]]; then
12642                 error "Must return error due to dropped pages, rc=$RC"
12643         fi
12644
12645         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12646         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12647         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12648                         grep -c writeback)
12649         if [[ $LOCKED -ne 0 ]]; then
12650                 error "Locked pages remain in cache, locked=$LOCKED"
12651         fi
12652
12653         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12654                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12655         fi
12656
12657         rm -f $DIR/$tfile
12658         echo "No pages locked after fsync"
12659
12660         reset_async
12661         return 0
12662 }
12663 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12664
12665 test_118h() {
12666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12667         remote_ost_nodsh && skip "remote OST with nodsh"
12668
12669         reset_async
12670
12671         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12672         set_nodes_failloc "$(osts_nodes)" 0x20e
12673         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12674         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12675         RC=$?
12676
12677         set_nodes_failloc "$(osts_nodes)" 0
12678         if [[ $RC -eq 0 ]]; then
12679                 error "Must return error due to dropped pages, rc=$RC"
12680         fi
12681
12682         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12683         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12684         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12685                     grep -c writeback)
12686         if [[ $LOCKED -ne 0 ]]; then
12687                 error "Locked pages remain in cache, locked=$LOCKED"
12688         fi
12689
12690         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12691                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12692         fi
12693
12694         rm -f $DIR/$tfile
12695         echo "No pages locked after fsync"
12696
12697         return 0
12698 }
12699 run_test 118h "Verify timeout in handling recoverables errors  =========="
12700
12701 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12702
12703 test_118i() {
12704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12705         remote_ost_nodsh && skip "remote OST with nodsh"
12706
12707         reset_async
12708
12709         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12710         set_nodes_failloc "$(osts_nodes)" 0x20e
12711
12712         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12713         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12714         PID=$!
12715         sleep 5
12716         set_nodes_failloc "$(osts_nodes)" 0
12717
12718         wait $PID
12719         RC=$?
12720         if [[ $RC -ne 0 ]]; then
12721                 error "got error, but should be not, rc=$RC"
12722         fi
12723
12724         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12725         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12726         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12727         if [[ $LOCKED -ne 0 ]]; then
12728                 error "Locked pages remain in cache, locked=$LOCKED"
12729         fi
12730
12731         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12732                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12733         fi
12734
12735         rm -f $DIR/$tfile
12736         echo "No pages locked after fsync"
12737
12738         return 0
12739 }
12740 run_test 118i "Fix error before timeout in recoverable error  =========="
12741
12742 [ "$SLOW" = "no" ] && set_resend_count 4
12743
12744 test_118j() {
12745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12746         remote_ost_nodsh && skip "remote OST with nodsh"
12747
12748         reset_async
12749
12750         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12751         set_nodes_failloc "$(osts_nodes)" 0x220
12752
12753         # return -EIO from OST
12754         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12755         RC=$?
12756         set_nodes_failloc "$(osts_nodes)" 0x0
12757         if [[ $RC -eq 0 ]]; then
12758                 error "Must return error due to dropped pages, rc=$RC"
12759         fi
12760
12761         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12762         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12763         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12764         if [[ $LOCKED -ne 0 ]]; then
12765                 error "Locked pages remain in cache, locked=$LOCKED"
12766         fi
12767
12768         # in recoverable error on OST we want resend and stay until it finished
12769         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12770                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12771         fi
12772
12773         rm -f $DIR/$tfile
12774         echo "No pages locked after fsync"
12775
12776         return 0
12777 }
12778 run_test 118j "Simulate unrecoverable OST side error =========="
12779
12780 test_118k()
12781 {
12782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12783         remote_ost_nodsh && skip "remote OSTs with nodsh"
12784
12785         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12786         set_nodes_failloc "$(osts_nodes)" 0x20e
12787         test_mkdir $DIR/$tdir
12788
12789         for ((i=0;i<10;i++)); do
12790                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12791                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12792                 SLEEPPID=$!
12793                 sleep 0.500s
12794                 kill $SLEEPPID
12795                 wait $SLEEPPID
12796         done
12797
12798         set_nodes_failloc "$(osts_nodes)" 0
12799         rm -rf $DIR/$tdir
12800 }
12801 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12802
12803 test_118l() # LU-646
12804 {
12805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12806
12807         test_mkdir $DIR/$tdir
12808         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12809         rm -rf $DIR/$tdir
12810 }
12811 run_test 118l "fsync dir"
12812
12813 test_118m() # LU-3066
12814 {
12815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12816
12817         test_mkdir $DIR/$tdir
12818         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12819         rm -rf $DIR/$tdir
12820 }
12821 run_test 118m "fdatasync dir ========="
12822
12823 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12824
12825 test_118n()
12826 {
12827         local begin
12828         local end
12829
12830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12831         remote_ost_nodsh && skip "remote OSTs with nodsh"
12832
12833         # Sleep to avoid a cached response.
12834         #define OBD_STATFS_CACHE_SECONDS 1
12835         sleep 2
12836
12837         # Inject a 10 second delay in the OST_STATFS handler.
12838         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12839         set_nodes_failloc "$(osts_nodes)" 0x242
12840
12841         begin=$SECONDS
12842         stat --file-system $MOUNT > /dev/null
12843         end=$SECONDS
12844
12845         set_nodes_failloc "$(osts_nodes)" 0
12846
12847         if ((end - begin > 20)); then
12848             error "statfs took $((end - begin)) seconds, expected 10"
12849         fi
12850 }
12851 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12852
12853 test_119a() # bug 11737
12854 {
12855         BSIZE=$((512 * 1024))
12856         directio write $DIR/$tfile 0 1 $BSIZE
12857         # We ask to read two blocks, which is more than a file size.
12858         # directio will indicate an error when requested and actual
12859         # sizes aren't equeal (a normal situation in this case) and
12860         # print actual read amount.
12861         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12862         if [ "$NOB" != "$BSIZE" ]; then
12863                 error "read $NOB bytes instead of $BSIZE"
12864         fi
12865         rm -f $DIR/$tfile
12866 }
12867 run_test 119a "Short directIO read must return actual read amount"
12868
12869 test_119b() # bug 11737
12870 {
12871         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12872
12873         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12874         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12875         sync
12876         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12877                 error "direct read failed"
12878         rm -f $DIR/$tfile
12879 }
12880 run_test 119b "Sparse directIO read must return actual read amount"
12881
12882 test_119c() # bug 13099
12883 {
12884         BSIZE=1048576
12885         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12886         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12887         rm -f $DIR/$tfile
12888 }
12889 run_test 119c "Testing for direct read hitting hole"
12890
12891 test_119d() # bug 15950
12892 {
12893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12894
12895         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12896         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12897         BSIZE=1048576
12898         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12899         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12900         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12901         lctl set_param fail_loc=0x40d
12902         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12903         pid_dio=$!
12904         sleep 1
12905         cat $DIR/$tfile > /dev/null &
12906         lctl set_param fail_loc=0
12907         pid_reads=$!
12908         wait $pid_dio
12909         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12910         sleep 2
12911         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12912         error "the read rpcs have not completed in 2s"
12913         rm -f $DIR/$tfile
12914         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12915 }
12916 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12917
12918 test_120a() {
12919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12920         remote_mds_nodsh && skip "remote MDS with nodsh"
12921         test_mkdir -i0 -c1 $DIR/$tdir
12922         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12923                 skip_env "no early lock cancel on server"
12924
12925         lru_resize_disable mdc
12926         lru_resize_disable osc
12927         cancel_lru_locks mdc
12928         # asynchronous object destroy at MDT could cause bl ast to client
12929         cancel_lru_locks osc
12930
12931         stat $DIR/$tdir > /dev/null
12932         can1=$(do_facet mds1 \
12933                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12934                awk '/ldlm_cancel/ {print $2}')
12935         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12936                awk '/ldlm_bl_callback/ {print $2}')
12937         test_mkdir -i0 -c1 $DIR/$tdir/d1
12938         can2=$(do_facet mds1 \
12939                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12940                awk '/ldlm_cancel/ {print $2}')
12941         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12942                awk '/ldlm_bl_callback/ {print $2}')
12943         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12944         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12945         lru_resize_enable mdc
12946         lru_resize_enable osc
12947 }
12948 run_test 120a "Early Lock Cancel: mkdir test"
12949
12950 test_120b() {
12951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12952         remote_mds_nodsh && skip "remote MDS with nodsh"
12953         test_mkdir $DIR/$tdir
12954         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12955                 skip_env "no early lock cancel on server"
12956
12957         lru_resize_disable mdc
12958         lru_resize_disable osc
12959         cancel_lru_locks mdc
12960         stat $DIR/$tdir > /dev/null
12961         can1=$(do_facet $SINGLEMDS \
12962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12963                awk '/ldlm_cancel/ {print $2}')
12964         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12965                awk '/ldlm_bl_callback/ {print $2}')
12966         touch $DIR/$tdir/f1
12967         can2=$(do_facet $SINGLEMDS \
12968                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12969                awk '/ldlm_cancel/ {print $2}')
12970         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12971                awk '/ldlm_bl_callback/ {print $2}')
12972         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12973         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12974         lru_resize_enable mdc
12975         lru_resize_enable osc
12976 }
12977 run_test 120b "Early Lock Cancel: create test"
12978
12979 test_120c() {
12980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12981         remote_mds_nodsh && skip "remote MDS with nodsh"
12982         test_mkdir -i0 -c1 $DIR/$tdir
12983         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12984                 skip "no early lock cancel on server"
12985
12986         lru_resize_disable mdc
12987         lru_resize_disable osc
12988         test_mkdir -i0 -c1 $DIR/$tdir/d1
12989         test_mkdir -i0 -c1 $DIR/$tdir/d2
12990         touch $DIR/$tdir/d1/f1
12991         cancel_lru_locks mdc
12992         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12993         can1=$(do_facet mds1 \
12994                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12995                awk '/ldlm_cancel/ {print $2}')
12996         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12997                awk '/ldlm_bl_callback/ {print $2}')
12998         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12999         can2=$(do_facet mds1 \
13000                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13001                awk '/ldlm_cancel/ {print $2}')
13002         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13003                awk '/ldlm_bl_callback/ {print $2}')
13004         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13005         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13006         lru_resize_enable mdc
13007         lru_resize_enable osc
13008 }
13009 run_test 120c "Early Lock Cancel: link test"
13010
13011 test_120d() {
13012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13013         remote_mds_nodsh && skip "remote MDS with nodsh"
13014         test_mkdir -i0 -c1 $DIR/$tdir
13015         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13016                 skip_env "no early lock cancel on server"
13017
13018         lru_resize_disable mdc
13019         lru_resize_disable osc
13020         touch $DIR/$tdir
13021         cancel_lru_locks mdc
13022         stat $DIR/$tdir > /dev/null
13023         can1=$(do_facet mds1 \
13024                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13025                awk '/ldlm_cancel/ {print $2}')
13026         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13027                awk '/ldlm_bl_callback/ {print $2}')
13028         chmod a+x $DIR/$tdir
13029         can2=$(do_facet mds1 \
13030                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13031                awk '/ldlm_cancel/ {print $2}')
13032         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13033                awk '/ldlm_bl_callback/ {print $2}')
13034         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13035         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13036         lru_resize_enable mdc
13037         lru_resize_enable osc
13038 }
13039 run_test 120d "Early Lock Cancel: setattr test"
13040
13041 test_120e() {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13044                 skip_env "no early lock cancel on server"
13045         remote_mds_nodsh && skip "remote MDS with nodsh"
13046
13047         local dlmtrace_set=false
13048
13049         test_mkdir -i0 -c1 $DIR/$tdir
13050         lru_resize_disable mdc
13051         lru_resize_disable osc
13052         ! $LCTL get_param debug | grep -q dlmtrace &&
13053                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13054         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13055         cancel_lru_locks mdc
13056         cancel_lru_locks osc
13057         dd if=$DIR/$tdir/f1 of=/dev/null
13058         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13059         # XXX client can not do early lock cancel of OST lock
13060         # during unlink (LU-4206), so cancel osc lock now.
13061         sleep 2
13062         cancel_lru_locks osc
13063         can1=$(do_facet mds1 \
13064                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13065                awk '/ldlm_cancel/ {print $2}')
13066         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13067                awk '/ldlm_bl_callback/ {print $2}')
13068         unlink $DIR/$tdir/f1
13069         sleep 5
13070         can2=$(do_facet mds1 \
13071                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13072                awk '/ldlm_cancel/ {print $2}')
13073         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13074                awk '/ldlm_bl_callback/ {print $2}')
13075         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13076                 $LCTL dk $TMP/cancel.debug.txt
13077         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13078                 $LCTL dk $TMP/blocking.debug.txt
13079         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13080         lru_resize_enable mdc
13081         lru_resize_enable osc
13082 }
13083 run_test 120e "Early Lock Cancel: unlink test"
13084
13085 test_120f() {
13086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13087         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13088                 skip_env "no early lock cancel on server"
13089         remote_mds_nodsh && skip "remote MDS with nodsh"
13090
13091         test_mkdir -i0 -c1 $DIR/$tdir
13092         lru_resize_disable mdc
13093         lru_resize_disable osc
13094         test_mkdir -i0 -c1 $DIR/$tdir/d1
13095         test_mkdir -i0 -c1 $DIR/$tdir/d2
13096         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13097         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13098         cancel_lru_locks mdc
13099         cancel_lru_locks osc
13100         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13101         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13102         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13103         # XXX client can not do early lock cancel of OST lock
13104         # during rename (LU-4206), so cancel osc lock now.
13105         sleep 2
13106         cancel_lru_locks osc
13107         can1=$(do_facet mds1 \
13108                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13109                awk '/ldlm_cancel/ {print $2}')
13110         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13111                awk '/ldlm_bl_callback/ {print $2}')
13112         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13113         sleep 5
13114         can2=$(do_facet mds1 \
13115                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13116                awk '/ldlm_cancel/ {print $2}')
13117         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13118                awk '/ldlm_bl_callback/ {print $2}')
13119         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13120         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13121         lru_resize_enable mdc
13122         lru_resize_enable osc
13123 }
13124 run_test 120f "Early Lock Cancel: rename test"
13125
13126 test_120g() {
13127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13128         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13129                 skip_env "no early lock cancel on server"
13130         remote_mds_nodsh && skip "remote MDS with nodsh"
13131
13132         lru_resize_disable mdc
13133         lru_resize_disable osc
13134         count=10000
13135         echo create $count files
13136         test_mkdir $DIR/$tdir
13137         cancel_lru_locks mdc
13138         cancel_lru_locks osc
13139         t0=$(date +%s)
13140
13141         can0=$(do_facet $SINGLEMDS \
13142                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13143                awk '/ldlm_cancel/ {print $2}')
13144         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13145                awk '/ldlm_bl_callback/ {print $2}')
13146         createmany -o $DIR/$tdir/f $count
13147         sync
13148         can1=$(do_facet $SINGLEMDS \
13149                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13150                awk '/ldlm_cancel/ {print $2}')
13151         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13152                awk '/ldlm_bl_callback/ {print $2}')
13153         t1=$(date +%s)
13154         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13155         echo rm $count files
13156         rm -r $DIR/$tdir
13157         sync
13158         can2=$(do_facet $SINGLEMDS \
13159                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13160                awk '/ldlm_cancel/ {print $2}')
13161         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13162                awk '/ldlm_bl_callback/ {print $2}')
13163         t2=$(date +%s)
13164         echo total: $count removes in $((t2-t1))
13165         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13166         sleep 2
13167         # wait for commitment of removal
13168         lru_resize_enable mdc
13169         lru_resize_enable osc
13170 }
13171 run_test 120g "Early Lock Cancel: performance test"
13172
13173 test_121() { #bug #10589
13174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13175
13176         rm -rf $DIR/$tfile
13177         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13178 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13179         lctl set_param fail_loc=0x310
13180         cancel_lru_locks osc > /dev/null
13181         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13182         lctl set_param fail_loc=0
13183         [[ $reads -eq $writes ]] ||
13184                 error "read $reads blocks, must be $writes blocks"
13185 }
13186 run_test 121 "read cancel race ========="
13187
13188 test_123a_base() { # was test 123, statahead(bug 11401)
13189         local lsx="$1"
13190
13191         SLOWOK=0
13192         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13193                 log "testing UP system. Performance may be lower than expected."
13194                 SLOWOK=1
13195         fi
13196         running_in_vm && SLOWOK=1
13197
13198         rm -rf $DIR/$tdir
13199         test_mkdir $DIR/$tdir
13200         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13201         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13202         MULT=10
13203         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13204                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13205
13206                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13207                 lctl set_param -n llite.*.statahead_max 0
13208                 lctl get_param llite.*.statahead_max
13209                 cancel_lru_locks mdc
13210                 cancel_lru_locks osc
13211                 stime=$(date +%s)
13212                 time $lsx $DIR/$tdir | wc -l
13213                 etime=$(date +%s)
13214                 delta=$((etime - stime))
13215                 log "$lsx $i files without statahead: $delta sec"
13216                 lctl set_param llite.*.statahead_max=$max
13217
13218                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13219                          awk '/statahead.wrong:/ { print $NF }')
13220                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13221                 cancel_lru_locks mdc
13222                 cancel_lru_locks osc
13223                 stime=$(date +%s)
13224                 time $lsx $DIR/$tdir | wc -l
13225                 etime=$(date +%s)
13226                 delta_sa=$((etime - stime))
13227                 log "$lsx $i files with statahead: $delta_sa sec"
13228                 lctl get_param -n llite.*.statahead_stats
13229                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13230                          awk '/statahead.wrong:/ { print $NF }')
13231
13232                 [[ $swrong -lt $ewrong ]] &&
13233                         log "statahead was stopped, maybe too many locks held!"
13234                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13235
13236                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13237                         max=$(lctl get_param -n llite.*.statahead_max |
13238                                 head -n 1)
13239                         lctl set_param -n llite.*.statahead_max 0
13240                         lctl get_param llite.*.statahead_max
13241                         cancel_lru_locks mdc
13242                         cancel_lru_locks osc
13243                         stime=$(date +%s)
13244                         time $lsx $DIR/$tdir | wc -l
13245                         etime=$(date +%s)
13246                         delta=$((etime - stime))
13247                         log "$lsx $i files again without statahead: $delta sec"
13248                         lctl set_param llite.*.statahead_max=$max
13249                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13250                                 if [ $SLOWOK -eq 0 ]; then
13251                                         error "$lsx $i files is slower with statahead!"
13252                                 else
13253                                         log "$lsx $i files is slower with statahead!"
13254                                 fi
13255                                 break
13256                         fi
13257                 fi
13258
13259                 [ $delta -gt 20 ] && break
13260                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13261                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13262         done
13263         log "$lsx done"
13264
13265         stime=$(date +%s)
13266         rm -r $DIR/$tdir
13267         sync
13268         etime=$(date +%s)
13269         delta=$((etime - stime))
13270         log "rm -r $DIR/$tdir/: $delta seconds"
13271         log "rm done"
13272         lctl get_param -n llite.*.statahead_stats
13273 }
13274
13275 test_123aa() {
13276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13277
13278         test_123a_base "ls -l"
13279 }
13280 run_test 123aa "verify statahead work"
13281
13282 test_123ab() {
13283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13284
13285         statx_supported || skip_env "Test must be statx() syscall supported"
13286
13287         test_123a_base "$STATX -l"
13288 }
13289 run_test 123ab "verify statahead work by using statx"
13290
13291 test_123ac() {
13292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13293
13294         statx_supported || skip_env "Test must be statx() syscall supported"
13295
13296         local rpcs_before
13297         local rpcs_after
13298         local agl_before
13299         local agl_after
13300
13301         cancel_lru_locks $OSC
13302         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13303         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13304                      awk '/agl.total:/ { print $NF }')
13305         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13306         test_123a_base "$STATX --cached=always -D"
13307         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13308                     awk '/agl.total:/ { print $NF }')
13309         [ $agl_before -eq $agl_after ] ||
13310                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13311         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13312         [ $rpcs_after -eq $rpcs_before ] ||
13313                 error "$STATX should not send glimpse RPCs to $OSC"
13314 }
13315 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13316
13317 test_123b () { # statahead(bug 15027)
13318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13319
13320         test_mkdir $DIR/$tdir
13321         createmany -o $DIR/$tdir/$tfile-%d 1000
13322
13323         cancel_lru_locks mdc
13324         cancel_lru_locks osc
13325
13326 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13327         lctl set_param fail_loc=0x80000803
13328         ls -lR $DIR/$tdir > /dev/null
13329         log "ls done"
13330         lctl set_param fail_loc=0x0
13331         lctl get_param -n llite.*.statahead_stats
13332         rm -r $DIR/$tdir
13333         sync
13334
13335 }
13336 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13337
13338 test_123c() {
13339         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13340
13341         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13342         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13343         touch $DIR/$tdir.1/{1..3}
13344         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13345
13346         remount_client $MOUNT
13347
13348         $MULTIOP $DIR/$tdir.0 Q
13349
13350         # let statahead to complete
13351         ls -l $DIR/$tdir.0 > /dev/null
13352
13353         testid=$(echo $TESTNAME | tr '_' ' ')
13354         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13355                 error "statahead warning" || true
13356 }
13357 run_test 123c "Can not initialize inode warning on DNE statahead"
13358
13359 test_123d() {
13360         local num=100
13361         local swrong
13362         local ewrong
13363
13364         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13365         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13366                 error "setdirstripe $DIR/$tdir failed"
13367         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13368         remount_client $MOUNT
13369         $LCTL get_param llite.*.statahead_max
13370         $LCTL set_param llite.*.statahead_stats=0 ||
13371                 error "clear statahead_stats failed"
13372         swrong=$(lctl get_param -n llite.*.statahead_stats |
13373                  awk '/statahead.wrong:/ { print $NF }')
13374         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13375         # wait for statahead thread finished to update hit/miss stats.
13376         sleep 1
13377         $LCTL get_param -n llite.*.statahead_stats
13378         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13379                  awk '/statahead.wrong:/ { print $NF }')
13380         (( $swrong == $ewrong )) ||
13381                 log "statahead was stopped, maybe too many locks held!"
13382 }
13383 run_test 123d "Statahead on striped directories works correctly"
13384
13385 test_124a() {
13386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13387         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13388                 skip_env "no lru resize on server"
13389
13390         local NR=2000
13391
13392         test_mkdir $DIR/$tdir
13393
13394         log "create $NR files at $DIR/$tdir"
13395         createmany -o $DIR/$tdir/f $NR ||
13396                 error "failed to create $NR files in $DIR/$tdir"
13397
13398         cancel_lru_locks mdc
13399         ls -l $DIR/$tdir > /dev/null
13400
13401         local NSDIR=""
13402         local LRU_SIZE=0
13403         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13404                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13405                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13406                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13407                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13408                         log "NSDIR=$NSDIR"
13409                         log "NS=$(basename $NSDIR)"
13410                         break
13411                 fi
13412         done
13413
13414         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13415                 skip "Not enough cached locks created!"
13416         fi
13417         log "LRU=$LRU_SIZE"
13418
13419         local SLEEP=30
13420
13421         # We know that lru resize allows one client to hold $LIMIT locks
13422         # for 10h. After that locks begin to be killed by client.
13423         local MAX_HRS=10
13424         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13425         log "LIMIT=$LIMIT"
13426         if [ $LIMIT -lt $LRU_SIZE ]; then
13427                 skip "Limit is too small $LIMIT"
13428         fi
13429
13430         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13431         # killing locks. Some time was spent for creating locks. This means
13432         # that up to the moment of sleep finish we must have killed some of
13433         # them (10-100 locks). This depends on how fast ther were created.
13434         # Many of them were touched in almost the same moment and thus will
13435         # be killed in groups.
13436         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13437
13438         # Use $LRU_SIZE_B here to take into account real number of locks
13439         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13440         local LRU_SIZE_B=$LRU_SIZE
13441         log "LVF=$LVF"
13442         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13443         log "OLD_LVF=$OLD_LVF"
13444         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13445
13446         # Let's make sure that we really have some margin. Client checks
13447         # cached locks every 10 sec.
13448         SLEEP=$((SLEEP+20))
13449         log "Sleep ${SLEEP} sec"
13450         local SEC=0
13451         while ((SEC<$SLEEP)); do
13452                 echo -n "..."
13453                 sleep 5
13454                 SEC=$((SEC+5))
13455                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13456                 echo -n "$LRU_SIZE"
13457         done
13458         echo ""
13459         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13460         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13461
13462         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13463                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13464                 unlinkmany $DIR/$tdir/f $NR
13465                 return
13466         }
13467
13468         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13469         log "unlink $NR files at $DIR/$tdir"
13470         unlinkmany $DIR/$tdir/f $NR
13471 }
13472 run_test 124a "lru resize ======================================="
13473
13474 get_max_pool_limit()
13475 {
13476         local limit=$($LCTL get_param \
13477                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13478         local max=0
13479         for l in $limit; do
13480                 if [[ $l -gt $max ]]; then
13481                         max=$l
13482                 fi
13483         done
13484         echo $max
13485 }
13486
13487 test_124b() {
13488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13489         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13490                 skip_env "no lru resize on server"
13491
13492         LIMIT=$(get_max_pool_limit)
13493
13494         NR=$(($(default_lru_size)*20))
13495         if [[ $NR -gt $LIMIT ]]; then
13496                 log "Limit lock number by $LIMIT locks"
13497                 NR=$LIMIT
13498         fi
13499
13500         IFree=$(mdsrate_inodes_available)
13501         if [ $IFree -lt $NR ]; then
13502                 log "Limit lock number by $IFree inodes"
13503                 NR=$IFree
13504         fi
13505
13506         lru_resize_disable mdc
13507         test_mkdir -p $DIR/$tdir/disable_lru_resize
13508
13509         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13510         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13511         cancel_lru_locks mdc
13512         stime=`date +%s`
13513         PID=""
13514         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13515         PID="$PID $!"
13516         sleep 2
13517         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13518         PID="$PID $!"
13519         sleep 2
13520         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13521         PID="$PID $!"
13522         wait $PID
13523         etime=`date +%s`
13524         nolruresize_delta=$((etime-stime))
13525         log "ls -la time: $nolruresize_delta seconds"
13526         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13527         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13528
13529         lru_resize_enable mdc
13530         test_mkdir -p $DIR/$tdir/enable_lru_resize
13531
13532         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13533         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13534         cancel_lru_locks mdc
13535         stime=`date +%s`
13536         PID=""
13537         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13538         PID="$PID $!"
13539         sleep 2
13540         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13541         PID="$PID $!"
13542         sleep 2
13543         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13544         PID="$PID $!"
13545         wait $PID
13546         etime=`date +%s`
13547         lruresize_delta=$((etime-stime))
13548         log "ls -la time: $lruresize_delta seconds"
13549         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13550
13551         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13552                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13553         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13554                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13555         else
13556                 log "lru resize performs the same with no lru resize"
13557         fi
13558         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13559 }
13560 run_test 124b "lru resize (performance test) ======================="
13561
13562 test_124c() {
13563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13564         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13565                 skip_env "no lru resize on server"
13566
13567         # cache ununsed locks on client
13568         local nr=100
13569         cancel_lru_locks mdc
13570         test_mkdir $DIR/$tdir
13571         createmany -o $DIR/$tdir/f $nr ||
13572                 error "failed to create $nr files in $DIR/$tdir"
13573         ls -l $DIR/$tdir > /dev/null
13574
13575         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13576         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13577         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13578         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13579         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13580
13581         # set lru_max_age to 1 sec
13582         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13583         echo "sleep $((recalc_p * 2)) seconds..."
13584         sleep $((recalc_p * 2))
13585
13586         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13587         # restore lru_max_age
13588         $LCTL set_param -n $nsdir.lru_max_age $max_age
13589         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13590         unlinkmany $DIR/$tdir/f $nr
13591 }
13592 run_test 124c "LRUR cancel very aged locks"
13593
13594 test_124d() {
13595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13596         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13597                 skip_env "no lru resize on server"
13598
13599         # cache ununsed locks on client
13600         local nr=100
13601
13602         lru_resize_disable mdc
13603         stack_trap "lru_resize_enable mdc" EXIT
13604
13605         cancel_lru_locks mdc
13606
13607         # asynchronous object destroy at MDT could cause bl ast to client
13608         test_mkdir $DIR/$tdir
13609         createmany -o $DIR/$tdir/f $nr ||
13610                 error "failed to create $nr files in $DIR/$tdir"
13611         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13612
13613         ls -l $DIR/$tdir > /dev/null
13614
13615         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13616         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13617         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13618         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13619
13620         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13621
13622         # set lru_max_age to 1 sec
13623         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13624         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13625
13626         echo "sleep $((recalc_p * 2)) seconds..."
13627         sleep $((recalc_p * 2))
13628
13629         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13630
13631         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13632 }
13633 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13634
13635 test_125() { # 13358
13636         $LCTL get_param -n llite.*.client_type | grep -q local ||
13637                 skip "must run as local client"
13638         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13639                 skip_env "must have acl enabled"
13640         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13641
13642         test_mkdir $DIR/$tdir
13643         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13644         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13645                 error "setfacl $DIR/$tdir failed"
13646         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13647 }
13648 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13649
13650 test_126() { # bug 12829/13455
13651         $GSS && skip_env "must run as gss disabled"
13652         $LCTL get_param -n llite.*.client_type | grep -q local ||
13653                 skip "must run as local client"
13654         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13655
13656         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13657         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13658         rm -f $DIR/$tfile
13659         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13660 }
13661 run_test 126 "check that the fsgid provided by the client is taken into account"
13662
13663 test_127a() { # bug 15521
13664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13665         local name count samp unit min max sum sumsq
13666         local tmpfile=$TMP/$tfile.tmp
13667
13668         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13669         echo "stats before reset"
13670         stack_trap "rm -f $tmpfile"
13671         local now=$(date +%s)
13672
13673         $LCTL get_param osc.*.stats | tee $tmpfile
13674
13675         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13676         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13677         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13678         local uptime=$(awk '{ print $1 }' /proc/uptime)
13679
13680         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13681         (( ${snapshot_time%\.*} >= $now - 5 &&
13682            ${snapshot_time%\.*} <= $now + 5 )) ||
13683                 error "snapshot_time=$snapshot_time != now=$now"
13684         # elapsed _should_ be from mount, but at least less than uptime
13685         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13686                 error "elapsed=$elapsed > uptime=$uptime"
13687         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13688            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13689                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13690
13691         $LCTL set_param osc.*.stats=0
13692         local reset=$(date +%s)
13693         local fsize=$((2048 * 1024))
13694
13695         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13696         cancel_lru_locks osc
13697         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13698
13699         now=$(date +%s)
13700         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13701         while read name count samp unit min max sum sumsq; do
13702                 [[ "$samp" == "samples" ]] || continue
13703
13704                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13705                 [ ! $min ] && error "Missing min value for $name proc entry"
13706                 eval $name=$count || error "Wrong proc format"
13707
13708                 case $name in
13709                 read_bytes|write_bytes)
13710                         [[ "$unit" =~ "bytes" ]] ||
13711                                 error "unit is not 'bytes': $unit"
13712                         (( $min >= 4096 )) || error "min is too small: $min"
13713                         (( $min <= $fsize )) || error "min is too big: $min"
13714                         (( $max >= 4096 )) || error "max is too small: $max"
13715                         (( $max <= $fsize )) || error "max is too big: $max"
13716                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13717                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13718                                 error "sumsquare is too small: $sumsq"
13719                         (( $sumsq <= $fsize * $fsize )) ||
13720                                 error "sumsquare is too big: $sumsq"
13721                         ;;
13722                 ost_read|ost_write)
13723                         [[ "$unit" =~ "usec" ]] ||
13724                                 error "unit is not 'usec': $unit"
13725                         ;;
13726                 *)      ;;
13727                 esac
13728         done < $tmpfile
13729
13730         #check that we actually got some stats
13731         [ "$read_bytes" ] || error "Missing read_bytes stats"
13732         [ "$write_bytes" ] || error "Missing write_bytes stats"
13733         [ "$read_bytes" != 0 ] || error "no read done"
13734         [ "$write_bytes" != 0 ] || error "no write done"
13735
13736         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13737         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13738         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13739
13740         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13741         (( ${snapshot_time%\.*} >= $now - 5 &&
13742            ${snapshot_time%\.*} <= $now + 5 )) ||
13743                 error "reset snapshot_time=$snapshot_time != now=$now"
13744         # elapsed should be from time of stats reset
13745         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13746            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13747                 error "reset elapsed=$elapsed > $now - $reset"
13748         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13749            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13750                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13751 }
13752 run_test 127a "verify the client stats are sane"
13753
13754 test_127b() { # bug LU-333
13755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13756         local name count samp unit min max sum sumsq
13757
13758         echo "stats before reset"
13759         $LCTL get_param llite.*.stats
13760         $LCTL set_param llite.*.stats=0
13761
13762         # perform 2 reads and writes so MAX is different from SUM.
13763         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13764         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13765         cancel_lru_locks osc
13766         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13767         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13768
13769         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13770         stack_trap "rm -f $TMP/$tfile.tmp"
13771         while read name count samp unit min max sum sumsq; do
13772                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13773                 eval $name=$count || error "Wrong proc format"
13774
13775                 case $name in
13776                 read_bytes|write_bytes)
13777                         [[ "$unit" =~ "bytes" ]] ||
13778                                 error "unit is not 'bytes': $unit"
13779                         (( $count == 2 )) || error "count is not 2: $count"
13780                         (( $min == $PAGE_SIZE )) ||
13781                                 error "min is not $PAGE_SIZE: $min"
13782                         (( $max == $PAGE_SIZE )) ||
13783                                 error "max is not $PAGE_SIZE: $max"
13784                         (( $sum == $PAGE_SIZE * 2 )) ||
13785                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13786                         ;;
13787                 read|write)
13788                         [[ "$unit" =~ "usec" ]] ||
13789                                 error "unit is not 'usec': $unit"
13790                         ;;
13791                 *)      ;;
13792                 esac
13793         done < $TMP/$tfile.tmp
13794
13795         #check that we actually got some stats
13796         [ "$read_bytes" ] || error "Missing read_bytes stats"
13797         [ "$write_bytes" ] || error "Missing write_bytes stats"
13798         [ "$read_bytes" != 0 ] || error "no read done"
13799         [ "$write_bytes" != 0 ] || error "no write done"
13800 }
13801 run_test 127b "verify the llite client stats are sane"
13802
13803 test_127c() { # LU-12394
13804         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13805         local size
13806         local bsize
13807         local reads
13808         local writes
13809         local count
13810
13811         $LCTL set_param llite.*.extents_stats=1
13812         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13813
13814         # Use two stripes so there is enough space in default config
13815         $LFS setstripe -c 2 $DIR/$tfile
13816
13817         # Extent stats start at 0-4K and go in power of two buckets
13818         # LL_HIST_START = 12 --> 2^12 = 4K
13819         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13820         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13821         # small configs
13822         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13823                 do
13824                 # Write and read, 2x each, second time at a non-zero offset
13825                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13826                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13827                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13828                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13829                 rm -f $DIR/$tfile
13830         done
13831
13832         $LCTL get_param llite.*.extents_stats
13833
13834         count=2
13835         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13836                 do
13837                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13838                                 grep -m 1 $bsize)
13839                 reads=$(echo $bucket | awk '{print $5}')
13840                 writes=$(echo $bucket | awk '{print $9}')
13841                 [ "$reads" -eq $count ] ||
13842                         error "$reads reads in < $bsize bucket, expect $count"
13843                 [ "$writes" -eq $count ] ||
13844                         error "$writes writes in < $bsize bucket, expect $count"
13845         done
13846
13847         # Test mmap write and read
13848         $LCTL set_param llite.*.extents_stats=c
13849         size=512
13850         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13851         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13852         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13853
13854         $LCTL get_param llite.*.extents_stats
13855
13856         count=$(((size*1024) / PAGE_SIZE))
13857
13858         bsize=$((2 * PAGE_SIZE / 1024))K
13859
13860         bucket=$($LCTL get_param -n llite.*.extents_stats |
13861                         grep -m 1 $bsize)
13862         reads=$(echo $bucket | awk '{print $5}')
13863         writes=$(echo $bucket | awk '{print $9}')
13864         # mmap writes fault in the page first, creating an additonal read
13865         [ "$reads" -eq $((2 * count)) ] ||
13866                 error "$reads reads in < $bsize bucket, expect $count"
13867         [ "$writes" -eq $count ] ||
13868                 error "$writes writes in < $bsize bucket, expect $count"
13869 }
13870 run_test 127c "test llite extent stats with regular & mmap i/o"
13871
13872 test_128() { # bug 15212
13873         touch $DIR/$tfile
13874         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13875                 find $DIR/$tfile
13876                 find $DIR/$tfile
13877         EOF
13878
13879         result=$(grep error $TMP/$tfile.log)
13880         rm -f $DIR/$tfile $TMP/$tfile.log
13881         [ -z "$result" ] ||
13882                 error "consecutive find's under interactive lfs failed"
13883 }
13884 run_test 128 "interactive lfs for 2 consecutive find's"
13885
13886 set_dir_limits () {
13887         local mntdev
13888         local canondev
13889         local node
13890
13891         local ldproc=/proc/fs/ldiskfs
13892         local facets=$(get_facets MDS)
13893
13894         for facet in ${facets//,/ }; do
13895                 canondev=$(ldiskfs_canon \
13896                            *.$(convert_facet2label $facet).mntdev $facet)
13897                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13898                         ldproc=/sys/fs/ldiskfs
13899                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13900                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13901         done
13902 }
13903
13904 check_mds_dmesg() {
13905         local facets=$(get_facets MDS)
13906         for facet in ${facets//,/ }; do
13907                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13908         done
13909         return 1
13910 }
13911
13912 test_129() {
13913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13914         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13915                 skip "Need MDS version with at least 2.5.56"
13916         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13917                 skip_env "ldiskfs only test"
13918         fi
13919         remote_mds_nodsh && skip "remote MDS with nodsh"
13920
13921         local ENOSPC=28
13922         local has_warning=false
13923
13924         rm -rf $DIR/$tdir
13925         mkdir -p $DIR/$tdir
13926
13927         # block size of mds1
13928         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13929         set_dir_limits $maxsize $((maxsize * 6 / 8))
13930         stack_trap "set_dir_limits 0 0"
13931         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13932         local dirsize=$(stat -c%s "$DIR/$tdir")
13933         local nfiles=0
13934         while (( $dirsize <= $maxsize )); do
13935                 $MCREATE $DIR/$tdir/file_base_$nfiles
13936                 rc=$?
13937                 # check two errors:
13938                 # ENOSPC for ext4 max_dir_size, which has been used since
13939                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13940                 if (( rc == ENOSPC )); then
13941                         set_dir_limits 0 0
13942                         echo "rc=$rc returned as expected after $nfiles files"
13943
13944                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13945                                 error "create failed w/o dir size limit"
13946
13947                         # messages may be rate limited if test is run repeatedly
13948                         check_mds_dmesg '"is approaching max"' ||
13949                                 echo "warning message should be output"
13950                         check_mds_dmesg '"has reached max"' ||
13951                                 echo "reached message should be output"
13952
13953                         dirsize=$(stat -c%s "$DIR/$tdir")
13954
13955                         [[ $dirsize -ge $maxsize ]] && return 0
13956                         error "dirsize $dirsize < $maxsize after $nfiles files"
13957                 elif (( rc != 0 )); then
13958                         break
13959                 fi
13960                 nfiles=$((nfiles + 1))
13961                 dirsize=$(stat -c%s "$DIR/$tdir")
13962         done
13963
13964         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13965 }
13966 run_test 129 "test directory size limit ========================"
13967
13968 OLDIFS="$IFS"
13969 cleanup_130() {
13970         trap 0
13971         IFS="$OLDIFS"
13972 }
13973
13974 test_130a() {
13975         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13976         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13977
13978         trap cleanup_130 EXIT RETURN
13979
13980         local fm_file=$DIR/$tfile
13981         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13982         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13983                 error "dd failed for $fm_file"
13984
13985         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13986         filefrag -ves $fm_file
13987         local rc=$?
13988         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13989                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13990         (( $rc == 0 )) || error "filefrag $fm_file failed"
13991
13992         filefrag_op=$(filefrag -ve -k $fm_file |
13993                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13994         local lun=$($LFS getstripe -i $fm_file)
13995
13996         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13997         IFS=$'\n'
13998         local tot_len=0
13999         for line in $filefrag_op; do
14000                 local frag_lun=$(echo $line | cut -d: -f5)
14001                 local ext_len=$(echo $line | cut -d: -f4)
14002
14003                 if (( $frag_lun != $lun )); then
14004                         error "FIEMAP on 1-stripe file($fm_file) failed"
14005                         return
14006                 fi
14007                 (( tot_len += ext_len ))
14008         done
14009
14010         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14011                 error "FIEMAP on 1-stripe file($fm_file) failed"
14012                 return
14013         fi
14014
14015         echo "FIEMAP on single striped file succeeded"
14016 }
14017 run_test 130a "FIEMAP (1-stripe file)"
14018
14019 test_130b() {
14020         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14021
14022         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14023         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14024         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14025                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14026
14027         trap cleanup_130 EXIT RETURN
14028
14029         local fm_file=$DIR/$tfile
14030         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14031                 error "setstripe on $fm_file"
14032
14033         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14034                 error "dd failed on $fm_file"
14035
14036         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14037         filefrag_op=$(filefrag -ve -k $fm_file |
14038                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14039
14040         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14041                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14042
14043         IFS=$'\n'
14044         local tot_len=0
14045         local num_luns=1
14046
14047         for line in $filefrag_op; do
14048                 local frag_lun=$(echo $line | cut -d: -f5 |
14049                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14050                 local ext_len=$(echo $line | cut -d: -f4)
14051                 if (( $frag_lun != $last_lun )); then
14052                         if (( tot_len != 1024 )); then
14053                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14054                                 return
14055                         else
14056                                 (( num_luns += 1 ))
14057                                 tot_len=0
14058                         fi
14059                 fi
14060                 (( tot_len += ext_len ))
14061                 last_lun=$frag_lun
14062         done
14063         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14064                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14065                 return
14066         fi
14067
14068         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14069 }
14070 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14071
14072 test_130c() {
14073         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14074
14075         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14076         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14077         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14078                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14079
14080         trap cleanup_130 EXIT RETURN
14081
14082         local fm_file=$DIR/$tfile
14083         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14084
14085         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14086                 error "dd failed on $fm_file"
14087
14088         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14089         filefrag_op=$(filefrag -ve -k $fm_file |
14090                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14091
14092         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14093                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14094
14095         IFS=$'\n'
14096         local tot_len=0
14097         local num_luns=1
14098         for line in $filefrag_op; do
14099                 local frag_lun=$(echo $line | cut -d: -f5 |
14100                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14101                 local ext_len=$(echo $line | cut -d: -f4)
14102                 if (( $frag_lun != $last_lun )); then
14103                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14104                         if (( logical != 512 )); then
14105                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14106                                 return
14107                         fi
14108                         if (( tot_len != 512 )); then
14109                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14110                                 return
14111                         else
14112                                 (( num_luns += 1 ))
14113                                 tot_len=0
14114                         fi
14115                 fi
14116                 (( tot_len += ext_len ))
14117                 last_lun=$frag_lun
14118         done
14119         if (( num_luns != 2 || tot_len != 512 )); then
14120                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14121                 return
14122         fi
14123
14124         echo "FIEMAP on 2-stripe file with hole succeeded"
14125 }
14126 run_test 130c "FIEMAP (2-stripe file with hole)"
14127
14128 test_130d() {
14129         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14130
14131         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14132         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14133         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14134                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14135
14136         trap cleanup_130 EXIT RETURN
14137
14138         local fm_file=$DIR/$tfile
14139         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14140                         error "setstripe on $fm_file"
14141
14142         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14143         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14144                 error "dd failed on $fm_file"
14145
14146         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14147         filefrag_op=$(filefrag -ve -k $fm_file |
14148                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14149
14150         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14151                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14152
14153         IFS=$'\n'
14154         local tot_len=0
14155         local num_luns=1
14156         for line in $filefrag_op; do
14157                 local frag_lun=$(echo $line | cut -d: -f5 |
14158                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14159                 local ext_len=$(echo $line | cut -d: -f4)
14160                 if (( $frag_lun != $last_lun )); then
14161                         if (( tot_len != 1024 )); then
14162                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14163                                 return
14164                         else
14165                                 (( num_luns += 1 ))
14166                                 local tot_len=0
14167                         fi
14168                 fi
14169                 (( tot_len += ext_len ))
14170                 last_lun=$frag_lun
14171         done
14172         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14173                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14174                 return
14175         fi
14176
14177         echo "FIEMAP on N-stripe file succeeded"
14178 }
14179 run_test 130d "FIEMAP (N-stripe file)"
14180
14181 test_130e() {
14182         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14183
14184         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14185         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14186         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14187                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14188
14189         trap cleanup_130 EXIT RETURN
14190
14191         local fm_file=$DIR/$tfile
14192         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14193
14194         local num_blks=512
14195         local expected_len=$(( (num_blks / 2) * 64 ))
14196         for ((i = 0; i < $num_blks; i++)); do
14197                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14198                         conv=notrunc > /dev/null 2>&1
14199         done
14200
14201         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14202         filefrag_op=$(filefrag -ve -k $fm_file |
14203                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14204
14205         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14206
14207         IFS=$'\n'
14208         local tot_len=0
14209         local num_luns=1
14210         for line in $filefrag_op; do
14211                 local frag_lun=$(echo $line | cut -d: -f5)
14212                 local ext_len=$(echo $line | cut -d: -f4)
14213                 if (( $frag_lun != $last_lun )); then
14214                         if (( tot_len != $expected_len )); then
14215                                 error "OST$last_lun $tot_len != $expected_len"
14216                         else
14217                                 (( num_luns += 1 ))
14218                                 tot_len=0
14219                         fi
14220                 fi
14221                 (( tot_len += ext_len ))
14222                 last_lun=$frag_lun
14223         done
14224         if (( num_luns != 2 || tot_len != $expected_len )); then
14225                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14226         fi
14227
14228         echo "FIEMAP with continuation calls succeeded"
14229 }
14230 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14231
14232 test_130f() {
14233         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14234         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14235         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14236                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14237
14238         local fm_file=$DIR/$tfile
14239         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14240                 error "multiop create with lov_delay_create on $fm_file"
14241
14242         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14243         filefrag_extents=$(filefrag -vek $fm_file |
14244                            awk '/extents? found/ { print $2 }')
14245         if (( $filefrag_extents != 0 )); then
14246                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14247         fi
14248
14249         rm -f $fm_file
14250 }
14251 run_test 130f "FIEMAP (unstriped file)"
14252
14253 test_130g() {
14254         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14255                 skip "Need MDS version with at least 2.12.53 for overstriping"
14256         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14257         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14258         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14259                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14260
14261         local file=$DIR/$tfile
14262         local nr=$((OSTCOUNT * 100))
14263
14264         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14265
14266         stack_trap "rm -f $file"
14267         dd if=/dev/zero of=$file count=$nr bs=1M
14268         sync
14269         nr=$($LFS getstripe -c $file)
14270
14271         local extents=$(filefrag -v $file |
14272                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14273
14274         echo "filefrag list $extents extents in file with stripecount $nr"
14275         if (( extents < nr )); then
14276                 $LFS getstripe $file
14277                 filefrag -v $file
14278                 error "filefrag printed $extents < $nr extents"
14279         fi
14280 }
14281 run_test 130g "FIEMAP (overstripe file)"
14282
14283 # Test for writev/readv
14284 test_131a() {
14285         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14286                 error "writev test failed"
14287         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14288                 error "readv failed"
14289         rm -f $DIR/$tfile
14290 }
14291 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14292
14293 test_131b() {
14294         local fsize=$((524288 + 1048576 + 1572864))
14295         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14296                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14297                         error "append writev test failed"
14298
14299         ((fsize += 1572864 + 1048576))
14300         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14301                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14302                         error "append writev test failed"
14303         rm -f $DIR/$tfile
14304 }
14305 run_test 131b "test append writev"
14306
14307 test_131c() {
14308         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14309         error "NOT PASS"
14310 }
14311 run_test 131c "test read/write on file w/o objects"
14312
14313 test_131d() {
14314         rwv -f $DIR/$tfile -w -n 1 1572864
14315         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14316         if [ "$NOB" != 1572864 ]; then
14317                 error "Short read filed: read $NOB bytes instead of 1572864"
14318         fi
14319         rm -f $DIR/$tfile
14320 }
14321 run_test 131d "test short read"
14322
14323 test_131e() {
14324         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14325         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14326         error "read hitting hole failed"
14327         rm -f $DIR/$tfile
14328 }
14329 run_test 131e "test read hitting hole"
14330
14331 check_stats() {
14332         local facet=$1
14333         local op=$2
14334         local want=${3:-0}
14335         local res
14336
14337         # open             11 samples [usecs] 468 4793 13658 35791898
14338         case $facet in
14339         mds*) res=($(do_facet $facet \
14340                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14341                  ;;
14342         ost*) res=($(do_facet $facet \
14343                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14344                  ;;
14345         *) error "Wrong facet '$facet'" ;;
14346         esac
14347         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14348         # if $want is zero, it means any stat increment is ok.
14349         if (( $want > 0 )); then
14350                 local count=${res[1]}
14351
14352                 if (( $count != $want )); then
14353                         if [[ $facet =~ "mds" ]]; then
14354                                 do_nodes $(comma_list $(mdts_nodes)) \
14355                                         $LCTL get_param mdt.*.md_stats
14356                         else
14357                                 do_nodes $(comma_list $(osts-nodes)) \
14358                                         $LCTL get_param obdfilter.*.stats
14359                         fi
14360                         error "The $op counter on $facet is $count, not $want"
14361                 fi
14362         fi
14363 }
14364
14365 test_133a() {
14366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14367         remote_ost_nodsh && skip "remote OST with nodsh"
14368         remote_mds_nodsh && skip "remote MDS with nodsh"
14369         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14370                 skip_env "MDS doesn't support rename stats"
14371
14372         local testdir=$DIR/${tdir}/stats_testdir
14373
14374         mkdir -p $DIR/${tdir}
14375
14376         # clear stats.
14377         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14378         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14379
14380         # verify mdt stats first.
14381         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14382         check_stats $SINGLEMDS "mkdir" 1
14383
14384         # clear "open" from "lfs mkdir" above
14385         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14386         touch ${testdir}/${tfile} || error "touch failed"
14387         check_stats $SINGLEMDS "open" 1
14388         check_stats $SINGLEMDS "close" 1
14389         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14390                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14391                 check_stats $SINGLEMDS "mknod" 2
14392         }
14393         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14394         check_stats $SINGLEMDS "unlink" 1
14395         rm -f ${testdir}/${tfile} || error "file remove failed"
14396         check_stats $SINGLEMDS "unlink" 2
14397
14398         # remove working dir and check mdt stats again.
14399         rmdir ${testdir} || error "rmdir failed"
14400         check_stats $SINGLEMDS "rmdir" 1
14401
14402         local testdir1=$DIR/${tdir}/stats_testdir1
14403         mkdir_on_mdt0 -p ${testdir}
14404         mkdir_on_mdt0 -p ${testdir1}
14405         touch ${testdir1}/test1
14406         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14407         check_stats $SINGLEMDS "crossdir_rename" 1
14408
14409         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14410         check_stats $SINGLEMDS "samedir_rename" 1
14411
14412         rm -rf $DIR/${tdir}
14413 }
14414 run_test 133a "Verifying MDT stats ========================================"
14415
14416 test_133b() {
14417         local res
14418
14419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14420         remote_ost_nodsh && skip "remote OST with nodsh"
14421         remote_mds_nodsh && skip "remote MDS with nodsh"
14422
14423         local testdir=$DIR/${tdir}/stats_testdir
14424
14425         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14426         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14427         touch ${testdir}/${tfile} || error "touch failed"
14428         cancel_lru_locks mdc
14429
14430         # clear stats.
14431         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14432         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14433
14434         # extra mdt stats verification.
14435         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14436         check_stats $SINGLEMDS "setattr" 1
14437         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14438         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14439         then            # LU-1740
14440                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14441                 check_stats $SINGLEMDS "getattr" 1
14442         fi
14443         rm -rf $DIR/${tdir}
14444
14445         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14446         # so the check below is not reliable
14447         [ $MDSCOUNT -eq 1 ] || return 0
14448
14449         # Sleep to avoid a cached response.
14450         #define OBD_STATFS_CACHE_SECONDS 1
14451         sleep 2
14452         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14453         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14454         $LFS df || error "lfs failed"
14455         check_stats $SINGLEMDS "statfs" 1
14456
14457         # check aggregated statfs (LU-10018)
14458         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14459                 return 0
14460         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14461                 return 0
14462         sleep 2
14463         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14464         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14465         df $DIR
14466         check_stats $SINGLEMDS "statfs" 1
14467
14468         # We want to check that the client didn't send OST_STATFS to
14469         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14470         # extra care is needed here.
14471         if remote_mds; then
14472                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14473                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14474
14475                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14476                 [ "$res" ] && error "OST got STATFS"
14477         fi
14478
14479         return 0
14480 }
14481 run_test 133b "Verifying extra MDT stats =================================="
14482
14483 test_133c() {
14484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14485         remote_ost_nodsh && skip "remote OST with nodsh"
14486         remote_mds_nodsh && skip "remote MDS with nodsh"
14487
14488         local testdir=$DIR/$tdir/stats_testdir
14489
14490         test_mkdir -p $testdir
14491
14492         # verify obdfilter stats.
14493         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14494         sync
14495         cancel_lru_locks osc
14496         wait_delete_completed
14497
14498         # clear stats.
14499         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14500         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14501
14502         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14503                 error "dd failed"
14504         sync
14505         cancel_lru_locks osc
14506         check_stats ost1 "write" 1
14507
14508         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14509         check_stats ost1 "read" 1
14510
14511         > $testdir/$tfile || error "truncate failed"
14512         check_stats ost1 "punch" 1
14513
14514         rm -f $testdir/$tfile || error "file remove failed"
14515         wait_delete_completed
14516         check_stats ost1 "destroy" 1
14517
14518         rm -rf $DIR/$tdir
14519 }
14520 run_test 133c "Verifying OST stats ========================================"
14521
14522 order_2() {
14523         local value=$1
14524         local orig=$value
14525         local order=1
14526
14527         while [ $value -ge 2 ]; do
14528                 order=$((order*2))
14529                 value=$((value/2))
14530         done
14531
14532         if [ $orig -gt $order ]; then
14533                 order=$((order*2))
14534         fi
14535         echo $order
14536 }
14537
14538 size_in_KMGT() {
14539     local value=$1
14540     local size=('K' 'M' 'G' 'T');
14541     local i=0
14542     local size_string=$value
14543
14544     while [ $value -ge 1024 ]; do
14545         if [ $i -gt 3 ]; then
14546             #T is the biggest unit we get here, if that is bigger,
14547             #just return XXXT
14548             size_string=${value}T
14549             break
14550         fi
14551         value=$((value >> 10))
14552         if [ $value -lt 1024 ]; then
14553             size_string=${value}${size[$i]}
14554             break
14555         fi
14556         i=$((i + 1))
14557     done
14558
14559     echo $size_string
14560 }
14561
14562 get_rename_size() {
14563         local size=$1
14564         local context=${2:-.}
14565         local sample=$(do_facet $SINGLEMDS $LCTL \
14566                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14567                 grep -A1 $context |
14568                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14569         echo $sample
14570 }
14571
14572 test_133d() {
14573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14574         remote_ost_nodsh && skip "remote OST with nodsh"
14575         remote_mds_nodsh && skip "remote MDS with nodsh"
14576         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14577                 skip_env "MDS doesn't support rename stats"
14578
14579         local testdir1=$DIR/${tdir}/stats_testdir1
14580         local testdir2=$DIR/${tdir}/stats_testdir2
14581         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14582
14583         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14584
14585         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14586         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14587
14588         createmany -o $testdir1/test 512 || error "createmany failed"
14589
14590         # check samedir rename size
14591         mv ${testdir1}/test0 ${testdir1}/test_0
14592
14593         local testdir1_size=$(ls -l $DIR/${tdir} |
14594                 awk '/stats_testdir1/ {print $5}')
14595         local testdir2_size=$(ls -l $DIR/${tdir} |
14596                 awk '/stats_testdir2/ {print $5}')
14597
14598         testdir1_size=$(order_2 $testdir1_size)
14599         testdir2_size=$(order_2 $testdir2_size)
14600
14601         testdir1_size=$(size_in_KMGT $testdir1_size)
14602         testdir2_size=$(size_in_KMGT $testdir2_size)
14603
14604         echo "source rename dir size: ${testdir1_size}"
14605         echo "target rename dir size: ${testdir2_size}"
14606
14607         local cmd="do_facet $SINGLEMDS $LCTL "
14608         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14609
14610         eval $cmd || error "$cmd failed"
14611         local samedir=$($cmd | grep 'same_dir')
14612         local same_sample=$(get_rename_size $testdir1_size)
14613         [ -z "$samedir" ] && error "samedir_rename_size count error"
14614         [[ $same_sample -eq 1 ]] ||
14615                 error "samedir_rename_size error $same_sample"
14616         echo "Check same dir rename stats success"
14617
14618         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14619
14620         # check crossdir rename size
14621         mv ${testdir1}/test_0 ${testdir2}/test_0
14622
14623         testdir1_size=$(ls -l $DIR/${tdir} |
14624                 awk '/stats_testdir1/ {print $5}')
14625         testdir2_size=$(ls -l $DIR/${tdir} |
14626                 awk '/stats_testdir2/ {print $5}')
14627
14628         testdir1_size=$(order_2 $testdir1_size)
14629         testdir2_size=$(order_2 $testdir2_size)
14630
14631         testdir1_size=$(size_in_KMGT $testdir1_size)
14632         testdir2_size=$(size_in_KMGT $testdir2_size)
14633
14634         echo "source rename dir size: ${testdir1_size}"
14635         echo "target rename dir size: ${testdir2_size}"
14636
14637         eval $cmd || error "$cmd failed"
14638         local crossdir=$($cmd | grep 'crossdir')
14639         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14640         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14641         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14642         [[ $src_sample -eq 1 ]] ||
14643                 error "crossdir_rename_size error $src_sample"
14644         [[ $tgt_sample -eq 1 ]] ||
14645                 error "crossdir_rename_size error $tgt_sample"
14646         echo "Check cross dir rename stats success"
14647         rm -rf $DIR/${tdir}
14648 }
14649 run_test 133d "Verifying rename_stats ========================================"
14650
14651 test_133e() {
14652         remote_mds_nodsh && skip "remote MDS with nodsh"
14653         remote_ost_nodsh && skip "remote OST with nodsh"
14654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14655
14656         local testdir=$DIR/${tdir}/stats_testdir
14657         local ctr f0 f1 bs=32768 count=42 sum
14658
14659         mkdir -p ${testdir} || error "mkdir failed"
14660
14661         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14662
14663         for ctr in {write,read}_bytes; do
14664                 sync
14665                 cancel_lru_locks osc
14666
14667                 do_facet ost1 $LCTL set_param -n \
14668                         "obdfilter.*.exports.clear=clear"
14669
14670                 if [ $ctr = write_bytes ]; then
14671                         f0=/dev/zero
14672                         f1=${testdir}/${tfile}
14673                 else
14674                         f0=${testdir}/${tfile}
14675                         f1=/dev/null
14676                 fi
14677
14678                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14679                         error "dd failed"
14680                 sync
14681                 cancel_lru_locks osc
14682
14683                 sum=$(do_facet ost1 $LCTL get_param \
14684                         "obdfilter.*.exports.*.stats" |
14685                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14686                                 $1 == ctr { sum += $7 }
14687                                 END { printf("%0.0f", sum) }')
14688
14689                 if ((sum != bs * count)); then
14690                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14691                 fi
14692         done
14693
14694         rm -rf $DIR/${tdir}
14695 }
14696 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14697
14698 test_133f() {
14699         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14700                 skip "too old lustre for get_param -R ($facet_ver)"
14701
14702         # verifying readability.
14703         $LCTL get_param -R '*' &> /dev/null
14704
14705         # Verifing writability with badarea_io.
14706         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14707         local skipped_params='force_lbug|changelog_mask|daemon_file'
14708         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14709                 egrep -v "$skipped_params" |
14710                 xargs -n 1 find $proc_dirs -name |
14711                 xargs -n 1 badarea_io ||
14712                 error "client badarea_io failed"
14713
14714         # remount the FS in case writes/reads /proc break the FS
14715         cleanup || error "failed to unmount"
14716         setup || error "failed to setup"
14717 }
14718 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14719
14720 test_133g() {
14721         remote_mds_nodsh && skip "remote MDS with nodsh"
14722         remote_ost_nodsh && skip "remote OST with nodsh"
14723
14724         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14725         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14726         local facet
14727         for facet in mds1 ost1; do
14728                 local facet_ver=$(lustre_version_code $facet)
14729                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14730                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14731                 else
14732                         log "$facet: too old lustre for get_param -R"
14733                 fi
14734                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14735                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14736                                 tr -d = | egrep -v $skipped_params |
14737                                 xargs -n 1 find $proc_dirs -name |
14738                                 xargs -n 1 badarea_io" ||
14739                                         error "$facet badarea_io failed"
14740                 else
14741                         skip_noexit "$facet: too old lustre for get_param -R"
14742                 fi
14743         done
14744
14745         # remount the FS in case writes/reads /proc break the FS
14746         cleanup || error "failed to unmount"
14747         setup || error "failed to setup"
14748 }
14749 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14750
14751 test_133h() {
14752         remote_mds_nodsh && skip "remote MDS with nodsh"
14753         remote_ost_nodsh && skip "remote OST with nodsh"
14754         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14755                 skip "Need MDS version at least 2.9.54"
14756
14757         local facet
14758         for facet in client mds1 ost1; do
14759                 # Get the list of files that are missing the terminating newline
14760                 local plist=$(do_facet $facet
14761                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14762                 local ent
14763                 for ent in $plist; do
14764                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14765                                 awk -v FS='\v' -v RS='\v\v' \
14766                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14767                                         print FILENAME}'" 2>/dev/null)
14768                         [ -z $missing ] || {
14769                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14770                                 error "file does not end with newline: $facet-$ent"
14771                         }
14772                 done
14773         done
14774 }
14775 run_test 133h "Proc files should end with newlines"
14776
14777 test_134a() {
14778         remote_mds_nodsh && skip "remote MDS with nodsh"
14779         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14780                 skip "Need MDS version at least 2.7.54"
14781
14782         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14783         cancel_lru_locks mdc
14784
14785         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14786         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14787         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14788
14789         local nr=1000
14790         createmany -o $DIR/$tdir/f $nr ||
14791                 error "failed to create $nr files in $DIR/$tdir"
14792         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14793
14794         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14795         do_facet mds1 $LCTL set_param fail_loc=0x327
14796         do_facet mds1 $LCTL set_param fail_val=500
14797         touch $DIR/$tdir/m
14798
14799         echo "sleep 10 seconds ..."
14800         sleep 10
14801         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14802
14803         do_facet mds1 $LCTL set_param fail_loc=0
14804         do_facet mds1 $LCTL set_param fail_val=0
14805         [ $lck_cnt -lt $unused ] ||
14806                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14807
14808         rm $DIR/$tdir/m
14809         unlinkmany $DIR/$tdir/f $nr
14810 }
14811 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14812
14813 test_134b() {
14814         remote_mds_nodsh && skip "remote MDS with nodsh"
14815         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14816                 skip "Need MDS version at least 2.7.54"
14817
14818         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14819         cancel_lru_locks mdc
14820
14821         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14822                         ldlm.lock_reclaim_threshold_mb)
14823         # disable reclaim temporarily
14824         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14825
14826         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14827         do_facet mds1 $LCTL set_param fail_loc=0x328
14828         do_facet mds1 $LCTL set_param fail_val=500
14829
14830         $LCTL set_param debug=+trace
14831
14832         local nr=600
14833         createmany -o $DIR/$tdir/f $nr &
14834         local create_pid=$!
14835
14836         echo "Sleep $TIMEOUT seconds ..."
14837         sleep $TIMEOUT
14838         if ! ps -p $create_pid  > /dev/null 2>&1; then
14839                 do_facet mds1 $LCTL set_param fail_loc=0
14840                 do_facet mds1 $LCTL set_param fail_val=0
14841                 do_facet mds1 $LCTL set_param \
14842                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14843                 error "createmany finished incorrectly!"
14844         fi
14845         do_facet mds1 $LCTL set_param fail_loc=0
14846         do_facet mds1 $LCTL set_param fail_val=0
14847         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14848         wait $create_pid || return 1
14849
14850         unlinkmany $DIR/$tdir/f $nr
14851 }
14852 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14853
14854 test_135() {
14855         remote_mds_nodsh && skip "remote MDS with nodsh"
14856         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14857                 skip "Need MDS version at least 2.13.50"
14858         local fname
14859
14860         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14861
14862 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14863         #set only one record at plain llog
14864         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14865
14866         #fill already existed plain llog each 64767
14867         #wrapping whole catalog
14868         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14869
14870         createmany -o $DIR/$tdir/$tfile_ 64700
14871         for (( i = 0; i < 64700; i = i + 2 ))
14872         do
14873                 rm $DIR/$tdir/$tfile_$i &
14874                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14875                 local pid=$!
14876                 wait $pid
14877         done
14878
14879         #waiting osp synchronization
14880         wait_delete_completed
14881 }
14882 run_test 135 "Race catalog processing"
14883
14884 test_136() {
14885         remote_mds_nodsh && skip "remote MDS with nodsh"
14886         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14887                 skip "Need MDS version at least 2.13.50"
14888         local fname
14889
14890         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14891         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14892         #set only one record at plain llog
14893 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14894         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14895
14896         #fill already existed 2 plain llogs each 64767
14897         #wrapping whole catalog
14898         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14899         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14900         wait_delete_completed
14901
14902         createmany -o $DIR/$tdir/$tfile_ 10
14903         sleep 25
14904
14905         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14906         for (( i = 0; i < 10; i = i + 3 ))
14907         do
14908                 rm $DIR/$tdir/$tfile_$i &
14909                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14910                 local pid=$!
14911                 wait $pid
14912                 sleep 7
14913                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14914         done
14915
14916         #waiting osp synchronization
14917         wait_delete_completed
14918 }
14919 run_test 136 "Race catalog processing 2"
14920
14921 test_140() { #bug-17379
14922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14923
14924         test_mkdir $DIR/$tdir
14925         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14926         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14927
14928         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14929         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14930         local i=0
14931         while i=$((i + 1)); do
14932                 test_mkdir $i
14933                 cd $i || error "Changing to $i"
14934                 ln -s ../stat stat || error "Creating stat symlink"
14935                 # Read the symlink until ELOOP present,
14936                 # not LBUGing the system is considered success,
14937                 # we didn't overrun the stack.
14938                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14939                 if [ $ret -ne 0 ]; then
14940                         if [ $ret -eq 40 ]; then
14941                                 break  # -ELOOP
14942                         else
14943                                 error "Open stat symlink"
14944                                         return
14945                         fi
14946                 fi
14947         done
14948         i=$((i - 1))
14949         echo "The symlink depth = $i"
14950         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14951                 error "Invalid symlink depth"
14952
14953         # Test recursive symlink
14954         ln -s symlink_self symlink_self
14955         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14956         echo "open symlink_self returns $ret"
14957         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14958 }
14959 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14960
14961 test_150a() {
14962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14963
14964         local TF="$TMP/$tfile"
14965
14966         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14967         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14968         cp $TF $DIR/$tfile
14969         cancel_lru_locks $OSC
14970         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14971         remount_client $MOUNT
14972         df -P $MOUNT
14973         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14974
14975         $TRUNCATE $TF 6000
14976         $TRUNCATE $DIR/$tfile 6000
14977         cancel_lru_locks $OSC
14978         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14979
14980         echo "12345" >>$TF
14981         echo "12345" >>$DIR/$tfile
14982         cancel_lru_locks $OSC
14983         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14984
14985         echo "12345" >>$TF
14986         echo "12345" >>$DIR/$tfile
14987         cancel_lru_locks $OSC
14988         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14989 }
14990 run_test 150a "truncate/append tests"
14991
14992 test_150b() {
14993         check_set_fallocate_or_skip
14994         local out
14995
14996         touch $DIR/$tfile
14997         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14998         out=$(check_fallocate $DIR/$tfile 2>&1) ||
14999                 skip_eopnotsupp "$out|check_fallocate failed"
15000 }
15001 run_test 150b "Verify fallocate (prealloc) functionality"
15002
15003 test_150bb() {
15004         check_set_fallocate_or_skip
15005
15006         touch $DIR/$tfile
15007         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15008         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15009         > $DIR/$tfile
15010         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15011         # precomputed md5sum for 20MB of zeroes
15012         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15013         local sum=($(md5sum $DIR/$tfile))
15014
15015         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15016
15017         check_set_fallocate 1
15018
15019         > $DIR/$tfile
15020         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15021         sum=($(md5sum $DIR/$tfile))
15022
15023         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15024 }
15025 run_test 150bb "Verify fallocate modes both zero space"
15026
15027 test_150c() {
15028         check_set_fallocate_or_skip
15029         local striping="-c2"
15030
15031         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15032         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15033         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15034         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15035         local want=$((OSTCOUNT * 1048576))
15036
15037         # Must allocate all requested space, not more than 5% extra
15038         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15039                 error "bytes $bytes is not $want"
15040
15041         rm -f $DIR/$tfile
15042
15043         echo "verify fallocate on PFL file"
15044
15045         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15046
15047         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15048                 error "Create $DIR/$tfile failed"
15049         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15050         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15051         want=$((512 * 1048576))
15052
15053         # Must allocate all requested space, not more than 5% extra
15054         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15055                 error "bytes $bytes is not $want"
15056 }
15057 run_test 150c "Verify fallocate Size and Blocks"
15058
15059 test_150d() {
15060         check_set_fallocate_or_skip
15061         local striping="-c2"
15062
15063         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15064
15065         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15066         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15067                 error "setstripe failed"
15068         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15069         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15070         local want=$((OSTCOUNT * 1048576))
15071
15072         # Must allocate all requested space, not more than 5% extra
15073         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15074                 error "bytes $bytes is not $want"
15075 }
15076 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15077
15078 test_150e() {
15079         check_set_fallocate_or_skip
15080
15081         echo "df before:"
15082         $LFS df
15083         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15084         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15085                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15086
15087         # Find OST with Minimum Size
15088         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15089                        sort -un | head -1)
15090
15091         # Get 100MB per OST of the available space to reduce run time
15092         # else 60% of the available space if we are running SLOW tests
15093         if [ $SLOW == "no" ]; then
15094                 local space=$((1024 * 100 * OSTCOUNT))
15095         else
15096                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15097         fi
15098
15099         fallocate -l${space}k $DIR/$tfile ||
15100                 error "fallocate ${space}k $DIR/$tfile failed"
15101         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15102
15103         # get size immediately after fallocate. This should be correctly
15104         # updated
15105         local size=$(stat -c '%s' $DIR/$tfile)
15106         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15107
15108         # Sleep for a while for statfs to get updated. And not pull from cache.
15109         sleep 2
15110
15111         echo "df after fallocate:"
15112         $LFS df
15113
15114         (( size / 1024 == space )) || error "size $size != requested $space"
15115         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15116                 error "used $used < space $space"
15117
15118         rm $DIR/$tfile || error "rm failed"
15119         sync
15120         wait_delete_completed
15121
15122         echo "df after unlink:"
15123         $LFS df
15124 }
15125 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15126
15127 test_150f() {
15128         local size
15129         local blocks
15130         local want_size_before=20480 # in bytes
15131         local want_blocks_before=40 # 512 sized blocks
15132         local want_blocks_after=24  # 512 sized blocks
15133         local length=$(((want_blocks_before - want_blocks_after) * 512))
15134
15135         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15136                 skip "need at least 2.14.0 for fallocate punch"
15137
15138         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15139                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15140         fi
15141
15142         check_set_fallocate_or_skip
15143         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15144
15145         [[ "x$DOM" == "xyes" ]] &&
15146                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15147
15148         echo "Verify fallocate punch: Range within the file range"
15149         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15150                 error "dd failed for bs 4096 and count 5"
15151
15152         # Call fallocate with punch range which is within the file range
15153         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15154                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15155         # client must see changes immediately after fallocate
15156         size=$(stat -c '%s' $DIR/$tfile)
15157         blocks=$(stat -c '%b' $DIR/$tfile)
15158
15159         # Verify punch worked.
15160         (( blocks == want_blocks_after )) ||
15161                 error "punch failed: blocks $blocks != $want_blocks_after"
15162
15163         (( size == want_size_before )) ||
15164                 error "punch failed: size $size != $want_size_before"
15165
15166         # Verify there is hole in file
15167         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15168         # precomputed md5sum
15169         local expect="4a9a834a2db02452929c0a348273b4aa"
15170
15171         cksum=($(md5sum $DIR/$tfile))
15172         [[ "${cksum[0]}" == "$expect" ]] ||
15173                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15174
15175         # Start second sub-case for fallocate punch.
15176         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15177         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15178                 error "dd failed for bs 4096 and count 5"
15179
15180         # Punch range less than block size will have no change in block count
15181         want_blocks_after=40  # 512 sized blocks
15182
15183         # Punch overlaps two blocks and less than blocksize
15184         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15185                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15186         size=$(stat -c '%s' $DIR/$tfile)
15187         blocks=$(stat -c '%b' $DIR/$tfile)
15188
15189         # Verify punch worked.
15190         (( blocks == want_blocks_after )) ||
15191                 error "punch failed: blocks $blocks != $want_blocks_after"
15192
15193         (( size == want_size_before )) ||
15194                 error "punch failed: size $size != $want_size_before"
15195
15196         # Verify if range is really zero'ed out. We expect Zeros.
15197         # precomputed md5sum
15198         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15199         cksum=($(md5sum $DIR/$tfile))
15200         [[ "${cksum[0]}" == "$expect" ]] ||
15201                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15202 }
15203 run_test 150f "Verify fallocate punch functionality"
15204
15205 test_150g() {
15206         local space
15207         local size
15208         local blocks
15209         local blocks_after
15210         local size_after
15211         local BS=4096 # Block size in bytes
15212
15213         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15214                 skip "need at least 2.14.0 for fallocate punch"
15215
15216         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15217                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15218         fi
15219
15220         check_set_fallocate_or_skip
15221         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15222
15223         if [[ "x$DOM" == "xyes" ]]; then
15224                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15225                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15226         else
15227                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15228                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15229         fi
15230
15231         # Get 100MB per OST of the available space to reduce run time
15232         # else 60% of the available space if we are running SLOW tests
15233         if [ $SLOW == "no" ]; then
15234                 space=$((1024 * 100 * OSTCOUNT))
15235         else
15236                 # Find OST with Minimum Size
15237                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15238                         sort -un | head -1)
15239                 echo "min size OST: $space"
15240                 space=$(((space * 60)/100 * OSTCOUNT))
15241         fi
15242         # space in 1k units, round to 4k blocks
15243         local blkcount=$((space * 1024 / $BS))
15244
15245         echo "Verify fallocate punch: Very large Range"
15246         fallocate -l${space}k $DIR/$tfile ||
15247                 error "fallocate ${space}k $DIR/$tfile failed"
15248         # write 1M at the end, start and in the middle
15249         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15250                 error "dd failed: bs $BS count 256"
15251         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15252                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15253         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15254                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15255
15256         # Gather stats.
15257         size=$(stat -c '%s' $DIR/$tfile)
15258
15259         # gather punch length.
15260         local punch_size=$((size - (BS * 2)))
15261
15262         echo "punch_size = $punch_size"
15263         echo "size - punch_size: $((size - punch_size))"
15264         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15265
15266         # Call fallocate to punch all except 2 blocks. We leave the
15267         # first and the last block
15268         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15269         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15270                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15271
15272         size_after=$(stat -c '%s' $DIR/$tfile)
15273         blocks_after=$(stat -c '%b' $DIR/$tfile)
15274
15275         # Verify punch worked.
15276         # Size should be kept
15277         (( size == size_after )) ||
15278                 error "punch failed: size $size != $size_after"
15279
15280         # two 4k data blocks to remain plus possible 1 extra extent block
15281         (( blocks_after <= ((BS / 512) * 3) )) ||
15282                 error "too many blocks remains: $blocks_after"
15283
15284         # Verify that file has hole between the first and the last blocks
15285         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15286         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15287
15288         echo "Hole at [$hole_start, $hole_end)"
15289         (( hole_start == BS )) ||
15290                 error "no hole at offset $BS after punch"
15291
15292         (( hole_end == BS + punch_size )) ||
15293                 error "data at offset $hole_end < $((BS + punch_size))"
15294 }
15295 run_test 150g "Verify fallocate punch on large range"
15296
15297 test_150h() {
15298         local file=$DIR/$tfile
15299         local size
15300
15301         check_set_fallocate_or_skip
15302         statx_supported || skip_env "Test must be statx() syscall supported"
15303
15304         # fallocate() does not update the size information on the MDT
15305         fallocate -l 16K $file || error "failed to fallocate $file"
15306         cancel_lru_locks $OSC
15307         # STATX with cached-always mode will not send glimpse RPCs to OST,
15308         # it uses the caching attrs on the client side as much as possible.
15309         size=$($STATX --cached=always -c %s $file)
15310         [ $size == 16384 ] ||
15311                 error "size after fallocate() is $size, expected 16384"
15312 }
15313 run_test 150h "Verify extend fallocate updates the file size"
15314
15315 #LU-2902 roc_hit was not able to read all values from lproc
15316 function roc_hit_init() {
15317         local list=$(comma_list $(osts_nodes))
15318         local dir=$DIR/$tdir-check
15319         local file=$dir/$tfile
15320         local BEFORE
15321         local AFTER
15322         local idx
15323
15324         test_mkdir $dir
15325         #use setstripe to do a write to every ost
15326         for i in $(seq 0 $((OSTCOUNT-1))); do
15327                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15328                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15329                 idx=$(printf %04x $i)
15330                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15331                         awk '$1 == "cache_access" {sum += $7}
15332                                 END { printf("%0.0f", sum) }')
15333
15334                 cancel_lru_locks osc
15335                 cat $file >/dev/null
15336
15337                 AFTER=$(get_osd_param $list *OST*$idx stats |
15338                         awk '$1 == "cache_access" {sum += $7}
15339                                 END { printf("%0.0f", sum) }')
15340
15341                 echo BEFORE:$BEFORE AFTER:$AFTER
15342                 if ! let "AFTER - BEFORE == 4"; then
15343                         rm -rf $dir
15344                         error "roc_hit is not safe to use"
15345                 fi
15346                 rm $file
15347         done
15348
15349         rm -rf $dir
15350 }
15351
15352 function roc_hit() {
15353         local list=$(comma_list $(osts_nodes))
15354         echo $(get_osd_param $list '' stats |
15355                 awk '$1 == "cache_hit" {sum += $7}
15356                         END { printf("%0.0f", sum) }')
15357 }
15358
15359 function set_cache() {
15360         local on=1
15361
15362         if [ "$2" == "off" ]; then
15363                 on=0;
15364         fi
15365         local list=$(comma_list $(osts_nodes))
15366         set_osd_param $list '' $1_cache_enable $on
15367
15368         cancel_lru_locks osc
15369 }
15370
15371 test_151() {
15372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15373         remote_ost_nodsh && skip "remote OST with nodsh"
15374
15375         local CPAGES=3
15376         local list=$(comma_list $(osts_nodes))
15377
15378         # check whether obdfilter is cache capable at all
15379         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15380                 skip "not cache-capable obdfilter"
15381         fi
15382
15383         # check cache is enabled on all obdfilters
15384         if get_osd_param $list '' read_cache_enable | grep 0; then
15385                 skip "oss cache is disabled"
15386         fi
15387
15388         set_osd_param $list '' writethrough_cache_enable 1
15389
15390         # check write cache is enabled on all obdfilters
15391         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15392                 skip "oss write cache is NOT enabled"
15393         fi
15394
15395         roc_hit_init
15396
15397         #define OBD_FAIL_OBD_NO_LRU  0x609
15398         do_nodes $list $LCTL set_param fail_loc=0x609
15399
15400         # pages should be in the case right after write
15401         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15402                 error "dd failed"
15403
15404         local BEFORE=$(roc_hit)
15405         cancel_lru_locks osc
15406         cat $DIR/$tfile >/dev/null
15407         local AFTER=$(roc_hit)
15408
15409         do_nodes $list $LCTL set_param fail_loc=0
15410
15411         if ! let "AFTER - BEFORE == CPAGES"; then
15412                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15413         fi
15414
15415         cancel_lru_locks osc
15416         # invalidates OST cache
15417         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15418         set_osd_param $list '' read_cache_enable 0
15419         cat $DIR/$tfile >/dev/null
15420
15421         # now data shouldn't be found in the cache
15422         BEFORE=$(roc_hit)
15423         cancel_lru_locks osc
15424         cat $DIR/$tfile >/dev/null
15425         AFTER=$(roc_hit)
15426         if let "AFTER - BEFORE != 0"; then
15427                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15428         fi
15429
15430         set_osd_param $list '' read_cache_enable 1
15431         rm -f $DIR/$tfile
15432 }
15433 run_test 151 "test cache on oss and controls ==============================="
15434
15435 test_152() {
15436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15437
15438         local TF="$TMP/$tfile"
15439
15440         # simulate ENOMEM during write
15441 #define OBD_FAIL_OST_NOMEM      0x226
15442         lctl set_param fail_loc=0x80000226
15443         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15444         cp $TF $DIR/$tfile
15445         sync || error "sync failed"
15446         lctl set_param fail_loc=0
15447
15448         # discard client's cache
15449         cancel_lru_locks osc
15450
15451         # simulate ENOMEM during read
15452         lctl set_param fail_loc=0x80000226
15453         cmp $TF $DIR/$tfile || error "cmp failed"
15454         lctl set_param fail_loc=0
15455
15456         rm -f $TF
15457 }
15458 run_test 152 "test read/write with enomem ============================"
15459
15460 test_153() {
15461         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15462 }
15463 run_test 153 "test if fdatasync does not crash ======================="
15464
15465 dot_lustre_fid_permission_check() {
15466         local fid=$1
15467         local ffid=$MOUNT/.lustre/fid/$fid
15468         local test_dir=$2
15469
15470         echo "stat fid $fid"
15471         stat $ffid || error "stat $ffid failed."
15472         echo "touch fid $fid"
15473         touch $ffid || error "touch $ffid failed."
15474         echo "write to fid $fid"
15475         cat /etc/hosts > $ffid || error "write $ffid failed."
15476         echo "read fid $fid"
15477         diff /etc/hosts $ffid || error "read $ffid failed."
15478         echo "append write to fid $fid"
15479         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15480         echo "rename fid $fid"
15481         mv $ffid $test_dir/$tfile.1 &&
15482                 error "rename $ffid to $tfile.1 should fail."
15483         touch $test_dir/$tfile.1
15484         mv $test_dir/$tfile.1 $ffid &&
15485                 error "rename $tfile.1 to $ffid should fail."
15486         rm -f $test_dir/$tfile.1
15487         echo "truncate fid $fid"
15488         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15489         echo "link fid $fid"
15490         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15491         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15492                 echo "setfacl fid $fid"
15493                 setfacl -R -m u:$USER0:rwx $ffid ||
15494                         error "setfacl $ffid failed"
15495                 echo "getfacl fid $fid"
15496                 getfacl $ffid || error "getfacl $ffid failed."
15497         fi
15498         echo "unlink fid $fid"
15499         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15500         echo "mknod fid $fid"
15501         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15502
15503         fid=[0xf00000400:0x1:0x0]
15504         ffid=$MOUNT/.lustre/fid/$fid
15505
15506         echo "stat non-exist fid $fid"
15507         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15508         echo "write to non-exist fid $fid"
15509         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15510         echo "link new fid $fid"
15511         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15512
15513         mkdir -p $test_dir/$tdir
15514         touch $test_dir/$tdir/$tfile
15515         fid=$($LFS path2fid $test_dir/$tdir)
15516         rc=$?
15517         [ $rc -ne 0 ] &&
15518                 error "error: could not get fid for $test_dir/$dir/$tfile."
15519
15520         ffid=$MOUNT/.lustre/fid/$fid
15521
15522         echo "ls $fid"
15523         ls $ffid || error "ls $ffid failed."
15524         echo "touch $fid/$tfile.1"
15525         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15526
15527         echo "touch $MOUNT/.lustre/fid/$tfile"
15528         touch $MOUNT/.lustre/fid/$tfile && \
15529                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15530
15531         echo "setxattr to $MOUNT/.lustre/fid"
15532         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15533
15534         echo "listxattr for $MOUNT/.lustre/fid"
15535         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15536
15537         echo "delxattr from $MOUNT/.lustre/fid"
15538         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15539
15540         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15541         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15542                 error "touch invalid fid should fail."
15543
15544         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15545         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15546                 error "touch non-normal fid should fail."
15547
15548         echo "rename $tdir to $MOUNT/.lustre/fid"
15549         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15550                 error "rename to $MOUNT/.lustre/fid should fail."
15551
15552         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15553         then            # LU-3547
15554                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15555                 local new_obf_mode=777
15556
15557                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15558                 chmod $new_obf_mode $DIR/.lustre/fid ||
15559                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15560
15561                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15562                 [ $obf_mode -eq $new_obf_mode ] ||
15563                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15564
15565                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15566                 chmod $old_obf_mode $DIR/.lustre/fid ||
15567                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15568         fi
15569
15570         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15571         fid=$($LFS path2fid $test_dir/$tfile-2)
15572
15573         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15574         then # LU-5424
15575                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15576                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15577                         error "create lov data thru .lustre failed"
15578         fi
15579         echo "cp /etc/passwd $test_dir/$tfile-2"
15580         cp /etc/passwd $test_dir/$tfile-2 ||
15581                 error "copy to $test_dir/$tfile-2 failed."
15582         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15583         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15584                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15585
15586         rm -rf $test_dir/tfile.lnk
15587         rm -rf $test_dir/$tfile-2
15588 }
15589
15590 test_154A() {
15591         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15592                 skip "Need MDS version at least 2.4.1"
15593
15594         local tf=$DIR/$tfile
15595         touch $tf
15596
15597         local fid=$($LFS path2fid $tf)
15598         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15599
15600         # check that we get the same pathname back
15601         local rootpath
15602         local found
15603         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15604                 echo "$rootpath $fid"
15605                 found=$($LFS fid2path $rootpath "$fid")
15606                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15607                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15608         done
15609
15610         # check wrong root path format
15611         rootpath=$MOUNT"_wrong"
15612         found=$($LFS fid2path $rootpath "$fid")
15613         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15614 }
15615 run_test 154A "lfs path2fid and fid2path basic checks"
15616
15617 test_154B() {
15618         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15619                 skip "Need MDS version at least 2.4.1"
15620
15621         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15622         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15623         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15624         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15625
15626         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15627         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15628
15629         # check that we get the same pathname
15630         echo "PFID: $PFID, name: $name"
15631         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15632         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15633         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15634                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15635
15636         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15637 }
15638 run_test 154B "verify the ll_decode_linkea tool"
15639
15640 test_154a() {
15641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15642         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15643         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15644                 skip "Need MDS version at least 2.2.51"
15645         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15646
15647         cp /etc/hosts $DIR/$tfile
15648
15649         fid=$($LFS path2fid $DIR/$tfile)
15650         rc=$?
15651         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15652
15653         dot_lustre_fid_permission_check "$fid" $DIR ||
15654                 error "dot lustre permission check $fid failed"
15655
15656         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15657
15658         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15659
15660         touch $MOUNT/.lustre/file &&
15661                 error "creation is not allowed under .lustre"
15662
15663         mkdir $MOUNT/.lustre/dir &&
15664                 error "mkdir is not allowed under .lustre"
15665
15666         rm -rf $DIR/$tfile
15667 }
15668 run_test 154a "Open-by-FID"
15669
15670 test_154b() {
15671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15672         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15674         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15675                 skip "Need MDS version at least 2.2.51"
15676
15677         local remote_dir=$DIR/$tdir/remote_dir
15678         local MDTIDX=1
15679         local rc=0
15680
15681         mkdir -p $DIR/$tdir
15682         $LFS mkdir -i $MDTIDX $remote_dir ||
15683                 error "create remote directory failed"
15684
15685         cp /etc/hosts $remote_dir/$tfile
15686
15687         fid=$($LFS path2fid $remote_dir/$tfile)
15688         rc=$?
15689         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15690
15691         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15692                 error "dot lustre permission check $fid failed"
15693         rm -rf $DIR/$tdir
15694 }
15695 run_test 154b "Open-by-FID for remote directory"
15696
15697 test_154c() {
15698         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15699                 skip "Need MDS version at least 2.4.1"
15700
15701         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15702         local FID1=$($LFS path2fid $DIR/$tfile.1)
15703         local FID2=$($LFS path2fid $DIR/$tfile.2)
15704         local FID3=$($LFS path2fid $DIR/$tfile.3)
15705
15706         local N=1
15707         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15708                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15709                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15710                 local want=FID$N
15711                 [ "$FID" = "${!want}" ] ||
15712                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15713                 N=$((N + 1))
15714         done
15715
15716         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15717         do
15718                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15719                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15720                 N=$((N + 1))
15721         done
15722 }
15723 run_test 154c "lfs path2fid and fid2path multiple arguments"
15724
15725 test_154d() {
15726         remote_mds_nodsh && skip "remote MDS with nodsh"
15727         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15728                 skip "Need MDS version at least 2.5.53"
15729
15730         if remote_mds; then
15731                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15732         else
15733                 nid="0@lo"
15734         fi
15735         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15736         local fd
15737         local cmd
15738
15739         rm -f $DIR/$tfile
15740         touch $DIR/$tfile
15741
15742         local fid=$($LFS path2fid $DIR/$tfile)
15743         # Open the file
15744         fd=$(free_fd)
15745         cmd="exec $fd<$DIR/$tfile"
15746         eval $cmd
15747         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15748         echo "$fid_list" | grep "$fid"
15749         rc=$?
15750
15751         cmd="exec $fd>/dev/null"
15752         eval $cmd
15753         if [ $rc -ne 0 ]; then
15754                 error "FID $fid not found in open files list $fid_list"
15755         fi
15756 }
15757 run_test 154d "Verify open file fid"
15758
15759 test_154e()
15760 {
15761         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15762                 skip "Need MDS version at least 2.6.50"
15763
15764         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15765                 error ".lustre returned by readdir"
15766         fi
15767 }
15768 run_test 154e ".lustre is not returned by readdir"
15769
15770 test_154f() {
15771         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15772
15773         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15774         mkdir_on_mdt0 $DIR/$tdir
15775         # test dirs inherit from its stripe
15776         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15777         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15778         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15779         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15780         touch $DIR/f
15781
15782         # get fid of parents
15783         local FID0=$($LFS path2fid $DIR/$tdir)
15784         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15785         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15786         local FID3=$($LFS path2fid $DIR)
15787
15788         # check that path2fid --parents returns expected <parent_fid>/name
15789         # 1) test for a directory (single parent)
15790         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15791         [ "$parent" == "$FID0/foo1" ] ||
15792                 error "expected parent: $FID0/foo1, got: $parent"
15793
15794         # 2) test for a file with nlink > 1 (multiple parents)
15795         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15796         echo "$parent" | grep -F "$FID1/$tfile" ||
15797                 error "$FID1/$tfile not returned in parent list"
15798         echo "$parent" | grep -F "$FID2/link" ||
15799                 error "$FID2/link not returned in parent list"
15800
15801         # 3) get parent by fid
15802         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15803         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15804         echo "$parent" | grep -F "$FID1/$tfile" ||
15805                 error "$FID1/$tfile not returned in parent list (by fid)"
15806         echo "$parent" | grep -F "$FID2/link" ||
15807                 error "$FID2/link not returned in parent list (by fid)"
15808
15809         # 4) test for entry in root directory
15810         parent=$($LFS path2fid --parents $DIR/f)
15811         echo "$parent" | grep -F "$FID3/f" ||
15812                 error "$FID3/f not returned in parent list"
15813
15814         # 5) test it on root directory
15815         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15816                 error "$MOUNT should not have parents"
15817
15818         # enable xattr caching and check that linkea is correctly updated
15819         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15820         save_lustre_params client "llite.*.xattr_cache" > $save
15821         lctl set_param llite.*.xattr_cache 1
15822
15823         # 6.1) linkea update on rename
15824         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15825
15826         # get parents by fid
15827         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15828         # foo1 should no longer be returned in parent list
15829         echo "$parent" | grep -F "$FID1" &&
15830                 error "$FID1 should no longer be in parent list"
15831         # the new path should appear
15832         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15833                 error "$FID2/$tfile.moved is not in parent list"
15834
15835         # 6.2) linkea update on unlink
15836         rm -f $DIR/$tdir/foo2/link
15837         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15838         # foo2/link should no longer be returned in parent list
15839         echo "$parent" | grep -F "$FID2/link" &&
15840                 error "$FID2/link should no longer be in parent list"
15841         true
15842
15843         rm -f $DIR/f
15844         restore_lustre_params < $save
15845         rm -f $save
15846 }
15847 run_test 154f "get parent fids by reading link ea"
15848
15849 test_154g()
15850 {
15851         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15852            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15853                 skip "Need MDS version at least 2.6.92"
15854
15855         mkdir_on_mdt0 $DIR/$tdir
15856         llapi_fid_test -d $DIR/$tdir
15857 }
15858 run_test 154g "various llapi FID tests"
15859
15860 test_155_small_load() {
15861     local temp=$TMP/$tfile
15862     local file=$DIR/$tfile
15863
15864     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15865         error "dd of=$temp bs=6096 count=1 failed"
15866     cp $temp $file
15867     cancel_lru_locks $OSC
15868     cmp $temp $file || error "$temp $file differ"
15869
15870     $TRUNCATE $temp 6000
15871     $TRUNCATE $file 6000
15872     cmp $temp $file || error "$temp $file differ (truncate1)"
15873
15874     echo "12345" >>$temp
15875     echo "12345" >>$file
15876     cmp $temp $file || error "$temp $file differ (append1)"
15877
15878     echo "12345" >>$temp
15879     echo "12345" >>$file
15880     cmp $temp $file || error "$temp $file differ (append2)"
15881
15882     rm -f $temp $file
15883     true
15884 }
15885
15886 test_155_big_load() {
15887         remote_ost_nodsh && skip "remote OST with nodsh"
15888
15889         local temp=$TMP/$tfile
15890         local file=$DIR/$tfile
15891
15892         free_min_max
15893         local cache_size=$(do_facet ost$((MAXI+1)) \
15894                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15895
15896         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15897         # pre-set value
15898         if [ -z "$cache_size" ]; then
15899                 cache_size=256
15900         fi
15901         local large_file_size=$((cache_size * 2))
15902
15903         echo "OSS cache size: $cache_size KB"
15904         echo "Large file size: $large_file_size KB"
15905
15906         [ $MAXV -le $large_file_size ] &&
15907                 skip_env "max available OST size needs > $large_file_size KB"
15908
15909         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15910
15911         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15912                 error "dd of=$temp bs=$large_file_size count=1k failed"
15913         cp $temp $file
15914         ls -lh $temp $file
15915         cancel_lru_locks osc
15916         cmp $temp $file || error "$temp $file differ"
15917
15918         rm -f $temp $file
15919         true
15920 }
15921
15922 save_writethrough() {
15923         local facets=$(get_facets OST)
15924
15925         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15926 }
15927
15928 test_155a() {
15929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15930
15931         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15932
15933         save_writethrough $p
15934
15935         set_cache read on
15936         set_cache writethrough on
15937         test_155_small_load
15938         restore_lustre_params < $p
15939         rm -f $p
15940 }
15941 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15942
15943 test_155b() {
15944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15945
15946         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15947
15948         save_writethrough $p
15949
15950         set_cache read on
15951         set_cache writethrough off
15952         test_155_small_load
15953         restore_lustre_params < $p
15954         rm -f $p
15955 }
15956 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15957
15958 test_155c() {
15959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15960
15961         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15962
15963         save_writethrough $p
15964
15965         set_cache read off
15966         set_cache writethrough on
15967         test_155_small_load
15968         restore_lustre_params < $p
15969         rm -f $p
15970 }
15971 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15972
15973 test_155d() {
15974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15975
15976         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15977
15978         save_writethrough $p
15979
15980         set_cache read off
15981         set_cache writethrough off
15982         test_155_small_load
15983         restore_lustre_params < $p
15984         rm -f $p
15985 }
15986 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15987
15988 test_155e() {
15989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15990
15991         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15992
15993         save_writethrough $p
15994
15995         set_cache read on
15996         set_cache writethrough on
15997         test_155_big_load
15998         restore_lustre_params < $p
15999         rm -f $p
16000 }
16001 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16002
16003 test_155f() {
16004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16005
16006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16007
16008         save_writethrough $p
16009
16010         set_cache read on
16011         set_cache writethrough off
16012         test_155_big_load
16013         restore_lustre_params < $p
16014         rm -f $p
16015 }
16016 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16017
16018 test_155g() {
16019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16020
16021         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16022
16023         save_writethrough $p
16024
16025         set_cache read off
16026         set_cache writethrough on
16027         test_155_big_load
16028         restore_lustre_params < $p
16029         rm -f $p
16030 }
16031 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16032
16033 test_155h() {
16034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16035
16036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16037
16038         save_writethrough $p
16039
16040         set_cache read off
16041         set_cache writethrough off
16042         test_155_big_load
16043         restore_lustre_params < $p
16044         rm -f $p
16045 }
16046 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16047
16048 test_156() {
16049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16050         remote_ost_nodsh && skip "remote OST with nodsh"
16051         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16052                 skip "stats not implemented on old servers"
16053         [ "$ost1_FSTYPE" = "zfs" ] &&
16054                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16055
16056         local CPAGES=3
16057         local BEFORE
16058         local AFTER
16059         local file="$DIR/$tfile"
16060         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16061
16062         save_writethrough $p
16063         roc_hit_init
16064
16065         log "Turn on read and write cache"
16066         set_cache read on
16067         set_cache writethrough on
16068
16069         log "Write data and read it back."
16070         log "Read should be satisfied from the cache."
16071         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16072         BEFORE=$(roc_hit)
16073         cancel_lru_locks osc
16074         cat $file >/dev/null
16075         AFTER=$(roc_hit)
16076         if ! let "AFTER - BEFORE == CPAGES"; then
16077                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16078         else
16079                 log "cache hits: before: $BEFORE, after: $AFTER"
16080         fi
16081
16082         log "Read again; it should be satisfied from the cache."
16083         BEFORE=$AFTER
16084         cancel_lru_locks osc
16085         cat $file >/dev/null
16086         AFTER=$(roc_hit)
16087         if ! let "AFTER - BEFORE == CPAGES"; then
16088                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16089         else
16090                 log "cache hits:: before: $BEFORE, after: $AFTER"
16091         fi
16092
16093         log "Turn off the read cache and turn on the write cache"
16094         set_cache read off
16095         set_cache writethrough on
16096
16097         log "Read again; it should be satisfied from the cache."
16098         BEFORE=$(roc_hit)
16099         cancel_lru_locks osc
16100         cat $file >/dev/null
16101         AFTER=$(roc_hit)
16102         if ! let "AFTER - BEFORE == CPAGES"; then
16103                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16104         else
16105                 log "cache hits:: before: $BEFORE, after: $AFTER"
16106         fi
16107
16108         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16109                 # > 2.12.56 uses pagecache if cached
16110                 log "Read again; it should not be satisfied from the cache."
16111                 BEFORE=$AFTER
16112                 cancel_lru_locks osc
16113                 cat $file >/dev/null
16114                 AFTER=$(roc_hit)
16115                 if ! let "AFTER - BEFORE == 0"; then
16116                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16117                 else
16118                         log "cache hits:: before: $BEFORE, after: $AFTER"
16119                 fi
16120         fi
16121
16122         log "Write data and read it back."
16123         log "Read should be satisfied from the cache."
16124         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16125         BEFORE=$(roc_hit)
16126         cancel_lru_locks osc
16127         cat $file >/dev/null
16128         AFTER=$(roc_hit)
16129         if ! let "AFTER - BEFORE == CPAGES"; then
16130                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16131         else
16132                 log "cache hits:: before: $BEFORE, after: $AFTER"
16133         fi
16134
16135         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16136                 # > 2.12.56 uses pagecache if cached
16137                 log "Read again; it should not be satisfied from the cache."
16138                 BEFORE=$AFTER
16139                 cancel_lru_locks osc
16140                 cat $file >/dev/null
16141                 AFTER=$(roc_hit)
16142                 if ! let "AFTER - BEFORE == 0"; then
16143                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16144                 else
16145                         log "cache hits:: before: $BEFORE, after: $AFTER"
16146                 fi
16147         fi
16148
16149         log "Turn off read and write cache"
16150         set_cache read off
16151         set_cache writethrough off
16152
16153         log "Write data and read it back"
16154         log "It should not be satisfied from the cache."
16155         rm -f $file
16156         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16157         cancel_lru_locks osc
16158         BEFORE=$(roc_hit)
16159         cat $file >/dev/null
16160         AFTER=$(roc_hit)
16161         if ! let "AFTER - BEFORE == 0"; then
16162                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16163         else
16164                 log "cache hits:: before: $BEFORE, after: $AFTER"
16165         fi
16166
16167         log "Turn on the read cache and turn off the write cache"
16168         set_cache read on
16169         set_cache writethrough off
16170
16171         log "Write data and read it back"
16172         log "It should not be satisfied from the cache."
16173         rm -f $file
16174         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16175         BEFORE=$(roc_hit)
16176         cancel_lru_locks osc
16177         cat $file >/dev/null
16178         AFTER=$(roc_hit)
16179         if ! let "AFTER - BEFORE == 0"; then
16180                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16181         else
16182                 log "cache hits:: before: $BEFORE, after: $AFTER"
16183         fi
16184
16185         log "Read again; it should be satisfied from the cache."
16186         BEFORE=$(roc_hit)
16187         cancel_lru_locks osc
16188         cat $file >/dev/null
16189         AFTER=$(roc_hit)
16190         if ! let "AFTER - BEFORE == CPAGES"; then
16191                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16192         else
16193                 log "cache hits:: before: $BEFORE, after: $AFTER"
16194         fi
16195
16196         restore_lustre_params < $p
16197         rm -f $p $file
16198 }
16199 run_test 156 "Verification of tunables"
16200
16201 test_160a() {
16202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16203         remote_mds_nodsh && skip "remote MDS with nodsh"
16204         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16205                 skip "Need MDS version at least 2.2.0"
16206
16207         changelog_register || error "changelog_register failed"
16208         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16209         changelog_users $SINGLEMDS | grep -q $cl_user ||
16210                 error "User $cl_user not found in changelog_users"
16211
16212         mkdir_on_mdt0 $DIR/$tdir
16213
16214         # change something
16215         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16216         changelog_clear 0 || error "changelog_clear failed"
16217         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16218         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16219         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16220         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16221         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16222         rm $DIR/$tdir/pics/desktop.jpg
16223
16224         echo "verifying changelog mask"
16225         changelog_chmask "-MKDIR"
16226         changelog_chmask "-CLOSE"
16227
16228         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16229         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16230
16231         changelog_chmask "+MKDIR"
16232         changelog_chmask "+CLOSE"
16233
16234         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16235         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16236
16237         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16238         CLOSES=$(changelog_dump | grep -c "CLOSE")
16239         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16240         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16241
16242         # verify contents
16243         echo "verifying target fid"
16244         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16245         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16246         [ "$fidc" == "$fidf" ] ||
16247                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16248         echo "verifying parent fid"
16249         # The FID returned from the Changelog may be the directory shard on
16250         # a different MDT, and not the FID returned by path2fid on the parent.
16251         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16252         # since this is what will matter when recreating this file in the tree.
16253         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16254         local pathp=$($LFS fid2path $MOUNT "$fidp")
16255         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16256                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16257
16258         echo "getting records for $cl_user"
16259         changelog_users $SINGLEMDS
16260         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16261         local nclr=3
16262         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16263                 error "changelog_clear failed"
16264         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16265         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16266         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16267                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16268
16269         local min0_rec=$(changelog_users $SINGLEMDS |
16270                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16271         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16272                           awk '{ print $1; exit; }')
16273
16274         changelog_dump | tail -n 5
16275         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16276         [ $first_rec == $((min0_rec + 1)) ] ||
16277                 error "first index should be $min0_rec + 1 not $first_rec"
16278
16279         # LU-3446 changelog index reset on MDT restart
16280         local cur_rec1=$(changelog_users $SINGLEMDS |
16281                          awk '/^current.index:/ { print $NF }')
16282         changelog_clear 0 ||
16283                 error "clear all changelog records for $cl_user failed"
16284         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16285         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16286                 error "Fail to start $SINGLEMDS"
16287         local cur_rec2=$(changelog_users $SINGLEMDS |
16288                          awk '/^current.index:/ { print $NF }')
16289         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16290         [ $cur_rec1 == $cur_rec2 ] ||
16291                 error "current index should be $cur_rec1 not $cur_rec2"
16292
16293         echo "verifying users from this test are deregistered"
16294         changelog_deregister || error "changelog_deregister failed"
16295         changelog_users $SINGLEMDS | grep -q $cl_user &&
16296                 error "User '$cl_user' still in changelog_users"
16297
16298         # lctl get_param -n mdd.*.changelog_users
16299         # current_index: 144
16300         # ID    index (idle seconds)
16301         # cl3   144   (2) mask=<list>
16302         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16303                 # this is the normal case where all users were deregistered
16304                 # make sure no new records are added when no users are present
16305                 local last_rec1=$(changelog_users $SINGLEMDS |
16306                                   awk '/^current.index:/ { print $NF }')
16307                 touch $DIR/$tdir/chloe
16308                 local last_rec2=$(changelog_users $SINGLEMDS |
16309                                   awk '/^current.index:/ { print $NF }')
16310                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16311                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16312         else
16313                 # any changelog users must be leftovers from a previous test
16314                 changelog_users $SINGLEMDS
16315                 echo "other changelog users; can't verify off"
16316         fi
16317 }
16318 run_test 160a "changelog sanity"
16319
16320 test_160b() { # LU-3587
16321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16322         remote_mds_nodsh && skip "remote MDS with nodsh"
16323         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16324                 skip "Need MDS version at least 2.2.0"
16325
16326         changelog_register || error "changelog_register failed"
16327         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16328         changelog_users $SINGLEMDS | grep -q $cl_user ||
16329                 error "User '$cl_user' not found in changelog_users"
16330
16331         local longname1=$(str_repeat a 255)
16332         local longname2=$(str_repeat b 255)
16333
16334         cd $DIR
16335         echo "creating very long named file"
16336         touch $longname1 || error "create of '$longname1' failed"
16337         echo "renaming very long named file"
16338         mv $longname1 $longname2
16339
16340         changelog_dump | grep RENME | tail -n 5
16341         rm -f $longname2
16342 }
16343 run_test 160b "Verify that very long rename doesn't crash in changelog"
16344
16345 test_160c() {
16346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16347         remote_mds_nodsh && skip "remote MDS with nodsh"
16348
16349         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16350                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16351                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16352                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16353
16354         local rc=0
16355
16356         # Registration step
16357         changelog_register || error "changelog_register failed"
16358
16359         rm -rf $DIR/$tdir
16360         mkdir -p $DIR/$tdir
16361         $MCREATE $DIR/$tdir/foo_160c
16362         changelog_chmask "-TRUNC"
16363         $TRUNCATE $DIR/$tdir/foo_160c 200
16364         changelog_chmask "+TRUNC"
16365         $TRUNCATE $DIR/$tdir/foo_160c 199
16366         changelog_dump | tail -n 5
16367         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16368         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16369 }
16370 run_test 160c "verify that changelog log catch the truncate event"
16371
16372 test_160d() {
16373         remote_mds_nodsh && skip "remote MDS with nodsh"
16374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16376         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16377                 skip "Need MDS version at least 2.7.60"
16378
16379         # Registration step
16380         changelog_register || error "changelog_register failed"
16381
16382         mkdir -p $DIR/$tdir/migrate_dir
16383         changelog_clear 0 || error "changelog_clear failed"
16384
16385         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16386         changelog_dump | tail -n 5
16387         local migrates=$(changelog_dump | grep -c "MIGRT")
16388         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16389 }
16390 run_test 160d "verify that changelog log catch the migrate event"
16391
16392 test_160e() {
16393         remote_mds_nodsh && skip "remote MDS with nodsh"
16394
16395         # Create a user
16396         changelog_register || error "changelog_register failed"
16397
16398         local MDT0=$(facet_svc $SINGLEMDS)
16399         local rc
16400
16401         # No user (expect fail)
16402         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16403         rc=$?
16404         if [ $rc -eq 0 ]; then
16405                 error "Should fail without user"
16406         elif [ $rc -ne 4 ]; then
16407                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16408         fi
16409
16410         # Delete a future user (expect fail)
16411         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16412         rc=$?
16413         if [ $rc -eq 0 ]; then
16414                 error "Deleted non-existant user cl77"
16415         elif [ $rc -ne 2 ]; then
16416                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16417         fi
16418
16419         # Clear to a bad index (1 billion should be safe)
16420         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16421         rc=$?
16422
16423         if [ $rc -eq 0 ]; then
16424                 error "Successfully cleared to invalid CL index"
16425         elif [ $rc -ne 22 ]; then
16426                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16427         fi
16428 }
16429 run_test 160e "changelog negative testing (should return errors)"
16430
16431 test_160f() {
16432         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16433         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16434                 skip "Need MDS version at least 2.10.56"
16435
16436         local mdts=$(comma_list $(mdts_nodes))
16437
16438         # Create a user
16439         changelog_register || error "first changelog_register failed"
16440         changelog_register || error "second changelog_register failed"
16441         local cl_users
16442         declare -A cl_user1
16443         declare -A cl_user2
16444         local user_rec1
16445         local user_rec2
16446         local i
16447
16448         # generate some changelog records to accumulate on each MDT
16449         # use all_char because created files should be evenly distributed
16450         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16451                 error "test_mkdir $tdir failed"
16452         log "$(date +%s): creating first files"
16453         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16454                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16455                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16456         done
16457
16458         # check changelogs have been generated
16459         local start=$SECONDS
16460         local idle_time=$((MDSCOUNT * 5 + 5))
16461         local nbcl=$(changelog_dump | wc -l)
16462         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16463
16464         for param in "changelog_max_idle_time=$idle_time" \
16465                      "changelog_gc=1" \
16466                      "changelog_min_gc_interval=2" \
16467                      "changelog_min_free_cat_entries=3"; do
16468                 local MDT0=$(facet_svc $SINGLEMDS)
16469                 local var="${param%=*}"
16470                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16471
16472                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16473                 do_nodes $mdts $LCTL set_param mdd.*.$param
16474         done
16475
16476         # force cl_user2 to be idle (1st part), but also cancel the
16477         # cl_user1 records so that it is not evicted later in the test.
16478         local sleep1=$((idle_time / 2))
16479         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16480         sleep $sleep1
16481
16482         # simulate changelog catalog almost full
16483         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16484         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16485
16486         for i in $(seq $MDSCOUNT); do
16487                 cl_users=(${CL_USERS[mds$i]})
16488                 cl_user1[mds$i]="${cl_users[0]}"
16489                 cl_user2[mds$i]="${cl_users[1]}"
16490
16491                 [ -n "${cl_user1[mds$i]}" ] ||
16492                         error "mds$i: no user registered"
16493                 [ -n "${cl_user2[mds$i]}" ] ||
16494                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16495
16496                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16497                 [ -n "$user_rec1" ] ||
16498                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16499                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16500                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16501                 [ -n "$user_rec2" ] ||
16502                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16503                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16504                      "$user_rec1 + 2 == $user_rec2"
16505                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16506                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16507                               "$user_rec1 + 2, but is $user_rec2"
16508                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16509                 [ -n "$user_rec2" ] ||
16510                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16511                 [ $user_rec1 == $user_rec2 ] ||
16512                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16513                               "$user_rec1, but is $user_rec2"
16514         done
16515
16516         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16517         local sleep2=$((idle_time - (SECONDS - start) + 1))
16518         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16519         sleep $sleep2
16520
16521         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16522         # cl_user1 should be OK because it recently processed records.
16523         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16524         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16525                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16526                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16527         done
16528
16529         # ensure gc thread is done
16530         for i in $(mdts_nodes); do
16531                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16532                         error "$i: GC-thread not done"
16533         done
16534
16535         local first_rec
16536         for (( i = 1; i <= MDSCOUNT; i++ )); do
16537                 # check cl_user1 still registered
16538                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16539                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16540                 # check cl_user2 unregistered
16541                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16542                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16543
16544                 # check changelogs are present and starting at $user_rec1 + 1
16545                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16546                 [ -n "$user_rec1" ] ||
16547                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16548                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16549                             awk '{ print $1; exit; }')
16550
16551                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16552                 [ $((user_rec1 + 1)) == $first_rec ] ||
16553                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16554         done
16555 }
16556 run_test 160f "changelog garbage collect (timestamped users)"
16557
16558 test_160g() {
16559         remote_mds_nodsh && skip "remote MDS with nodsh"
16560         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16561                 skip "Need MDS version at least 2.14.55"
16562
16563         local mdts=$(comma_list $(mdts_nodes))
16564
16565         # Create a user
16566         changelog_register || error "first changelog_register failed"
16567         changelog_register || error "second changelog_register failed"
16568         local cl_users
16569         declare -A cl_user1
16570         declare -A cl_user2
16571         local user_rec1
16572         local user_rec2
16573         local i
16574
16575         # generate some changelog records to accumulate on each MDT
16576         # use all_char because created files should be evenly distributed
16577         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16578                 error "test_mkdir $tdir failed"
16579         for ((i = 0; i < MDSCOUNT; i++)); do
16580                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16581                         error "create $DIR/$tdir/d$i.1 failed"
16582         done
16583
16584         # check changelogs have been generated
16585         local nbcl=$(changelog_dump | wc -l)
16586         (( $nbcl > 0 )) || error "no changelogs found"
16587
16588         # reduce the max_idle_indexes value to make sure we exceed it
16589         for param in "changelog_max_idle_indexes=2" \
16590                      "changelog_gc=1" \
16591                      "changelog_min_gc_interval=2"; do
16592                 local MDT0=$(facet_svc $SINGLEMDS)
16593                 local var="${param%=*}"
16594                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16595
16596                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16597                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16598                         error "unable to set mdd.*.$param"
16599         done
16600
16601         local start=$SECONDS
16602         for i in $(seq $MDSCOUNT); do
16603                 cl_users=(${CL_USERS[mds$i]})
16604                 cl_user1[mds$i]="${cl_users[0]}"
16605                 cl_user2[mds$i]="${cl_users[1]}"
16606
16607                 [ -n "${cl_user1[mds$i]}" ] ||
16608                         error "mds$i: user1 is not registered"
16609                 [ -n "${cl_user2[mds$i]}" ] ||
16610                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16611
16612                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16613                 [ -n "$user_rec1" ] ||
16614                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16615                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16616                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16617                 [ -n "$user_rec2" ] ||
16618                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16619                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16620                      "$user_rec1 + 2 == $user_rec2"
16621                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16622                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16623                               "expected $user_rec1 + 2, but is $user_rec2"
16624                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16625                 [ -n "$user_rec2" ] ||
16626                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16627                 [ $user_rec1 == $user_rec2 ] ||
16628                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16629                               "expected $user_rec1, but is $user_rec2"
16630         done
16631
16632         # ensure we are past the previous changelog_min_gc_interval set above
16633         local sleep2=$((start + 2 - SECONDS))
16634         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16635         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16636         # cl_user1 should be OK because it recently processed records.
16637         for ((i = 0; i < MDSCOUNT; i++)); do
16638                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16639                         error "create $DIR/$tdir/d$i.3 failed"
16640         done
16641
16642         # ensure gc thread is done
16643         for i in $(mdts_nodes); do
16644                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16645                         error "$i: GC-thread not done"
16646         done
16647
16648         local first_rec
16649         for (( i = 1; i <= MDSCOUNT; i++ )); do
16650                 # check cl_user1 still registered
16651                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16652                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16653                 # check cl_user2 unregistered
16654                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16655                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16656
16657                 # check changelogs are present and starting at $user_rec1 + 1
16658                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16659                 [ -n "$user_rec1" ] ||
16660                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16661                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16662                             awk '{ print $1; exit; }')
16663
16664                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16665                 [ $((user_rec1 + 1)) == $first_rec ] ||
16666                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16667         done
16668 }
16669 run_test 160g "changelog garbage collect on idle records"
16670
16671 test_160h() {
16672         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16673         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16674                 skip "Need MDS version at least 2.10.56"
16675
16676         local mdts=$(comma_list $(mdts_nodes))
16677
16678         # Create a user
16679         changelog_register || error "first changelog_register failed"
16680         changelog_register || error "second changelog_register failed"
16681         local cl_users
16682         declare -A cl_user1
16683         declare -A cl_user2
16684         local user_rec1
16685         local user_rec2
16686         local i
16687
16688         # generate some changelog records to accumulate on each MDT
16689         # use all_char because created files should be evenly distributed
16690         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16691                 error "test_mkdir $tdir failed"
16692         for ((i = 0; i < MDSCOUNT; i++)); do
16693                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16694                         error "create $DIR/$tdir/d$i.1 failed"
16695         done
16696
16697         # check changelogs have been generated
16698         local nbcl=$(changelog_dump | wc -l)
16699         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16700
16701         for param in "changelog_max_idle_time=10" \
16702                      "changelog_gc=1" \
16703                      "changelog_min_gc_interval=2"; do
16704                 local MDT0=$(facet_svc $SINGLEMDS)
16705                 local var="${param%=*}"
16706                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16707
16708                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16709                 do_nodes $mdts $LCTL set_param mdd.*.$param
16710         done
16711
16712         # force cl_user2 to be idle (1st part)
16713         sleep 9
16714
16715         for i in $(seq $MDSCOUNT); do
16716                 cl_users=(${CL_USERS[mds$i]})
16717                 cl_user1[mds$i]="${cl_users[0]}"
16718                 cl_user2[mds$i]="${cl_users[1]}"
16719
16720                 [ -n "${cl_user1[mds$i]}" ] ||
16721                         error "mds$i: no user registered"
16722                 [ -n "${cl_user2[mds$i]}" ] ||
16723                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16724
16725                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16726                 [ -n "$user_rec1" ] ||
16727                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16728                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16729                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16730                 [ -n "$user_rec2" ] ||
16731                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16732                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16733                      "$user_rec1 + 2 == $user_rec2"
16734                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16735                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16736                               "$user_rec1 + 2, but is $user_rec2"
16737                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16738                 [ -n "$user_rec2" ] ||
16739                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16740                 [ $user_rec1 == $user_rec2 ] ||
16741                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16742                               "$user_rec1, but is $user_rec2"
16743         done
16744
16745         # force cl_user2 to be idle (2nd part) and to reach
16746         # changelog_max_idle_time
16747         sleep 2
16748
16749         # force each GC-thread start and block then
16750         # one per MDT/MDD, set fail_val accordingly
16751         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16752         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16753
16754         # generate more changelogs to trigger fail_loc
16755         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16756                 error "create $DIR/$tdir/${tfile}bis failed"
16757
16758         # stop MDT to stop GC-thread, should be done in back-ground as it will
16759         # block waiting for the thread to be released and exit
16760         declare -A stop_pids
16761         for i in $(seq $MDSCOUNT); do
16762                 stop mds$i &
16763                 stop_pids[mds$i]=$!
16764         done
16765
16766         for i in $(mdts_nodes); do
16767                 local facet
16768                 local nb=0
16769                 local facets=$(facets_up_on_host $i)
16770
16771                 for facet in ${facets//,/ }; do
16772                         if [[ $facet == mds* ]]; then
16773                                 nb=$((nb + 1))
16774                         fi
16775                 done
16776                 # ensure each MDS's gc threads are still present and all in "R"
16777                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16778                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16779                         error "$i: expected $nb GC-thread"
16780                 wait_update $i \
16781                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16782                         "R" 20 ||
16783                         error "$i: GC-thread not found in R-state"
16784                 # check umounts of each MDT on MDS have reached kthread_stop()
16785                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16786                         error "$i: expected $nb umount"
16787                 wait_update $i \
16788                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16789                         error "$i: umount not found in D-state"
16790         done
16791
16792         # release all GC-threads
16793         do_nodes $mdts $LCTL set_param fail_loc=0
16794
16795         # wait for MDT stop to complete
16796         for i in $(seq $MDSCOUNT); do
16797                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16798         done
16799
16800         # XXX
16801         # may try to check if any orphan changelog records are present
16802         # via ldiskfs/zfs and llog_reader...
16803
16804         # re-start/mount MDTs
16805         for i in $(seq $MDSCOUNT); do
16806                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16807                         error "Fail to start mds$i"
16808         done
16809
16810         local first_rec
16811         for i in $(seq $MDSCOUNT); do
16812                 # check cl_user1 still registered
16813                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16815                 # check cl_user2 unregistered
16816                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16817                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16818
16819                 # check changelogs are present and starting at $user_rec1 + 1
16820                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16821                 [ -n "$user_rec1" ] ||
16822                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16823                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16824                             awk '{ print $1; exit; }')
16825
16826                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16827                 [ $((user_rec1 + 1)) == $first_rec ] ||
16828                         error "mds$i: first index should be $user_rec1 + 1, " \
16829                               "but is $first_rec"
16830         done
16831 }
16832 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16833               "during mount"
16834
16835 test_160i() {
16836
16837         local mdts=$(comma_list $(mdts_nodes))
16838
16839         changelog_register || error "first changelog_register failed"
16840
16841         # generate some changelog records to accumulate on each MDT
16842         # use all_char because created files should be evenly distributed
16843         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16844                 error "test_mkdir $tdir failed"
16845         for ((i = 0; i < MDSCOUNT; i++)); do
16846                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16847                         error "create $DIR/$tdir/d$i.1 failed"
16848         done
16849
16850         # check changelogs have been generated
16851         local nbcl=$(changelog_dump | wc -l)
16852         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16853
16854         # simulate race between register and unregister
16855         # XXX as fail_loc is set per-MDS, with DNE configs the race
16856         # simulation will only occur for one MDT per MDS and for the
16857         # others the normal race scenario will take place
16858         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16859         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16860         do_nodes $mdts $LCTL set_param fail_val=1
16861
16862         # unregister 1st user
16863         changelog_deregister &
16864         local pid1=$!
16865         # wait some time for deregister work to reach race rdv
16866         sleep 2
16867         # register 2nd user
16868         changelog_register || error "2nd user register failed"
16869
16870         wait $pid1 || error "1st user deregister failed"
16871
16872         local i
16873         local last_rec
16874         declare -A LAST_REC
16875         for i in $(seq $MDSCOUNT); do
16876                 if changelog_users mds$i | grep "^cl"; then
16877                         # make sure new records are added with one user present
16878                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16879                                           awk '/^current.index:/ { print $NF }')
16880                 else
16881                         error "mds$i has no user registered"
16882                 fi
16883         done
16884
16885         # generate more changelog records to accumulate on each MDT
16886         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16887                 error "create $DIR/$tdir/${tfile}bis failed"
16888
16889         for i in $(seq $MDSCOUNT); do
16890                 last_rec=$(changelog_users $SINGLEMDS |
16891                            awk '/^current.index:/ { print $NF }')
16892                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16893                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16894                         error "changelogs are off on mds$i"
16895         done
16896 }
16897 run_test 160i "changelog user register/unregister race"
16898
16899 test_160j() {
16900         remote_mds_nodsh && skip "remote MDS with nodsh"
16901         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16902                 skip "Need MDS version at least 2.12.56"
16903
16904         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16905         stack_trap "umount $MOUNT2" EXIT
16906
16907         changelog_register || error "first changelog_register failed"
16908         stack_trap "changelog_deregister" EXIT
16909
16910         # generate some changelog
16911         # use all_char because created files should be evenly distributed
16912         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16913                 error "mkdir $tdir failed"
16914         for ((i = 0; i < MDSCOUNT; i++)); do
16915                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16916                         error "create $DIR/$tdir/d$i.1 failed"
16917         done
16918
16919         # open the changelog device
16920         exec 3>/dev/changelog-$FSNAME-MDT0000
16921         stack_trap "exec 3>&-" EXIT
16922         exec 4</dev/changelog-$FSNAME-MDT0000
16923         stack_trap "exec 4<&-" EXIT
16924
16925         # umount the first lustre mount
16926         umount $MOUNT
16927         stack_trap "mount_client $MOUNT" EXIT
16928
16929         # read changelog, which may or may not fail, but should not crash
16930         cat <&4 >/dev/null
16931
16932         # clear changelog
16933         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16934         changelog_users $SINGLEMDS | grep -q $cl_user ||
16935                 error "User $cl_user not found in changelog_users"
16936
16937         printf 'clear:'$cl_user':0' >&3
16938 }
16939 run_test 160j "client can be umounted while its chanangelog is being used"
16940
16941 test_160k() {
16942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16943         remote_mds_nodsh && skip "remote MDS with nodsh"
16944
16945         mkdir -p $DIR/$tdir/1/1
16946
16947         changelog_register || error "changelog_register failed"
16948         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16949
16950         changelog_users $SINGLEMDS | grep -q $cl_user ||
16951                 error "User '$cl_user' not found in changelog_users"
16952 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16953         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16954         rmdir $DIR/$tdir/1/1 & sleep 1
16955         mkdir $DIR/$tdir/2
16956         touch $DIR/$tdir/2/2
16957         rm -rf $DIR/$tdir/2
16958
16959         wait
16960         sleep 4
16961
16962         changelog_dump | grep rmdir || error "rmdir not recorded"
16963 }
16964 run_test 160k "Verify that changelog records are not lost"
16965
16966 # Verifies that a file passed as a parameter has recently had an operation
16967 # performed on it that has generated an MTIME changelog which contains the
16968 # correct parent FID. As files might reside on a different MDT from the
16969 # parent directory in DNE configurations, the FIDs are translated to paths
16970 # before being compared, which should be identical
16971 compare_mtime_changelog() {
16972         local file="${1}"
16973         local mdtidx
16974         local mtime
16975         local cl_fid
16976         local pdir
16977         local dir
16978
16979         mdtidx=$($LFS getstripe --mdt-index $file)
16980         mdtidx=$(printf "%04x" $mdtidx)
16981
16982         # Obtain the parent FID from the MTIME changelog
16983         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16984         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16985
16986         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16987         [ -z "$cl_fid" ] && error "parent FID not present"
16988
16989         # Verify that the path for the parent FID is the same as the path for
16990         # the test directory
16991         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16992
16993         dir=$(dirname $1)
16994
16995         [[ "${pdir%/}" == "$dir" ]] ||
16996                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16997 }
16998
16999 test_160l() {
17000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17001
17002         remote_mds_nodsh && skip "remote MDS with nodsh"
17003         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17004                 skip "Need MDS version at least 2.13.55"
17005
17006         local cl_user
17007
17008         changelog_register || error "changelog_register failed"
17009         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17010
17011         changelog_users $SINGLEMDS | grep -q $cl_user ||
17012                 error "User '$cl_user' not found in changelog_users"
17013
17014         # Clear some types so that MTIME changelogs are generated
17015         changelog_chmask "-CREAT"
17016         changelog_chmask "-CLOSE"
17017
17018         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17019
17020         # Test CL_MTIME during setattr
17021         touch $DIR/$tdir/$tfile
17022         compare_mtime_changelog $DIR/$tdir/$tfile
17023
17024         # Test CL_MTIME during close
17025         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17026         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17027 }
17028 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17029
17030 test_160m() {
17031         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17032         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17033                 skip "Need MDS version at least 2.14.51"
17034         local cl_users
17035         local cl_user1
17036         local cl_user2
17037         local pid1
17038
17039         # Create a user
17040         changelog_register || error "first changelog_register failed"
17041         changelog_register || error "second changelog_register failed"
17042
17043         cl_users=(${CL_USERS[mds1]})
17044         cl_user1="${cl_users[0]}"
17045         cl_user2="${cl_users[1]}"
17046         # generate some changelog records to accumulate on MDT0
17047         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17048         createmany -m $DIR/$tdir/$tfile 50 ||
17049                 error "create $DIR/$tdir/$tfile failed"
17050         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17051         rm -f $DIR/$tdir
17052
17053         # check changelogs have been generated
17054         local nbcl=$(changelog_dump | wc -l)
17055         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17056
17057 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17058         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17059
17060         __changelog_clear mds1 $cl_user1 +10
17061         __changelog_clear mds1 $cl_user2 0 &
17062         pid1=$!
17063         sleep 2
17064         __changelog_clear mds1 $cl_user1 0 ||
17065                 error "fail to cancel record for $cl_user1"
17066         wait $pid1
17067         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17068 }
17069 run_test 160m "Changelog clear race"
17070
17071 test_160n() {
17072         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17073         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17074                 skip "Need MDS version at least 2.14.51"
17075         local cl_users
17076         local cl_user1
17077         local cl_user2
17078         local pid1
17079         local first_rec
17080         local last_rec=0
17081
17082         # Create a user
17083         changelog_register || error "first changelog_register failed"
17084
17085         cl_users=(${CL_USERS[mds1]})
17086         cl_user1="${cl_users[0]}"
17087
17088         # generate some changelog records to accumulate on MDT0
17089         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17090         first_rec=$(changelog_users $SINGLEMDS |
17091                         awk '/^current.index:/ { print $NF }')
17092         while (( last_rec < (( first_rec + 65000)) )); do
17093                 createmany -m $DIR/$tdir/$tfile 10000 ||
17094                         error "create $DIR/$tdir/$tfile failed"
17095
17096                 for i in $(seq 0 10000); do
17097                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17098                                 > /dev/null
17099                 done
17100
17101                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17102                         error "unlinkmany failed unlink"
17103                 last_rec=$(changelog_users $SINGLEMDS |
17104                         awk '/^current.index:/ { print $NF }')
17105                 echo last record $last_rec
17106                 (( last_rec == 0 )) && error "no changelog found"
17107         done
17108
17109 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17110         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17111
17112         __changelog_clear mds1 $cl_user1 0 &
17113         pid1=$!
17114         sleep 2
17115         __changelog_clear mds1 $cl_user1 0 ||
17116                 error "fail to cancel record for $cl_user1"
17117         wait $pid1
17118         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17119 }
17120 run_test 160n "Changelog destroy race"
17121
17122 test_160o() {
17123         local mdt="$(facet_svc $SINGLEMDS)"
17124
17125         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17126         remote_mds_nodsh && skip "remote MDS with nodsh"
17127         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17128                 skip "Need MDS version at least 2.14.52"
17129
17130         changelog_register --user test_160o -m unlnk+close+open ||
17131                 error "changelog_register failed"
17132
17133         do_facet $SINGLEMDS $LCTL --device $mdt \
17134                                 changelog_register -u "Tt3_-#" &&
17135                 error "bad symbols in name should fail"
17136
17137         do_facet $SINGLEMDS $LCTL --device $mdt \
17138                                 changelog_register -u test_160o &&
17139                 error "the same name registration should fail"
17140
17141         do_facet $SINGLEMDS $LCTL --device $mdt \
17142                         changelog_register -u test_160toolongname &&
17143                 error "too long name registration should fail"
17144
17145         changelog_chmask "MARK+HSM"
17146         lctl get_param mdd.*.changelog*mask
17147         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17148         changelog_users $SINGLEMDS | grep -q $cl_user ||
17149                 error "User $cl_user not found in changelog_users"
17150         #verify username
17151         echo $cl_user | grep -q test_160o ||
17152                 error "User $cl_user has no specific name 'test160o'"
17153
17154         # change something
17155         changelog_clear 0 || error "changelog_clear failed"
17156         # generate some changelog records to accumulate on MDT0
17157         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17158         touch $DIR/$tdir/$tfile                 # open 1
17159
17160         OPENS=$(changelog_dump | grep -c "OPEN")
17161         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17162
17163         # must be no MKDIR it wasn't set as user mask
17164         MKDIR=$(changelog_dump | grep -c "MKDIR")
17165         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17166
17167         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17168                                 mdd.$mdt.changelog_current_mask -n)
17169         # register maskless user
17170         changelog_register || error "changelog_register failed"
17171         # effective mask should be not changed because it is not minimal
17172         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17173                                 mdd.$mdt.changelog_current_mask -n)
17174         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17175         # set server mask to minimal value
17176         changelog_chmask "MARK"
17177         # check effective mask again, should be treated as DEFMASK now
17178         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17179                                 mdd.$mdt.changelog_current_mask -n)
17180         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17181
17182         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17183                 # set server mask back to some value
17184                 changelog_chmask "CLOSE,UNLNK"
17185                 # check effective mask again, should not remain as DEFMASK
17186                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17187                                 mdd.$mdt.changelog_current_mask -n)
17188                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17189         fi
17190
17191         do_facet $SINGLEMDS $LCTL --device $mdt \
17192                                 changelog_deregister -u test_160o ||
17193                 error "cannot deregister by name"
17194 }
17195 run_test 160o "changelog user name and mask"
17196
17197 test_160p() {
17198         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17199         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17200                 skip "Need MDS version at least 2.14.51"
17201         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17202         local cl_users
17203         local cl_user1
17204         local entry_count
17205
17206         # Create a user
17207         changelog_register || error "first changelog_register failed"
17208
17209         cl_users=(${CL_USERS[mds1]})
17210         cl_user1="${cl_users[0]}"
17211
17212         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17213         createmany -m $DIR/$tdir/$tfile 50 ||
17214                 error "create $DIR/$tdir/$tfile failed"
17215         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17216         rm -rf $DIR/$tdir
17217
17218         # check changelogs have been generated
17219         entry_count=$(changelog_dump | wc -l)
17220         ((entry_count != 0)) || error "no changelog entries found"
17221
17222         # remove changelog_users and check that orphan entries are removed
17223         stop mds1
17224         local dev=$(mdsdevname 1)
17225         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17226         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17227         entry_count=$(changelog_dump | wc -l)
17228         ((entry_count == 0)) ||
17229                 error "found $entry_count changelog entries, expected none"
17230 }
17231 run_test 160p "Changelog orphan cleanup with no users"
17232
17233 test_160q() {
17234         local mdt="$(facet_svc $SINGLEMDS)"
17235         local clu
17236
17237         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17238         remote_mds_nodsh && skip "remote MDS with nodsh"
17239         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17240                 skip "Need MDS version at least 2.14.54"
17241
17242         # set server mask to minimal value like server init does
17243         changelog_chmask "MARK"
17244         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17245                 error "changelog_register failed"
17246         # check effective mask again, should be treated as DEFMASK now
17247         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17248                                 mdd.$mdt.changelog_current_mask -n)
17249         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17250                 error "changelog_deregister failed"
17251         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17252 }
17253 run_test 160q "changelog effective mask is DEFMASK if not set"
17254
17255 test_160s() {
17256         remote_mds_nodsh && skip "remote MDS with nodsh"
17257         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17258                 skip "Need MDS version at least 2.14.55"
17259
17260         local mdts=$(comma_list $(mdts_nodes))
17261
17262         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17263         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17264                                        fail_val=$((24 * 3600 * 10))
17265
17266         # Create a user which is 10 days old
17267         changelog_register || error "first changelog_register failed"
17268         local cl_users
17269         declare -A cl_user1
17270         local i
17271
17272         # generate some changelog records to accumulate on each MDT
17273         # use all_char because created files should be evenly distributed
17274         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17275                 error "test_mkdir $tdir failed"
17276         for ((i = 0; i < MDSCOUNT; i++)); do
17277                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17278                         error "create $DIR/$tdir/d$i.1 failed"
17279         done
17280
17281         # check changelogs have been generated
17282         local nbcl=$(changelog_dump | wc -l)
17283         (( nbcl > 0 )) || error "no changelogs found"
17284
17285         # reduce the max_idle_indexes value to make sure we exceed it
17286         for param in "changelog_max_idle_indexes=2097446912" \
17287                      "changelog_max_idle_time=2592000" \
17288                      "changelog_gc=1" \
17289                      "changelog_min_gc_interval=2"; do
17290                 local MDT0=$(facet_svc $SINGLEMDS)
17291                 local var="${param%=*}"
17292                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17293
17294                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17295                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17296                         error "unable to set mdd.*.$param"
17297         done
17298
17299         local start=$SECONDS
17300         for i in $(seq $MDSCOUNT); do
17301                 cl_users=(${CL_USERS[mds$i]})
17302                 cl_user1[mds$i]="${cl_users[0]}"
17303
17304                 [[ -n "${cl_user1[mds$i]}" ]] ||
17305                         error "mds$i: no user registered"
17306         done
17307
17308         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17309         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17310
17311         # ensure we are past the previous changelog_min_gc_interval set above
17312         local sleep2=$((start + 2 - SECONDS))
17313         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17314
17315         # Generate one more changelog to trigger GC
17316         for ((i = 0; i < MDSCOUNT; i++)); do
17317                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17318                         error "create $DIR/$tdir/d$i.3 failed"
17319         done
17320
17321         # ensure gc thread is done
17322         for node in $(mdts_nodes); do
17323                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17324                         error "$node: GC-thread not done"
17325         done
17326
17327         do_nodes $mdts $LCTL set_param fail_loc=0
17328
17329         for (( i = 1; i <= MDSCOUNT; i++ )); do
17330                 # check cl_user1 is purged
17331                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17332                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17333         done
17334         return 0
17335 }
17336 run_test 160s "changelog garbage collect on idle records * time"
17337
17338 test_160t() {
17339         remote_mds_nodsh && skip "remote MDS with nodsh"
17340         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17341                 skip "Need MDS version at least 2.15.50"
17342
17343         local MDT0=$(facet_svc $SINGLEMDS)
17344         local cl_users
17345         local cl_user1
17346         local cl_user2
17347         local start
17348
17349         changelog_register --user user1 -m all ||
17350                 error "user1 failed to register"
17351
17352         mkdir_on_mdt0 $DIR/$tdir
17353         # create default overstripe to maximize changelog size
17354         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17355         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17356         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17357
17358         # user2 consumes less records so less space
17359         changelog_register --user user2 || error "user2 failed to register"
17360         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17361         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17362
17363         # check changelogs have been generated
17364         local nbcl=$(changelog_dump | wc -l)
17365         (( nbcl > 0 )) || error "no changelogs found"
17366
17367         # reduce the changelog_min_gc_interval to force check
17368         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17369                 local var="${param%=*}"
17370                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17371
17372                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17373                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17374                         error "unable to set mdd.*.$param"
17375         done
17376
17377         start=$SECONDS
17378         cl_users=(${CL_USERS[mds1]})
17379         cl_user1="${cl_users[0]}"
17380         cl_user2="${cl_users[1]}"
17381
17382         [[ -n $cl_user1 ]] ||
17383                 error "mds1: user #1 isn't registered"
17384         [[ -n $cl_user2 ]] ||
17385                 error "mds1: user #2 isn't registered"
17386
17387         # ensure we are past the previous changelog_min_gc_interval set above
17388         local sleep2=$((start + 2 - SECONDS))
17389         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17390
17391         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17392         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17393                         fail_val=$(((llog_size1 + llog_size2) / 2))
17394
17395         # Generate more changelog to trigger GC
17396         createmany -o $DIR/$tdir/u3_ 4 ||
17397                 error "create failed for more files"
17398
17399         # ensure gc thread is done
17400         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17401                 error "mds1: GC-thread not done"
17402
17403         do_facet mds1 $LCTL set_param fail_loc=0
17404
17405         # check cl_user1 is purged
17406         changelog_users mds1 | grep -q "$cl_user1" &&
17407                 error "User $cl_user1 is registered"
17408         # check cl_user2 is not purged
17409         changelog_users mds1 | grep -q "$cl_user2" ||
17410                 error "User $cl_user2 is not registered"
17411 }
17412 run_test 160t "changelog garbage collect on lack of space"
17413
17414 test_161a() {
17415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17416
17417         test_mkdir -c1 $DIR/$tdir
17418         cp /etc/hosts $DIR/$tdir/$tfile
17419         test_mkdir -c1 $DIR/$tdir/foo1
17420         test_mkdir -c1 $DIR/$tdir/foo2
17421         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17422         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17423         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17424         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17425         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17426         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17427                 $LFS fid2path $DIR $FID
17428                 error "bad link ea"
17429         fi
17430         # middle
17431         rm $DIR/$tdir/foo2/zachary
17432         # last
17433         rm $DIR/$tdir/foo2/thor
17434         # first
17435         rm $DIR/$tdir/$tfile
17436         # rename
17437         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17438         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17439                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17440         rm $DIR/$tdir/foo2/maggie
17441
17442         # overflow the EA
17443         local longname=$tfile.avg_len_is_thirty_two_
17444         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17445                 error_noexit 'failed to unlink many hardlinks'" EXIT
17446         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17447                 error "failed to hardlink many files"
17448         links=$($LFS fid2path $DIR $FID | wc -l)
17449         echo -n "${links}/1000 links in link EA"
17450         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17451 }
17452 run_test 161a "link ea sanity"
17453
17454 test_161b() {
17455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17456         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17457
17458         local MDTIDX=1
17459         local remote_dir=$DIR/$tdir/remote_dir
17460
17461         mkdir -p $DIR/$tdir
17462         $LFS mkdir -i $MDTIDX $remote_dir ||
17463                 error "create remote directory failed"
17464
17465         cp /etc/hosts $remote_dir/$tfile
17466         mkdir -p $remote_dir/foo1
17467         mkdir -p $remote_dir/foo2
17468         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17469         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17470         ln $remote_dir/$tfile $remote_dir/foo1/luna
17471         ln $remote_dir/$tfile $remote_dir/foo2/thor
17472
17473         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17474                      tr -d ']')
17475         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17476                 $LFS fid2path $DIR $FID
17477                 error "bad link ea"
17478         fi
17479         # middle
17480         rm $remote_dir/foo2/zachary
17481         # last
17482         rm $remote_dir/foo2/thor
17483         # first
17484         rm $remote_dir/$tfile
17485         # rename
17486         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17487         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17488         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17489                 $LFS fid2path $DIR $FID
17490                 error "bad link rename"
17491         fi
17492         rm $remote_dir/foo2/maggie
17493
17494         # overflow the EA
17495         local longname=filename_avg_len_is_thirty_two_
17496         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17497                 error "failed to hardlink many files"
17498         links=$($LFS fid2path $DIR $FID | wc -l)
17499         echo -n "${links}/1000 links in link EA"
17500         [[ ${links} -gt 60 ]] ||
17501                 error "expected at least 60 links in link EA"
17502         unlinkmany $remote_dir/foo2/$longname 1000 ||
17503         error "failed to unlink many hardlinks"
17504 }
17505 run_test 161b "link ea sanity under remote directory"
17506
17507 test_161c() {
17508         remote_mds_nodsh && skip "remote MDS with nodsh"
17509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17510         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17511                 skip "Need MDS version at least 2.1.5"
17512
17513         # define CLF_RENAME_LAST 0x0001
17514         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17515         changelog_register || error "changelog_register failed"
17516
17517         rm -rf $DIR/$tdir
17518         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17519         touch $DIR/$tdir/foo_161c
17520         touch $DIR/$tdir/bar_161c
17521         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17522         changelog_dump | grep RENME | tail -n 5
17523         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17524         changelog_clear 0 || error "changelog_clear failed"
17525         if [ x$flags != "x0x1" ]; then
17526                 error "flag $flags is not 0x1"
17527         fi
17528
17529         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17530         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17531         touch $DIR/$tdir/foo_161c
17532         touch $DIR/$tdir/bar_161c
17533         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17534         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17535         changelog_dump | grep RENME | tail -n 5
17536         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17537         changelog_clear 0 || error "changelog_clear failed"
17538         if [ x$flags != "x0x0" ]; then
17539                 error "flag $flags is not 0x0"
17540         fi
17541         echo "rename overwrite a target having nlink > 1," \
17542                 "changelog record has flags of $flags"
17543
17544         # rename doesn't overwrite a target (changelog flag 0x0)
17545         touch $DIR/$tdir/foo_161c
17546         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17547         changelog_dump | grep RENME | tail -n 5
17548         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17549         changelog_clear 0 || error "changelog_clear failed"
17550         if [ x$flags != "x0x0" ]; then
17551                 error "flag $flags is not 0x0"
17552         fi
17553         echo "rename doesn't overwrite a target," \
17554                 "changelog record has flags of $flags"
17555
17556         # define CLF_UNLINK_LAST 0x0001
17557         # unlink a file having nlink = 1 (changelog flag 0x1)
17558         rm -f $DIR/$tdir/foo2_161c
17559         changelog_dump | grep UNLNK | tail -n 5
17560         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17561         changelog_clear 0 || error "changelog_clear failed"
17562         if [ x$flags != "x0x1" ]; then
17563                 error "flag $flags is not 0x1"
17564         fi
17565         echo "unlink a file having nlink = 1," \
17566                 "changelog record has flags of $flags"
17567
17568         # unlink a file having nlink > 1 (changelog flag 0x0)
17569         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17570         rm -f $DIR/$tdir/foobar_161c
17571         changelog_dump | grep UNLNK | tail -n 5
17572         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17573         changelog_clear 0 || error "changelog_clear failed"
17574         if [ x$flags != "x0x0" ]; then
17575                 error "flag $flags is not 0x0"
17576         fi
17577         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17578 }
17579 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17580
17581 test_161d() {
17582         remote_mds_nodsh && skip "remote MDS with nodsh"
17583         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17584
17585         local pid
17586         local fid
17587
17588         changelog_register || error "changelog_register failed"
17589
17590         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17591         # interfer with $MOUNT/.lustre/fid/ access
17592         mkdir $DIR/$tdir
17593         [[ $? -eq 0 ]] || error "mkdir failed"
17594
17595         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17596         $LCTL set_param fail_loc=0x8000140c
17597         # 5s pause
17598         $LCTL set_param fail_val=5
17599
17600         # create file
17601         echo foofoo > $DIR/$tdir/$tfile &
17602         pid=$!
17603
17604         # wait for create to be delayed
17605         sleep 2
17606
17607         ps -p $pid
17608         [[ $? -eq 0 ]] || error "create should be blocked"
17609
17610         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17611         stack_trap "rm -f $tempfile"
17612         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17613         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17614         # some delay may occur during ChangeLog publishing and file read just
17615         # above, that could allow file write to happen finally
17616         [[ -s $tempfile ]] && echo "file should be empty"
17617
17618         $LCTL set_param fail_loc=0
17619
17620         wait $pid
17621         [[ $? -eq 0 ]] || error "create failed"
17622 }
17623 run_test 161d "create with concurrent .lustre/fid access"
17624
17625 check_path() {
17626         local expected="$1"
17627         shift
17628         local fid="$2"
17629
17630         local path
17631         path=$($LFS fid2path "$@")
17632         local rc=$?
17633
17634         if [ $rc -ne 0 ]; then
17635                 error "path looked up of '$expected' failed: rc=$rc"
17636         elif [ "$path" != "$expected" ]; then
17637                 error "path looked up '$path' instead of '$expected'"
17638         else
17639                 echo "FID '$fid' resolves to path '$path' as expected"
17640         fi
17641 }
17642
17643 test_162a() { # was test_162
17644         test_mkdir -p -c1 $DIR/$tdir/d2
17645         touch $DIR/$tdir/d2/$tfile
17646         touch $DIR/$tdir/d2/x1
17647         touch $DIR/$tdir/d2/x2
17648         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17649         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17650         # regular file
17651         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17652         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17653
17654         # softlink
17655         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17656         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17657         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17658
17659         # softlink to wrong file
17660         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17661         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17662         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17663
17664         # hardlink
17665         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17666         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17667         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17668         # fid2path dir/fsname should both work
17669         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17670         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17671
17672         # hardlink count: check that there are 2 links
17673         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17674         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17675
17676         # hardlink indexing: remove the first link
17677         rm $DIR/$tdir/d2/p/q/r/hlink
17678         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17679 }
17680 run_test 162a "path lookup sanity"
17681
17682 test_162b() {
17683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17685
17686         mkdir $DIR/$tdir
17687         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17688                                 error "create striped dir failed"
17689
17690         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17691                                         tail -n 1 | awk '{print $2}')
17692         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17693
17694         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17695         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17696
17697         # regular file
17698         for ((i=0;i<5;i++)); do
17699                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17700                         error "get fid for f$i failed"
17701                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17702
17703                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17704                         error "get fid for d$i failed"
17705                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17706         done
17707
17708         return 0
17709 }
17710 run_test 162b "striped directory path lookup sanity"
17711
17712 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17713 test_162c() {
17714         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17715                 skip "Need MDS version at least 2.7.51"
17716
17717         local lpath=$tdir.local
17718         local rpath=$tdir.remote
17719
17720         test_mkdir $DIR/$lpath
17721         test_mkdir $DIR/$rpath
17722
17723         for ((i = 0; i <= 101; i++)); do
17724                 lpath="$lpath/$i"
17725                 mkdir $DIR/$lpath
17726                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17727                         error "get fid for local directory $DIR/$lpath failed"
17728                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17729
17730                 rpath="$rpath/$i"
17731                 test_mkdir $DIR/$rpath
17732                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17733                         error "get fid for remote directory $DIR/$rpath failed"
17734                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17735         done
17736
17737         return 0
17738 }
17739 run_test 162c "fid2path works with paths 100 or more directories deep"
17740
17741 oalr_event_count() {
17742         local event="${1}"
17743         local trace="${2}"
17744
17745         awk -v name="${FSNAME}-OST0000" \
17746             -v event="${event}" \
17747             '$1 == "TRACE" && $2 == event && $3 == name' \
17748             "${trace}" |
17749         wc -l
17750 }
17751
17752 oalr_expect_event_count() {
17753         local event="${1}"
17754         local trace="${2}"
17755         local expect="${3}"
17756         local count
17757
17758         count=$(oalr_event_count "${event}" "${trace}")
17759         if ((count == expect)); then
17760                 return 0
17761         fi
17762
17763         error_noexit "${event} event count was '${count}', expected ${expect}"
17764         cat "${trace}" >&2
17765         exit 1
17766 }
17767
17768 cleanup_165() {
17769         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17770         stop ost1
17771         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17772 }
17773
17774 setup_165() {
17775         sync # Flush previous IOs so we can count log entries.
17776         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17777         stack_trap cleanup_165 EXIT
17778 }
17779
17780 test_165a() {
17781         local trace="/tmp/${tfile}.trace"
17782         local rc
17783         local count
17784
17785         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17786                 skip "OFD access log unsupported"
17787
17788         setup_165
17789         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17790         sleep 5
17791
17792         do_facet ost1 ofd_access_log_reader --list
17793         stop ost1
17794
17795         do_facet ost1 killall -TERM ofd_access_log_reader
17796         wait
17797         rc=$?
17798
17799         if ((rc != 0)); then
17800                 error "ofd_access_log_reader exited with rc = '${rc}'"
17801         fi
17802
17803         # Parse trace file for discovery events:
17804         oalr_expect_event_count alr_log_add "${trace}" 1
17805         oalr_expect_event_count alr_log_eof "${trace}" 1
17806         oalr_expect_event_count alr_log_free "${trace}" 1
17807 }
17808 run_test 165a "ofd access log discovery"
17809
17810 test_165b() {
17811         local trace="/tmp/${tfile}.trace"
17812         local file="${DIR}/${tfile}"
17813         local pfid1
17814         local pfid2
17815         local -a entry
17816         local rc
17817         local count
17818         local size
17819         local flags
17820
17821         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17822                 skip "OFD access log unsupported"
17823
17824         setup_165
17825         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17826         sleep 5
17827
17828         do_facet ost1 ofd_access_log_reader --list
17829
17830         lfs setstripe -c 1 -i 0 "${file}"
17831         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17832                 error "cannot create '${file}'"
17833
17834         sleep 5
17835         do_facet ost1 killall -TERM ofd_access_log_reader
17836         wait
17837         rc=$?
17838
17839         if ((rc != 0)); then
17840                 error "ofd_access_log_reader exited with rc = '${rc}'"
17841         fi
17842
17843         oalr_expect_event_count alr_log_entry "${trace}" 1
17844
17845         pfid1=$($LFS path2fid "${file}")
17846
17847         # 1     2             3   4    5     6   7    8    9     10
17848         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17849         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17850
17851         echo "entry = '${entry[*]}'" >&2
17852
17853         pfid2=${entry[4]}
17854         if [[ "${pfid1}" != "${pfid2}" ]]; then
17855                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17856         fi
17857
17858         size=${entry[8]}
17859         if ((size != 1048576)); then
17860                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17861         fi
17862
17863         flags=${entry[10]}
17864         if [[ "${flags}" != "w" ]]; then
17865                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17866         fi
17867
17868         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17869         sleep 5
17870
17871         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17872                 error "cannot read '${file}'"
17873         sleep 5
17874
17875         do_facet ost1 killall -TERM ofd_access_log_reader
17876         wait
17877         rc=$?
17878
17879         if ((rc != 0)); then
17880                 error "ofd_access_log_reader exited with rc = '${rc}'"
17881         fi
17882
17883         oalr_expect_event_count alr_log_entry "${trace}" 1
17884
17885         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17886         echo "entry = '${entry[*]}'" >&2
17887
17888         pfid2=${entry[4]}
17889         if [[ "${pfid1}" != "${pfid2}" ]]; then
17890                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17891         fi
17892
17893         size=${entry[8]}
17894         if ((size != 524288)); then
17895                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17896         fi
17897
17898         flags=${entry[10]}
17899         if [[ "${flags}" != "r" ]]; then
17900                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17901         fi
17902 }
17903 run_test 165b "ofd access log entries are produced and consumed"
17904
17905 test_165c() {
17906         local trace="/tmp/${tfile}.trace"
17907         local file="${DIR}/${tdir}/${tfile}"
17908
17909         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17910                 skip "OFD access log unsupported"
17911
17912         test_mkdir "${DIR}/${tdir}"
17913
17914         setup_165
17915         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17916         sleep 5
17917
17918         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17919
17920         # 4096 / 64 = 64. Create twice as many entries.
17921         for ((i = 0; i < 128; i++)); do
17922                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17923                         error "cannot create file"
17924         done
17925
17926         sync
17927
17928         do_facet ost1 killall -TERM ofd_access_log_reader
17929         wait
17930         rc=$?
17931         if ((rc != 0)); then
17932                 error "ofd_access_log_reader exited with rc = '${rc}'"
17933         fi
17934
17935         unlinkmany  "${file}-%d" 128
17936 }
17937 run_test 165c "full ofd access logs do not block IOs"
17938
17939 oal_get_read_count() {
17940         local stats="$1"
17941
17942         # STATS lustre-OST0001 alr_read_count 1
17943
17944         do_facet ost1 cat "${stats}" |
17945         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17946              END { print count; }'
17947 }
17948
17949 oal_expect_read_count() {
17950         local stats="$1"
17951         local count
17952         local expect="$2"
17953
17954         # Ask ofd_access_log_reader to write stats.
17955         do_facet ost1 killall -USR1 ofd_access_log_reader
17956
17957         # Allow some time for things to happen.
17958         sleep 1
17959
17960         count=$(oal_get_read_count "${stats}")
17961         if ((count == expect)); then
17962                 return 0
17963         fi
17964
17965         error_noexit "bad read count, got ${count}, expected ${expect}"
17966         do_facet ost1 cat "${stats}" >&2
17967         exit 1
17968 }
17969
17970 test_165d() {
17971         local stats="/tmp/${tfile}.stats"
17972         local file="${DIR}/${tdir}/${tfile}"
17973         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17974
17975         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17976                 skip "OFD access log unsupported"
17977
17978         test_mkdir "${DIR}/${tdir}"
17979
17980         setup_165
17981         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17982         sleep 5
17983
17984         lfs setstripe -c 1 -i 0 "${file}"
17985
17986         do_facet ost1 lctl set_param "${param}=rw"
17987         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17988                 error "cannot create '${file}'"
17989         oal_expect_read_count "${stats}" 1
17990
17991         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17992                 error "cannot read '${file}'"
17993         oal_expect_read_count "${stats}" 2
17994
17995         do_facet ost1 lctl set_param "${param}=r"
17996         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17997                 error "cannot create '${file}'"
17998         oal_expect_read_count "${stats}" 2
17999
18000         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18001                 error "cannot read '${file}'"
18002         oal_expect_read_count "${stats}" 3
18003
18004         do_facet ost1 lctl set_param "${param}=w"
18005         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18006                 error "cannot create '${file}'"
18007         oal_expect_read_count "${stats}" 4
18008
18009         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18010                 error "cannot read '${file}'"
18011         oal_expect_read_count "${stats}" 4
18012
18013         do_facet ost1 lctl set_param "${param}=0"
18014         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18015                 error "cannot create '${file}'"
18016         oal_expect_read_count "${stats}" 4
18017
18018         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18019                 error "cannot read '${file}'"
18020         oal_expect_read_count "${stats}" 4
18021
18022         do_facet ost1 killall -TERM ofd_access_log_reader
18023         wait
18024         rc=$?
18025         if ((rc != 0)); then
18026                 error "ofd_access_log_reader exited with rc = '${rc}'"
18027         fi
18028 }
18029 run_test 165d "ofd_access_log mask works"
18030
18031 test_165e() {
18032         local stats="/tmp/${tfile}.stats"
18033         local file0="${DIR}/${tdir}-0/${tfile}"
18034         local file1="${DIR}/${tdir}-1/${tfile}"
18035
18036         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18037                 skip "OFD access log unsupported"
18038
18039         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18040
18041         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18042         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18043
18044         lfs setstripe -c 1 -i 0 "${file0}"
18045         lfs setstripe -c 1 -i 0 "${file1}"
18046
18047         setup_165
18048         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18049         sleep 5
18050
18051         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18052                 error "cannot create '${file0}'"
18053         sync
18054         oal_expect_read_count "${stats}" 0
18055
18056         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18057                 error "cannot create '${file1}'"
18058         sync
18059         oal_expect_read_count "${stats}" 1
18060
18061         do_facet ost1 killall -TERM ofd_access_log_reader
18062         wait
18063         rc=$?
18064         if ((rc != 0)); then
18065                 error "ofd_access_log_reader exited with rc = '${rc}'"
18066         fi
18067 }
18068 run_test 165e "ofd_access_log MDT index filter works"
18069
18070 test_165f() {
18071         local trace="/tmp/${tfile}.trace"
18072         local rc
18073         local count
18074
18075         setup_165
18076         do_facet ost1 timeout 60 ofd_access_log_reader \
18077                 --exit-on-close --debug=- --trace=- > "${trace}" &
18078         sleep 5
18079         stop ost1
18080
18081         wait
18082         rc=$?
18083
18084         if ((rc != 0)); then
18085                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18086                 cat "${trace}"
18087                 exit 1
18088         fi
18089 }
18090 run_test 165f "ofd_access_log_reader --exit-on-close works"
18091
18092 test_169() {
18093         # do directio so as not to populate the page cache
18094         log "creating a 10 Mb file"
18095         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18096                 error "multiop failed while creating a file"
18097         log "starting reads"
18098         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18099         log "truncating the file"
18100         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18101                 error "multiop failed while truncating the file"
18102         log "killing dd"
18103         kill %+ || true # reads might have finished
18104         echo "wait until dd is finished"
18105         wait
18106         log "removing the temporary file"
18107         rm -rf $DIR/$tfile || error "tmp file removal failed"
18108 }
18109 run_test 169 "parallel read and truncate should not deadlock"
18110
18111 test_170() {
18112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18113
18114         $LCTL clear     # bug 18514
18115         $LCTL debug_daemon start $TMP/${tfile}_log_good
18116         touch $DIR/$tfile
18117         $LCTL debug_daemon stop
18118         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18119                 error "sed failed to read log_good"
18120
18121         $LCTL debug_daemon start $TMP/${tfile}_log_good
18122         rm -rf $DIR/$tfile
18123         $LCTL debug_daemon stop
18124
18125         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18126                error "lctl df log_bad failed"
18127
18128         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18129         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18130
18131         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18132         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18133
18134         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18135                 error "bad_line good_line1 good_line2 are empty"
18136
18137         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18138         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18139         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18140
18141         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18142         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18143         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18144
18145         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18146                 error "bad_line_new good_line_new are empty"
18147
18148         local expected_good=$((good_line1 + good_line2*2))
18149
18150         rm -f $TMP/${tfile}*
18151         # LU-231, short malformed line may not be counted into bad lines
18152         if [ $bad_line -ne $bad_line_new ] &&
18153                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18154                 error "expected $bad_line bad lines, but got $bad_line_new"
18155                 return 1
18156         fi
18157
18158         if [ $expected_good -ne $good_line_new ]; then
18159                 error "expected $expected_good good lines, but got $good_line_new"
18160                 return 2
18161         fi
18162         true
18163 }
18164 run_test 170 "test lctl df to handle corrupted log ====================="
18165
18166 test_171() { # bug20592
18167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18168
18169         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18170         $LCTL set_param fail_loc=0x50e
18171         $LCTL set_param fail_val=3000
18172         multiop_bg_pause $DIR/$tfile O_s || true
18173         local MULTIPID=$!
18174         kill -USR1 $MULTIPID
18175         # cause log dump
18176         sleep 3
18177         wait $MULTIPID
18178         if dmesg | grep "recursive fault"; then
18179                 error "caught a recursive fault"
18180         fi
18181         $LCTL set_param fail_loc=0
18182         true
18183 }
18184 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18185
18186 test_172() {
18187
18188         #define OBD_FAIL_OBD_CLEANUP  0x60e
18189         $LCTL set_param fail_loc=0x60e
18190         umount $MOUNT || error "umount $MOUNT failed"
18191         stack_trap "mount_client $MOUNT"
18192
18193         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18194                 error "no client OBDs are remained"
18195
18196         $LCTL dl | while read devno state type name foo; do
18197                 case $type in
18198                 lov|osc|lmv|mdc)
18199                         $LCTL --device $name cleanup
18200                         $LCTL --device $name detach
18201                         ;;
18202                 *)
18203                         # skip server devices
18204                         ;;
18205                 esac
18206         done
18207
18208         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18209                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18210                 error "some client OBDs are still remained"
18211         fi
18212
18213 }
18214 run_test 172 "manual device removal with lctl cleanup/detach ======"
18215
18216 # it would be good to share it with obdfilter-survey/iokit-libecho code
18217 setup_obdecho_osc () {
18218         local rc=0
18219         local ost_nid=$1
18220         local obdfilter_name=$2
18221         echo "Creating new osc for $obdfilter_name on $ost_nid"
18222         # make sure we can find loopback nid
18223         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18224
18225         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18226                            ${obdfilter_name}_osc_UUID || rc=2; }
18227         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18228                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18229         return $rc
18230 }
18231
18232 cleanup_obdecho_osc () {
18233         local obdfilter_name=$1
18234         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18235         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18236         return 0
18237 }
18238
18239 obdecho_test() {
18240         local OBD=$1
18241         local node=$2
18242         local pages=${3:-64}
18243         local rc=0
18244         local id
18245
18246         local count=10
18247         local obd_size=$(get_obd_size $node $OBD)
18248         local page_size=$(get_page_size $node)
18249         if [[ -n "$obd_size" ]]; then
18250                 local new_count=$((obd_size / (pages * page_size / 1024)))
18251                 [[ $new_count -ge $count ]] || count=$new_count
18252         fi
18253
18254         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18255         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18256                            rc=2; }
18257         if [ $rc -eq 0 ]; then
18258             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18259             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18260         fi
18261         echo "New object id is $id"
18262         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18263                            rc=4; }
18264         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18265                            "test_brw $count w v $pages $id" || rc=4; }
18266         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18267                            rc=4; }
18268         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18269                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18270         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18271                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18272         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18273         return $rc
18274 }
18275
18276 test_180a() {
18277         skip "obdecho on osc is no longer supported"
18278 }
18279 run_test 180a "test obdecho on osc"
18280
18281 test_180b() {
18282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18283         remote_ost_nodsh && skip "remote OST with nodsh"
18284
18285         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18286                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18287                 error "failed to load module obdecho"
18288
18289         local target=$(do_facet ost1 $LCTL dl |
18290                        awk '/obdfilter/ { print $4; exit; }')
18291
18292         if [ -n "$target" ]; then
18293                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18294         else
18295                 do_facet ost1 $LCTL dl
18296                 error "there is no obdfilter target on ost1"
18297         fi
18298 }
18299 run_test 180b "test obdecho directly on obdfilter"
18300
18301 test_180c() { # LU-2598
18302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18303         remote_ost_nodsh && skip "remote OST with nodsh"
18304         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18305                 skip "Need MDS version at least 2.4.0"
18306
18307         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18308                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18309                 error "failed to load module obdecho"
18310
18311         local target=$(do_facet ost1 $LCTL dl |
18312                        awk '/obdfilter/ { print $4; exit; }')
18313
18314         if [ -n "$target" ]; then
18315                 local pages=16384 # 64MB bulk I/O RPC size
18316
18317                 obdecho_test "$target" ost1 "$pages" ||
18318                         error "obdecho_test with pages=$pages failed with $?"
18319         else
18320                 do_facet ost1 $LCTL dl
18321                 error "there is no obdfilter target on ost1"
18322         fi
18323 }
18324 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18325
18326 test_181() { # bug 22177
18327         test_mkdir $DIR/$tdir
18328         # create enough files to index the directory
18329         createmany -o $DIR/$tdir/foobar 4000
18330         # print attributes for debug purpose
18331         lsattr -d .
18332         # open dir
18333         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18334         MULTIPID=$!
18335         # remove the files & current working dir
18336         unlinkmany $DIR/$tdir/foobar 4000
18337         rmdir $DIR/$tdir
18338         kill -USR1 $MULTIPID
18339         wait $MULTIPID
18340         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18341         return 0
18342 }
18343 run_test 181 "Test open-unlinked dir ========================"
18344
18345 test_182a() {
18346         local fcount=1000
18347         local tcount=10
18348
18349         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18350
18351         $LCTL set_param mdc.*.rpc_stats=clear
18352
18353         for (( i = 0; i < $tcount; i++ )) ; do
18354                 mkdir $DIR/$tdir/$i
18355         done
18356
18357         for (( i = 0; i < $tcount; i++ )) ; do
18358                 createmany -o $DIR/$tdir/$i/f- $fcount &
18359         done
18360         wait
18361
18362         for (( i = 0; i < $tcount; i++ )) ; do
18363                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18364         done
18365         wait
18366
18367         $LCTL get_param mdc.*.rpc_stats
18368
18369         rm -rf $DIR/$tdir
18370 }
18371 run_test 182a "Test parallel modify metadata operations from mdc"
18372
18373 test_182b() {
18374         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18375         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18376         local dcount=1000
18377         local tcount=10
18378         local stime
18379         local etime
18380         local delta
18381
18382         do_facet mds1 $LCTL list_param \
18383                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18384                 skip "MDS lacks parallel RPC handling"
18385
18386         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18387
18388         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18389                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18390
18391         stime=$(date +%s)
18392         createmany -i 0 -d $DIR/$tdir/t- $tcount
18393
18394         for (( i = 0; i < $tcount; i++ )) ; do
18395                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18396         done
18397         wait
18398         etime=$(date +%s)
18399         delta=$((etime - stime))
18400         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18401
18402         stime=$(date +%s)
18403         for (( i = 0; i < $tcount; i++ )) ; do
18404                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18405         done
18406         wait
18407         etime=$(date +%s)
18408         delta=$((etime - stime))
18409         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18410
18411         rm -rf $DIR/$tdir
18412
18413         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18414
18415         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18416
18417         stime=$(date +%s)
18418         createmany -i 0 -d $DIR/$tdir/t- $tcount
18419
18420         for (( i = 0; i < $tcount; i++ )) ; do
18421                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18422         done
18423         wait
18424         etime=$(date +%s)
18425         delta=$((etime - stime))
18426         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18427
18428         stime=$(date +%s)
18429         for (( i = 0; i < $tcount; i++ )) ; do
18430                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18431         done
18432         wait
18433         etime=$(date +%s)
18434         delta=$((etime - stime))
18435         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18436
18437         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18438 }
18439 run_test 182b "Test parallel modify metadata operations from osp"
18440
18441 test_183() { # LU-2275
18442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18443         remote_mds_nodsh && skip "remote MDS with nodsh"
18444         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18445                 skip "Need MDS version at least 2.3.56"
18446
18447         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18448         echo aaa > $DIR/$tdir/$tfile
18449
18450 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18451         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18452
18453         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18454         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18455
18456         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18457
18458         # Flush negative dentry cache
18459         touch $DIR/$tdir/$tfile
18460
18461         # We are not checking for any leaked references here, they'll
18462         # become evident next time we do cleanup with module unload.
18463         rm -rf $DIR/$tdir
18464 }
18465 run_test 183 "No crash or request leak in case of strange dispositions ========"
18466
18467 # test suite 184 is for LU-2016, LU-2017
18468 test_184a() {
18469         check_swap_layouts_support
18470
18471         dir0=$DIR/$tdir/$testnum
18472         test_mkdir -p -c1 $dir0
18473         ref1=/etc/passwd
18474         ref2=/etc/group
18475         file1=$dir0/f1
18476         file2=$dir0/f2
18477         $LFS setstripe -c1 $file1
18478         cp $ref1 $file1
18479         $LFS setstripe -c2 $file2
18480         cp $ref2 $file2
18481         gen1=$($LFS getstripe -g $file1)
18482         gen2=$($LFS getstripe -g $file2)
18483
18484         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18485         gen=$($LFS getstripe -g $file1)
18486         [[ $gen1 != $gen ]] ||
18487                 error "Layout generation on $file1 does not change"
18488         gen=$($LFS getstripe -g $file2)
18489         [[ $gen2 != $gen ]] ||
18490                 error "Layout generation on $file2 does not change"
18491
18492         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18493         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18494
18495         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18496 }
18497 run_test 184a "Basic layout swap"
18498
18499 test_184b() {
18500         check_swap_layouts_support
18501
18502         dir0=$DIR/$tdir/$testnum
18503         mkdir -p $dir0 || error "creating dir $dir0"
18504         file1=$dir0/f1
18505         file2=$dir0/f2
18506         file3=$dir0/f3
18507         dir1=$dir0/d1
18508         dir2=$dir0/d2
18509         mkdir $dir1 $dir2
18510         $LFS setstripe -c1 $file1
18511         $LFS setstripe -c2 $file2
18512         $LFS setstripe -c1 $file3
18513         chown $RUNAS_ID $file3
18514         gen1=$($LFS getstripe -g $file1)
18515         gen2=$($LFS getstripe -g $file2)
18516
18517         $LFS swap_layouts $dir1 $dir2 &&
18518                 error "swap of directories layouts should fail"
18519         $LFS swap_layouts $dir1 $file1 &&
18520                 error "swap of directory and file layouts should fail"
18521         $RUNAS $LFS swap_layouts $file1 $file2 &&
18522                 error "swap of file we cannot write should fail"
18523         $LFS swap_layouts $file1 $file3 &&
18524                 error "swap of file with different owner should fail"
18525         /bin/true # to clear error code
18526 }
18527 run_test 184b "Forbidden layout swap (will generate errors)"
18528
18529 test_184c() {
18530         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18531         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18532         check_swap_layouts_support
18533         check_swap_layout_no_dom $DIR
18534
18535         local dir0=$DIR/$tdir/$testnum
18536         mkdir -p $dir0 || error "creating dir $dir0"
18537
18538         local ref1=$dir0/ref1
18539         local ref2=$dir0/ref2
18540         local file1=$dir0/file1
18541         local file2=$dir0/file2
18542         # create a file large enough for the concurrent test
18543         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18544         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18545         echo "ref file size: ref1($(stat -c %s $ref1))," \
18546              "ref2($(stat -c %s $ref2))"
18547
18548         cp $ref2 $file2
18549         dd if=$ref1 of=$file1 bs=16k &
18550         local DD_PID=$!
18551
18552         # Make sure dd starts to copy file, but wait at most 5 seconds
18553         local loops=0
18554         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18555
18556         $LFS swap_layouts $file1 $file2
18557         local rc=$?
18558         wait $DD_PID
18559         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18560         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18561
18562         # how many bytes copied before swapping layout
18563         local copied=$(stat -c %s $file2)
18564         local remaining=$(stat -c %s $ref1)
18565         remaining=$((remaining - copied))
18566         echo "Copied $copied bytes before swapping layout..."
18567
18568         cmp -n $copied $file1 $ref2 | grep differ &&
18569                 error "Content mismatch [0, $copied) of ref2 and file1"
18570         cmp -n $copied $file2 $ref1 ||
18571                 error "Content mismatch [0, $copied) of ref1 and file2"
18572         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18573                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18574
18575         # clean up
18576         rm -f $ref1 $ref2 $file1 $file2
18577 }
18578 run_test 184c "Concurrent write and layout swap"
18579
18580 test_184d() {
18581         check_swap_layouts_support
18582         check_swap_layout_no_dom $DIR
18583         [ -z "$(which getfattr 2>/dev/null)" ] &&
18584                 skip_env "no getfattr command"
18585
18586         local file1=$DIR/$tdir/$tfile-1
18587         local file2=$DIR/$tdir/$tfile-2
18588         local file3=$DIR/$tdir/$tfile-3
18589         local lovea1
18590         local lovea2
18591
18592         mkdir -p $DIR/$tdir
18593         touch $file1 || error "create $file1 failed"
18594         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18595                 error "create $file2 failed"
18596         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18597                 error "create $file3 failed"
18598         lovea1=$(get_layout_param $file1)
18599
18600         $LFS swap_layouts $file2 $file3 ||
18601                 error "swap $file2 $file3 layouts failed"
18602         $LFS swap_layouts $file1 $file2 ||
18603                 error "swap $file1 $file2 layouts failed"
18604
18605         lovea2=$(get_layout_param $file2)
18606         echo "$lovea1"
18607         echo "$lovea2"
18608         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18609
18610         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18611         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18612 }
18613 run_test 184d "allow stripeless layouts swap"
18614
18615 test_184e() {
18616         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18617                 skip "Need MDS version at least 2.6.94"
18618         check_swap_layouts_support
18619         check_swap_layout_no_dom $DIR
18620         [ -z "$(which getfattr 2>/dev/null)" ] &&
18621                 skip_env "no getfattr command"
18622
18623         local file1=$DIR/$tdir/$tfile-1
18624         local file2=$DIR/$tdir/$tfile-2
18625         local file3=$DIR/$tdir/$tfile-3
18626         local lovea
18627
18628         mkdir -p $DIR/$tdir
18629         touch $file1 || error "create $file1 failed"
18630         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18631                 error "create $file2 failed"
18632         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18633                 error "create $file3 failed"
18634
18635         $LFS swap_layouts $file1 $file2 ||
18636                 error "swap $file1 $file2 layouts failed"
18637
18638         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18639         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18640
18641         echo 123 > $file1 || error "Should be able to write into $file1"
18642
18643         $LFS swap_layouts $file1 $file3 ||
18644                 error "swap $file1 $file3 layouts failed"
18645
18646         echo 123 > $file1 || error "Should be able to write into $file1"
18647
18648         rm -rf $file1 $file2 $file3
18649 }
18650 run_test 184e "Recreate layout after stripeless layout swaps"
18651
18652 test_184f() {
18653         # Create a file with name longer than sizeof(struct stat) ==
18654         # 144 to see if we can get chars from the file name to appear
18655         # in the returned striping. Note that 'f' == 0x66.
18656         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18657
18658         mkdir -p $DIR/$tdir
18659         mcreate $DIR/$tdir/$file
18660         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18661                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18662         fi
18663 }
18664 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18665
18666 test_185() { # LU-2441
18667         # LU-3553 - no volatile file support in old servers
18668         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18669                 skip "Need MDS version at least 2.3.60"
18670
18671         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18672         touch $DIR/$tdir/spoo
18673         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18674         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18675                 error "cannot create/write a volatile file"
18676         [ "$FILESET" == "" ] &&
18677         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18678                 error "FID is still valid after close"
18679
18680         multiop_bg_pause $DIR/$tdir vVw4096_c
18681         local multi_pid=$!
18682
18683         local OLD_IFS=$IFS
18684         IFS=":"
18685         local fidv=($fid)
18686         IFS=$OLD_IFS
18687         # assume that the next FID for this client is sequential, since stdout
18688         # is unfortunately eaten by multiop_bg_pause
18689         local n=$((${fidv[1]} + 1))
18690         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18691         if [ "$FILESET" == "" ]; then
18692                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18693                         error "FID is missing before close"
18694         fi
18695         kill -USR1 $multi_pid
18696         # 1 second delay, so if mtime change we will see it
18697         sleep 1
18698         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18699         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18700 }
18701 run_test 185 "Volatile file support"
18702
18703 function create_check_volatile() {
18704         local idx=$1
18705         local tgt
18706
18707         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18708         local PID=$!
18709         sleep 1
18710         local FID=$(cat /tmp/${tfile}.fid)
18711         [ "$FID" == "" ] && error "can't get FID for volatile"
18712         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18713         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18714         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18715         kill -USR1 $PID
18716         wait
18717         sleep 1
18718         cancel_lru_locks mdc # flush opencache
18719         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18720         return 0
18721 }
18722
18723 test_185a(){
18724         # LU-12516 - volatile creation via .lustre
18725         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18726                 skip "Need MDS version at least 2.3.55"
18727
18728         create_check_volatile 0
18729         [ $MDSCOUNT -lt 2 ] && return 0
18730
18731         # DNE case
18732         create_check_volatile 1
18733
18734         return 0
18735 }
18736 run_test 185a "Volatile file creation in .lustre/fid/"
18737
18738 test_187a() {
18739         remote_mds_nodsh && skip "remote MDS with nodsh"
18740         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18741                 skip "Need MDS version at least 2.3.0"
18742
18743         local dir0=$DIR/$tdir/$testnum
18744         mkdir -p $dir0 || error "creating dir $dir0"
18745
18746         local file=$dir0/file1
18747         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18748         local dv1=$($LFS data_version $file)
18749         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18750         local dv2=$($LFS data_version $file)
18751         [[ $dv1 != $dv2 ]] ||
18752                 error "data version did not change on write $dv1 == $dv2"
18753
18754         # clean up
18755         rm -f $file1
18756 }
18757 run_test 187a "Test data version change"
18758
18759 test_187b() {
18760         remote_mds_nodsh && skip "remote MDS with nodsh"
18761         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18762                 skip "Need MDS version at least 2.3.0"
18763
18764         local dir0=$DIR/$tdir/$testnum
18765         mkdir -p $dir0 || error "creating dir $dir0"
18766
18767         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18768         [[ ${DV[0]} != ${DV[1]} ]] ||
18769                 error "data version did not change on write"\
18770                       " ${DV[0]} == ${DV[1]}"
18771
18772         # clean up
18773         rm -f $file1
18774 }
18775 run_test 187b "Test data version change on volatile file"
18776
18777 test_200() {
18778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18779         remote_mgs_nodsh && skip "remote MGS with nodsh"
18780         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18781
18782         local POOL=${POOL:-cea1}
18783         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18784         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18785         # Pool OST targets
18786         local first_ost=0
18787         local last_ost=$(($OSTCOUNT - 1))
18788         local ost_step=2
18789         local ost_list=$(seq $first_ost $ost_step $last_ost)
18790         local ost_range="$first_ost $last_ost $ost_step"
18791         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18792         local file_dir=$POOL_ROOT/file_tst
18793         local subdir=$test_path/subdir
18794         local rc=0
18795
18796         while : ; do
18797                 # former test_200a test_200b
18798                 pool_add $POOL                          || { rc=$? ; break; }
18799                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18800                 # former test_200c test_200d
18801                 mkdir -p $test_path
18802                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18803                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18804                 mkdir -p $subdir
18805                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18806                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18807                                                         || { rc=$? ; break; }
18808                 # former test_200e test_200f
18809                 local files=$((OSTCOUNT*3))
18810                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18811                                                         || { rc=$? ; break; }
18812                 pool_create_files $POOL $file_dir $files "$ost_list" \
18813                                                         || { rc=$? ; break; }
18814                 # former test_200g test_200h
18815                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18816                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18817
18818                 # former test_201a test_201b test_201c
18819                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18820
18821                 local f=$test_path/$tfile
18822                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18823                 pool_remove $POOL $f                    || { rc=$? ; break; }
18824                 break
18825         done
18826
18827         destroy_test_pools
18828
18829         return $rc
18830 }
18831 run_test 200 "OST pools"
18832
18833 # usage: default_attr <count | size | offset>
18834 default_attr() {
18835         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18836 }
18837
18838 # usage: check_default_stripe_attr
18839 check_default_stripe_attr() {
18840         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18841         case $1 in
18842         --stripe-count|-c)
18843                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18844         --stripe-size|-S)
18845                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18846         --stripe-index|-i)
18847                 EXPECTED=-1;;
18848         *)
18849                 error "unknown getstripe attr '$1'"
18850         esac
18851
18852         [ $ACTUAL == $EXPECTED ] ||
18853                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18854 }
18855
18856 test_204a() {
18857         test_mkdir $DIR/$tdir
18858         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18859
18860         check_default_stripe_attr --stripe-count
18861         check_default_stripe_attr --stripe-size
18862         check_default_stripe_attr --stripe-index
18863 }
18864 run_test 204a "Print default stripe attributes"
18865
18866 test_204b() {
18867         test_mkdir $DIR/$tdir
18868         $LFS setstripe --stripe-count 1 $DIR/$tdir
18869
18870         check_default_stripe_attr --stripe-size
18871         check_default_stripe_attr --stripe-index
18872 }
18873 run_test 204b "Print default stripe size and offset"
18874
18875 test_204c() {
18876         test_mkdir $DIR/$tdir
18877         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18878
18879         check_default_stripe_attr --stripe-count
18880         check_default_stripe_attr --stripe-index
18881 }
18882 run_test 204c "Print default stripe count and offset"
18883
18884 test_204d() {
18885         test_mkdir $DIR/$tdir
18886         $LFS setstripe --stripe-index 0 $DIR/$tdir
18887
18888         check_default_stripe_attr --stripe-count
18889         check_default_stripe_attr --stripe-size
18890 }
18891 run_test 204d "Print default stripe count and size"
18892
18893 test_204e() {
18894         test_mkdir $DIR/$tdir
18895         $LFS setstripe -d $DIR/$tdir
18896
18897         check_default_stripe_attr --stripe-count --raw
18898         check_default_stripe_attr --stripe-size --raw
18899         check_default_stripe_attr --stripe-index --raw
18900 }
18901 run_test 204e "Print raw stripe attributes"
18902
18903 test_204f() {
18904         test_mkdir $DIR/$tdir
18905         $LFS setstripe --stripe-count 1 $DIR/$tdir
18906
18907         check_default_stripe_attr --stripe-size --raw
18908         check_default_stripe_attr --stripe-index --raw
18909 }
18910 run_test 204f "Print raw stripe size and offset"
18911
18912 test_204g() {
18913         test_mkdir $DIR/$tdir
18914         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18915
18916         check_default_stripe_attr --stripe-count --raw
18917         check_default_stripe_attr --stripe-index --raw
18918 }
18919 run_test 204g "Print raw stripe count and offset"
18920
18921 test_204h() {
18922         test_mkdir $DIR/$tdir
18923         $LFS setstripe --stripe-index 0 $DIR/$tdir
18924
18925         check_default_stripe_attr --stripe-count --raw
18926         check_default_stripe_attr --stripe-size --raw
18927 }
18928 run_test 204h "Print raw stripe count and size"
18929
18930 # Figure out which job scheduler is being used, if any,
18931 # or use a fake one
18932 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18933         JOBENV=SLURM_JOB_ID
18934 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18935         JOBENV=LSB_JOBID
18936 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18937         JOBENV=PBS_JOBID
18938 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18939         JOBENV=LOADL_STEP_ID
18940 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18941         JOBENV=JOB_ID
18942 else
18943         $LCTL list_param jobid_name > /dev/null 2>&1
18944         if [ $? -eq 0 ]; then
18945                 JOBENV=nodelocal
18946         else
18947                 JOBENV=FAKE_JOBID
18948         fi
18949 fi
18950 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18951
18952 verify_jobstats() {
18953         local cmd=($1)
18954         shift
18955         local facets="$@"
18956
18957 # we don't really need to clear the stats for this test to work, since each
18958 # command has a unique jobid, but it makes debugging easier if needed.
18959 #       for facet in $facets; do
18960 #               local dev=$(convert_facet2label $facet)
18961 #               # clear old jobstats
18962 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18963 #       done
18964
18965         # use a new JobID for each test, or we might see an old one
18966         [ "$JOBENV" = "FAKE_JOBID" ] &&
18967                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18968
18969         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18970
18971         [ "$JOBENV" = "nodelocal" ] && {
18972                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18973                 $LCTL set_param jobid_name=$FAKE_JOBID
18974                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18975         }
18976
18977         log "Test: ${cmd[*]}"
18978         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18979
18980         if [ $JOBENV = "FAKE_JOBID" ]; then
18981                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18982         else
18983                 ${cmd[*]}
18984         fi
18985
18986         # all files are created on OST0000
18987         for facet in $facets; do
18988                 local stats="*.$(convert_facet2label $facet).job_stats"
18989
18990                 # strip out libtool wrappers for in-tree executables
18991                 if (( $(do_facet $facet lctl get_param $stats |
18992                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18993                         do_facet $facet lctl get_param $stats
18994                         error "No jobstats for $JOBVAL found on $facet::$stats"
18995                 fi
18996         done
18997 }
18998
18999 jobstats_set() {
19000         local new_jobenv=$1
19001
19002         set_persistent_param_and_check client "jobid_var" \
19003                 "$FSNAME.sys.jobid_var" $new_jobenv
19004 }
19005
19006 test_205a() { # Job stats
19007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19008         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19009                 skip "Need MDS version with at least 2.7.1"
19010         remote_mgs_nodsh && skip "remote MGS with nodsh"
19011         remote_mds_nodsh && skip "remote MDS with nodsh"
19012         remote_ost_nodsh && skip "remote OST with nodsh"
19013         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19014                 skip "Server doesn't support jobstats"
19015         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19016
19017         local old_jobenv=$($LCTL get_param -n jobid_var)
19018         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19019
19020         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19021                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19022         else
19023                 stack_trap "do_facet mgs $PERM_CMD \
19024                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19025         fi
19026         changelog_register
19027
19028         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19029                                 mdt.*.job_cleanup_interval | head -n 1)
19030         local new_interval=5
19031         do_facet $SINGLEMDS \
19032                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19033         stack_trap "do_facet $SINGLEMDS \
19034                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19035         local start=$SECONDS
19036
19037         local cmd
19038         # mkdir
19039         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19040         verify_jobstats "$cmd" "$SINGLEMDS"
19041         # rmdir
19042         cmd="rmdir $DIR/$tdir"
19043         verify_jobstats "$cmd" "$SINGLEMDS"
19044         # mkdir on secondary MDT
19045         if [ $MDSCOUNT -gt 1 ]; then
19046                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19047                 verify_jobstats "$cmd" "mds2"
19048         fi
19049         # mknod
19050         cmd="mknod $DIR/$tfile c 1 3"
19051         verify_jobstats "$cmd" "$SINGLEMDS"
19052         # unlink
19053         cmd="rm -f $DIR/$tfile"
19054         verify_jobstats "$cmd" "$SINGLEMDS"
19055         # create all files on OST0000 so verify_jobstats can find OST stats
19056         # open & close
19057         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19058         verify_jobstats "$cmd" "$SINGLEMDS"
19059         # setattr
19060         cmd="touch $DIR/$tfile"
19061         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19062         # write
19063         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19064         verify_jobstats "$cmd" "ost1"
19065         # read
19066         cancel_lru_locks osc
19067         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19068         verify_jobstats "$cmd" "ost1"
19069         # truncate
19070         cmd="$TRUNCATE $DIR/$tfile 0"
19071         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19072         # rename
19073         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19074         verify_jobstats "$cmd" "$SINGLEMDS"
19075         # jobstats expiry - sleep until old stats should be expired
19076         local left=$((new_interval + 5 - (SECONDS - start)))
19077         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19078                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19079                         "0" $left
19080         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19081         verify_jobstats "$cmd" "$SINGLEMDS"
19082         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19083             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19084
19085         # Ensure that jobid are present in changelog (if supported by MDS)
19086         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19087                 changelog_dump | tail -10
19088                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19089                 [ $jobids -eq 9 ] ||
19090                         error "Wrong changelog jobid count $jobids != 9"
19091
19092                 # LU-5862
19093                 JOBENV="disable"
19094                 jobstats_set $JOBENV
19095                 touch $DIR/$tfile
19096                 changelog_dump | grep $tfile
19097                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19098                 [ $jobids -eq 0 ] ||
19099                         error "Unexpected jobids when jobid_var=$JOBENV"
19100         fi
19101
19102         # test '%j' access to environment variable - if supported
19103         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19104                 JOBENV="JOBCOMPLEX"
19105                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19106
19107                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19108         fi
19109
19110         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19111                 JOBENV="JOBCOMPLEX"
19112                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19113
19114                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19115         fi
19116
19117         # test '%j' access to per-session jobid - if supported
19118         if lctl list_param jobid_this_session > /dev/null 2>&1
19119         then
19120                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19121                 lctl set_param jobid_this_session=$USER
19122
19123                 JOBENV="JOBCOMPLEX"
19124                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19125
19126                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19127         fi
19128 }
19129 run_test 205a "Verify job stats"
19130
19131 # LU-13117, LU-13597
19132 test_205b() {
19133         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19134                 skip "Need MDS version at least 2.13.54.91"
19135
19136         local job_stats="mdt.*.job_stats"
19137         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19138
19139         do_facet mds1 $LCTL set_param $job_stats=clear
19140
19141         # Setting jobid_var to USER might not be supported
19142         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19143         $LCTL set_param jobid_var=USER || true
19144         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19145         $LCTL set_param jobid_name="%j.%e.%u"
19146
19147         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19148         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19149                 { do_facet mds1 $LCTL get_param $job_stats;
19150                   error "Unexpected jobid found"; }
19151         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19152                 { do_facet mds1 $LCTL get_param $job_stats;
19153                   error "wrong job_stats format found"; }
19154
19155         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19156                 echo "MDS does not yet escape jobid" && return 0
19157         $LCTL set_param jobid_var=TEST205b
19158         env -i TEST205b="has sp" touch $DIR/$tfile.2
19159         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19160                 { do_facet mds1 $LCTL get_param $job_stats;
19161                   error "jobid not escaped"; }
19162 }
19163 run_test 205b "Verify job stats jobid and output format"
19164
19165 # LU-13733
19166 test_205c() {
19167         $LCTL set_param llite.*.stats=0
19168         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19169         $LCTL get_param llite.*.stats
19170         $LCTL get_param llite.*.stats | grep \
19171                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19172                         error "wrong client stats format found"
19173 }
19174 run_test 205c "Verify client stats format"
19175
19176 test_205d() {
19177         local file=$DIR/$tdir/$tfile
19178
19179         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
19180                 skip "need lustre >= 2.15.51"
19181         (( $OST1_VERSION >= $(version_code 2.15.52) )) ||
19182                 skip "need lustre >= 2.15.51"
19183         verify_yaml_available || skip_env "YAML verification not installed"
19184
19185         test_mkdir $DIR/$tdir
19186         $LFS setstripe -E 1M -L mdt -E -1 $file || error "setstripe failed"
19187
19188         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19189                 error "failed to write data to $file"
19190         mv $file $file.2
19191
19192         echo -n 'verify rename_stats...'
19193         output=$(do_facet mds1 \
19194                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats")
19195         verify_yaml "$output" || error "rename_stats is not valid YAML"
19196         echo " OK"
19197
19198         echo -n 'verify mdt job_stats...'
19199         output=$(do_facet mds1 \
19200                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats")
19201         verify_yaml "$output" || error "job_stats on mds1 is not valid YAML"
19202         echo " OK"
19203
19204         echo -n 'verify ost job_stats...'
19205         output=$(do_facet ost1 \
19206                  "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats")
19207         verify_yaml "$output" || error "job_stats on ost1 is not valid YAML"
19208         echo " OK"
19209 }
19210 run_test 205d "verify the format of some stats files"
19211
19212 # LU-1480, LU-1773 and LU-1657
19213 test_206() {
19214         mkdir -p $DIR/$tdir
19215         $LFS setstripe -c -1 $DIR/$tdir
19216 #define OBD_FAIL_LOV_INIT 0x1403
19217         $LCTL set_param fail_loc=0xa0001403
19218         $LCTL set_param fail_val=1
19219         touch $DIR/$tdir/$tfile || true
19220 }
19221 run_test 206 "fail lov_init_raid0() doesn't lbug"
19222
19223 test_207a() {
19224         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19225         local fsz=`stat -c %s $DIR/$tfile`
19226         cancel_lru_locks mdc
19227
19228         # do not return layout in getattr intent
19229 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19230         $LCTL set_param fail_loc=0x170
19231         local sz=`stat -c %s $DIR/$tfile`
19232
19233         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19234
19235         rm -rf $DIR/$tfile
19236 }
19237 run_test 207a "can refresh layout at glimpse"
19238
19239 test_207b() {
19240         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19241         local cksum=`md5sum $DIR/$tfile`
19242         local fsz=`stat -c %s $DIR/$tfile`
19243         cancel_lru_locks mdc
19244         cancel_lru_locks osc
19245
19246         # do not return layout in getattr intent
19247 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19248         $LCTL set_param fail_loc=0x171
19249
19250         # it will refresh layout after the file is opened but before read issues
19251         echo checksum is "$cksum"
19252         echo "$cksum" |md5sum -c --quiet || error "file differs"
19253
19254         rm -rf $DIR/$tfile
19255 }
19256 run_test 207b "can refresh layout at open"
19257
19258 test_208() {
19259         # FIXME: in this test suite, only RD lease is used. This is okay
19260         # for now as only exclusive open is supported. After generic lease
19261         # is done, this test suite should be revised. - Jinshan
19262
19263         remote_mds_nodsh && skip "remote MDS with nodsh"
19264         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19265                 skip "Need MDS version at least 2.4.52"
19266
19267         echo "==== test 1: verify get lease work"
19268         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19269
19270         echo "==== test 2: verify lease can be broken by upcoming open"
19271         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19272         local PID=$!
19273         sleep 2
19274
19275         $MULTIOP $DIR/$tfile oO_RDWR:c
19276         kill -USR1 $PID && wait $PID || error "break lease error"
19277
19278         echo "==== test 3: verify lease can't be granted if an open already exists"
19279         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19280         local PID=$!
19281         sleep 2
19282
19283         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19284         kill -USR1 $PID && wait $PID || error "open file error"
19285
19286         echo "==== test 4: lease can sustain over recovery"
19287         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19288         PID=$!
19289         sleep 2
19290
19291         fail mds1
19292
19293         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19294
19295         echo "==== test 5: lease broken can't be regained by replay"
19296         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19297         PID=$!
19298         sleep 2
19299
19300         # open file to break lease and then recovery
19301         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19302         fail mds1
19303
19304         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19305
19306         rm -f $DIR/$tfile
19307 }
19308 run_test 208 "Exclusive open"
19309
19310 test_209() {
19311         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19312                 skip_env "must have disp_stripe"
19313
19314         touch $DIR/$tfile
19315         sync; sleep 5; sync;
19316
19317         echo 3 > /proc/sys/vm/drop_caches
19318         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19319                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19320         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19321
19322         # open/close 500 times
19323         for i in $(seq 500); do
19324                 cat $DIR/$tfile
19325         done
19326
19327         echo 3 > /proc/sys/vm/drop_caches
19328         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19329                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19330         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19331
19332         echo "before: $req_before, after: $req_after"
19333         [ $((req_after - req_before)) -ge 300 ] &&
19334                 error "open/close requests are not freed"
19335         return 0
19336 }
19337 run_test 209 "read-only open/close requests should be freed promptly"
19338
19339 test_210() {
19340         local pid
19341
19342         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19343         pid=$!
19344         sleep 1
19345
19346         $LFS getstripe $DIR/$tfile
19347         kill -USR1 $pid
19348         wait $pid || error "multiop failed"
19349
19350         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19351         pid=$!
19352         sleep 1
19353
19354         $LFS getstripe $DIR/$tfile
19355         kill -USR1 $pid
19356         wait $pid || error "multiop failed"
19357 }
19358 run_test 210 "lfs getstripe does not break leases"
19359
19360 test_212() {
19361         size=`date +%s`
19362         size=$((size % 8192 + 1))
19363         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19364         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19365         rm -f $DIR/f212 $DIR/f212.xyz
19366 }
19367 run_test 212 "Sendfile test ============================================"
19368
19369 test_213() {
19370         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19371         cancel_lru_locks osc
19372         lctl set_param fail_loc=0x8000040f
19373         # generate a read lock
19374         cat $DIR/$tfile > /dev/null
19375         # write to the file, it will try to cancel the above read lock.
19376         cat /etc/hosts >> $DIR/$tfile
19377 }
19378 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19379
19380 test_214() { # for bug 20133
19381         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19382         for (( i=0; i < 340; i++ )) ; do
19383                 touch $DIR/$tdir/d214c/a$i
19384         done
19385
19386         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19387         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19388         ls $DIR/d214c || error "ls $DIR/d214c failed"
19389         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19390         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19391 }
19392 run_test 214 "hash-indexed directory test - bug 20133"
19393
19394 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19395 create_lnet_proc_files() {
19396         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19397 }
19398
19399 # counterpart of create_lnet_proc_files
19400 remove_lnet_proc_files() {
19401         rm -f $TMP/lnet_$1.sys
19402 }
19403
19404 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19405 # 3rd arg as regexp for body
19406 check_lnet_proc_stats() {
19407         local l=$(cat "$TMP/lnet_$1" |wc -l)
19408         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19409
19410         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19411 }
19412
19413 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19414 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19415 # optional and can be regexp for 2nd line (lnet.routes case)
19416 check_lnet_proc_entry() {
19417         local blp=2          # blp stands for 'position of 1st line of body'
19418         [ -z "$5" ] || blp=3 # lnet.routes case
19419
19420         local l=$(cat "$TMP/lnet_$1" |wc -l)
19421         # subtracting one from $blp because the body can be empty
19422         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19423
19424         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19425                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19426
19427         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19428                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19429
19430         # bail out if any unexpected line happened
19431         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19432         [ "$?" != 0 ] || error "$2 misformatted"
19433 }
19434
19435 test_215() { # for bugs 18102, 21079, 21517
19436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19437
19438         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19439         local P='[1-9][0-9]*'           # positive numeric
19440         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19441         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19442         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19443         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19444
19445         local L1 # regexp for 1st line
19446         local L2 # regexp for 2nd line (optional)
19447         local BR # regexp for the rest (body)
19448
19449         # lnet.stats should look as 11 space-separated non-negative numerics
19450         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19451         create_lnet_proc_files "stats"
19452         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19453         remove_lnet_proc_files "stats"
19454
19455         # lnet.routes should look like this:
19456         # Routing disabled/enabled
19457         # net hops priority state router
19458         # where net is a string like tcp0, hops > 0, priority >= 0,
19459         # state is up/down,
19460         # router is a string like 192.168.1.1@tcp2
19461         L1="^Routing (disabled|enabled)$"
19462         L2="^net +hops +priority +state +router$"
19463         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19464         create_lnet_proc_files "routes"
19465         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19466         remove_lnet_proc_files "routes"
19467
19468         # lnet.routers should look like this:
19469         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19470         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19471         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19472         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19473         L1="^ref +rtr_ref +alive +router$"
19474         BR="^$P +$P +(up|down) +$NID$"
19475         create_lnet_proc_files "routers"
19476         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19477         remove_lnet_proc_files "routers"
19478
19479         # lnet.peers should look like this:
19480         # nid refs state last max rtr min tx min queue
19481         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19482         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19483         # numeric (0 or >0 or <0), queue >= 0.
19484         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19485         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19486         create_lnet_proc_files "peers"
19487         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19488         remove_lnet_proc_files "peers"
19489
19490         # lnet.buffers  should look like this:
19491         # pages count credits min
19492         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19493         L1="^pages +count +credits +min$"
19494         BR="^ +$N +$N +$I +$I$"
19495         create_lnet_proc_files "buffers"
19496         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19497         remove_lnet_proc_files "buffers"
19498
19499         # lnet.nis should look like this:
19500         # nid status alive refs peer rtr max tx min
19501         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19502         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19503         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19504         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19505         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19506         create_lnet_proc_files "nis"
19507         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19508         remove_lnet_proc_files "nis"
19509
19510         # can we successfully write to lnet.stats?
19511         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19512 }
19513 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19514
19515 test_216() { # bug 20317
19516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19517         remote_ost_nodsh && skip "remote OST with nodsh"
19518
19519         local node
19520         local facets=$(get_facets OST)
19521         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19522
19523         save_lustre_params client "osc.*.contention_seconds" > $p
19524         save_lustre_params $facets \
19525                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19526         save_lustre_params $facets \
19527                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19528         save_lustre_params $facets \
19529                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19530         clear_stats osc.*.osc_stats
19531
19532         # agressive lockless i/o settings
19533         do_nodes $(comma_list $(osts_nodes)) \
19534                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19535                         ldlm.namespaces.filter-*.contended_locks=0 \
19536                         ldlm.namespaces.filter-*.contention_seconds=60"
19537         lctl set_param -n osc.*.contention_seconds=60
19538
19539         $DIRECTIO write $DIR/$tfile 0 10 4096
19540         $CHECKSTAT -s 40960 $DIR/$tfile
19541
19542         # disable lockless i/o
19543         do_nodes $(comma_list $(osts_nodes)) \
19544                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19545                         ldlm.namespaces.filter-*.contended_locks=32 \
19546                         ldlm.namespaces.filter-*.contention_seconds=0"
19547         lctl set_param -n osc.*.contention_seconds=0
19548         clear_stats osc.*.osc_stats
19549
19550         dd if=/dev/zero of=$DIR/$tfile count=0
19551         $CHECKSTAT -s 0 $DIR/$tfile
19552
19553         restore_lustre_params <$p
19554         rm -f $p
19555         rm $DIR/$tfile
19556 }
19557 run_test 216 "check lockless direct write updates file size and kms correctly"
19558
19559 test_217() { # bug 22430
19560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19561
19562         local node
19563         local nid
19564
19565         for node in $(nodes_list); do
19566                 nid=$(host_nids_address $node $NETTYPE)
19567                 if [[ $nid = *-* ]] ; then
19568                         echo "lctl ping $(h2nettype $nid)"
19569                         lctl ping $(h2nettype $nid)
19570                 else
19571                         echo "skipping $node (no hyphen detected)"
19572                 fi
19573         done
19574 }
19575 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19576
19577 test_218() {
19578        # do directio so as not to populate the page cache
19579        log "creating a 10 Mb file"
19580        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19581        log "starting reads"
19582        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19583        log "truncating the file"
19584        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19585        log "killing dd"
19586        kill %+ || true # reads might have finished
19587        echo "wait until dd is finished"
19588        wait
19589        log "removing the temporary file"
19590        rm -rf $DIR/$tfile || error "tmp file removal failed"
19591 }
19592 run_test 218 "parallel read and truncate should not deadlock"
19593
19594 test_219() {
19595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19596
19597         # write one partial page
19598         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19599         # set no grant so vvp_io_commit_write will do sync write
19600         $LCTL set_param fail_loc=0x411
19601         # write a full page at the end of file
19602         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19603
19604         $LCTL set_param fail_loc=0
19605         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19606         $LCTL set_param fail_loc=0x411
19607         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19608
19609         # LU-4201
19610         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19611         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19612 }
19613 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19614
19615 test_220() { #LU-325
19616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19617         remote_ost_nodsh && skip "remote OST with nodsh"
19618         remote_mds_nodsh && skip "remote MDS with nodsh"
19619         remote_mgs_nodsh && skip "remote MGS with nodsh"
19620
19621         local OSTIDX=0
19622
19623         # create on MDT0000 so the last_id and next_id are correct
19624         mkdir_on_mdt0 $DIR/$tdir
19625         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19626         OST=${OST%_UUID}
19627
19628         # on the mdt's osc
19629         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19630         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19631                         osp.$mdtosc_proc1.prealloc_last_id)
19632         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19633                         osp.$mdtosc_proc1.prealloc_next_id)
19634
19635         $LFS df -i
19636
19637         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19638         #define OBD_FAIL_OST_ENOINO              0x229
19639         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19640         create_pool $FSNAME.$TESTNAME || return 1
19641         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19642
19643         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19644
19645         MDSOBJS=$((last_id - next_id))
19646         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19647
19648         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19649         echo "OST still has $count kbytes free"
19650
19651         echo "create $MDSOBJS files @next_id..."
19652         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19653
19654         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19655                         osp.$mdtosc_proc1.prealloc_last_id)
19656         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19657                         osp.$mdtosc_proc1.prealloc_next_id)
19658
19659         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19660         $LFS df -i
19661
19662         echo "cleanup..."
19663
19664         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19665         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19666
19667         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19668                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19669         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19670                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19671         echo "unlink $MDSOBJS files @$next_id..."
19672         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19673 }
19674 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19675
19676 test_221() {
19677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19678
19679         dd if=`which date` of=$MOUNT/date oflag=sync
19680         chmod +x $MOUNT/date
19681
19682         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19683         $LCTL set_param fail_loc=0x80001401
19684
19685         $MOUNT/date > /dev/null
19686         rm -f $MOUNT/date
19687 }
19688 run_test 221 "make sure fault and truncate race to not cause OOM"
19689
19690 test_222a () {
19691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19692
19693         rm -rf $DIR/$tdir
19694         test_mkdir $DIR/$tdir
19695         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19696         createmany -o $DIR/$tdir/$tfile 10
19697         cancel_lru_locks mdc
19698         cancel_lru_locks osc
19699         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19700         $LCTL set_param fail_loc=0x31a
19701         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19702         $LCTL set_param fail_loc=0
19703         rm -r $DIR/$tdir
19704 }
19705 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19706
19707 test_222b () {
19708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19709
19710         rm -rf $DIR/$tdir
19711         test_mkdir $DIR/$tdir
19712         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19713         createmany -o $DIR/$tdir/$tfile 10
19714         cancel_lru_locks mdc
19715         cancel_lru_locks osc
19716         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19717         $LCTL set_param fail_loc=0x31a
19718         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19719         $LCTL set_param fail_loc=0
19720 }
19721 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19722
19723 test_223 () {
19724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19725
19726         rm -rf $DIR/$tdir
19727         test_mkdir $DIR/$tdir
19728         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19729         createmany -o $DIR/$tdir/$tfile 10
19730         cancel_lru_locks mdc
19731         cancel_lru_locks osc
19732         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19733         $LCTL set_param fail_loc=0x31b
19734         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19735         $LCTL set_param fail_loc=0
19736         rm -r $DIR/$tdir
19737 }
19738 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19739
19740 test_224a() { # LU-1039, MRP-303
19741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19742         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19743         $LCTL set_param fail_loc=0x508
19744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19745         $LCTL set_param fail_loc=0
19746         df $DIR
19747 }
19748 run_test 224a "Don't panic on bulk IO failure"
19749
19750 test_224bd_sub() { # LU-1039, MRP-303
19751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19752         local timeout=$1
19753
19754         shift
19755         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19756
19757         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19758
19759         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19760         cancel_lru_locks osc
19761         set_checksums 0
19762         stack_trap "set_checksums $ORIG_CSUM" EXIT
19763         local at_max_saved=0
19764
19765         # adaptive timeouts may prevent seeing the issue
19766         if at_is_enabled; then
19767                 at_max_saved=$(at_max_get mds)
19768                 at_max_set 0 mds client
19769                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19770         fi
19771
19772         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19773         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19774         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19775
19776         do_facet ost1 $LCTL set_param fail_loc=0
19777         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19778         df $DIR
19779 }
19780
19781 test_224b() {
19782         test_224bd_sub 3 error "dd failed"
19783 }
19784 run_test 224b "Don't panic on bulk IO failure"
19785
19786 test_224c() { # LU-6441
19787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19788         remote_mds_nodsh && skip "remote MDS with nodsh"
19789
19790         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19791         save_writethrough $p
19792         set_cache writethrough on
19793
19794         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19795         local at_max=$($LCTL get_param -n at_max)
19796         local timeout=$($LCTL get_param -n timeout)
19797         local test_at="at_max"
19798         local param_at="$FSNAME.sys.at_max"
19799         local test_timeout="timeout"
19800         local param_timeout="$FSNAME.sys.timeout"
19801
19802         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19803
19804         set_persistent_param_and_check client "$test_at" "$param_at" 0
19805         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19806
19807         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19808         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19809         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19810         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19811         sync
19812         do_facet ost1 "$LCTL set_param fail_loc=0"
19813
19814         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19815         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19816                 $timeout
19817
19818         $LCTL set_param -n $pages_per_rpc
19819         restore_lustre_params < $p
19820         rm -f $p
19821 }
19822 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19823
19824 test_224d() { # LU-11169
19825         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19826 }
19827 run_test 224d "Don't corrupt data on bulk IO timeout"
19828
19829 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19830 test_225a () {
19831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19832         if [ -z ${MDSSURVEY} ]; then
19833                 skip_env "mds-survey not found"
19834         fi
19835         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19836                 skip "Need MDS version at least 2.2.51"
19837
19838         local mds=$(facet_host $SINGLEMDS)
19839         local target=$(do_nodes $mds 'lctl dl' |
19840                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19841
19842         local cmd1="file_count=1000 thrhi=4"
19843         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19844         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19845         local cmd="$cmd1 $cmd2 $cmd3"
19846
19847         rm -f ${TMP}/mds_survey*
19848         echo + $cmd
19849         eval $cmd || error "mds-survey with zero-stripe failed"
19850         cat ${TMP}/mds_survey*
19851         rm -f ${TMP}/mds_survey*
19852 }
19853 run_test 225a "Metadata survey sanity with zero-stripe"
19854
19855 test_225b () {
19856         if [ -z ${MDSSURVEY} ]; then
19857                 skip_env "mds-survey not found"
19858         fi
19859         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19860                 skip "Need MDS version at least 2.2.51"
19861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19862         remote_mds_nodsh && skip "remote MDS with nodsh"
19863         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19864                 skip_env "Need to mount OST to test"
19865         fi
19866
19867         local mds=$(facet_host $SINGLEMDS)
19868         local target=$(do_nodes $mds 'lctl dl' |
19869                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19870
19871         local cmd1="file_count=1000 thrhi=4"
19872         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19873         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19874         local cmd="$cmd1 $cmd2 $cmd3"
19875
19876         rm -f ${TMP}/mds_survey*
19877         echo + $cmd
19878         eval $cmd || error "mds-survey with stripe_count failed"
19879         cat ${TMP}/mds_survey*
19880         rm -f ${TMP}/mds_survey*
19881 }
19882 run_test 225b "Metadata survey sanity with stripe_count = 1"
19883
19884 mcreate_path2fid () {
19885         local mode=$1
19886         local major=$2
19887         local minor=$3
19888         local name=$4
19889         local desc=$5
19890         local path=$DIR/$tdir/$name
19891         local fid
19892         local rc
19893         local fid_path
19894
19895         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19896                 error "cannot create $desc"
19897
19898         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19899         rc=$?
19900         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19901
19902         fid_path=$($LFS fid2path $MOUNT $fid)
19903         rc=$?
19904         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19905
19906         [ "$path" == "$fid_path" ] ||
19907                 error "fid2path returned $fid_path, expected $path"
19908
19909         echo "pass with $path and $fid"
19910 }
19911
19912 test_226a () {
19913         rm -rf $DIR/$tdir
19914         mkdir -p $DIR/$tdir
19915
19916         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19917         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19918         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19919         mcreate_path2fid 0040666 0 0 dir "directory"
19920         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19921         mcreate_path2fid 0100666 0 0 file "regular file"
19922         mcreate_path2fid 0120666 0 0 link "symbolic link"
19923         mcreate_path2fid 0140666 0 0 sock "socket"
19924 }
19925 run_test 226a "call path2fid and fid2path on files of all type"
19926
19927 test_226b () {
19928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19929
19930         local MDTIDX=1
19931
19932         rm -rf $DIR/$tdir
19933         mkdir -p $DIR/$tdir
19934         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19935                 error "create remote directory failed"
19936         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19937         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19938                                 "character special file (null)"
19939         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19940                                 "character special file (no device)"
19941         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19942         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19943                                 "block special file (loop)"
19944         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19945         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19946         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19947 }
19948 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19949
19950 test_226c () {
19951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19952         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19953                 skip "Need MDS version at least 2.13.55"
19954
19955         local submnt=/mnt/submnt
19956         local srcfile=/etc/passwd
19957         local dstfile=$submnt/passwd
19958         local path
19959         local fid
19960
19961         rm -rf $DIR/$tdir
19962         rm -rf $submnt
19963         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19964                 error "create remote directory failed"
19965         mkdir -p $submnt || error "create $submnt failed"
19966         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19967                 error "mount $submnt failed"
19968         stack_trap "umount $submnt" EXIT
19969
19970         cp $srcfile $dstfile
19971         fid=$($LFS path2fid $dstfile)
19972         path=$($LFS fid2path $submnt "$fid")
19973         [ "$path" = "$dstfile" ] ||
19974                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19975 }
19976 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19977
19978 # LU-1299 Executing or running ldd on a truncated executable does not
19979 # cause an out-of-memory condition.
19980 test_227() {
19981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19982         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19983
19984         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19985         chmod +x $MOUNT/date
19986
19987         $MOUNT/date > /dev/null
19988         ldd $MOUNT/date > /dev/null
19989         rm -f $MOUNT/date
19990 }
19991 run_test 227 "running truncated executable does not cause OOM"
19992
19993 # LU-1512 try to reuse idle OI blocks
19994 test_228a() {
19995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19996         remote_mds_nodsh && skip "remote MDS with nodsh"
19997         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19998
19999         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20000         local myDIR=$DIR/$tdir
20001
20002         mkdir -p $myDIR
20003         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20004         $LCTL set_param fail_loc=0x80001002
20005         createmany -o $myDIR/t- 10000
20006         $LCTL set_param fail_loc=0
20007         # The guard is current the largest FID holder
20008         touch $myDIR/guard
20009         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20010                     tr -d '[')
20011         local IDX=$(($SEQ % 64))
20012
20013         do_facet $SINGLEMDS sync
20014         # Make sure journal flushed.
20015         sleep 6
20016         local blk1=$(do_facet $SINGLEMDS \
20017                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20018                      grep Blockcount | awk '{print $4}')
20019
20020         # Remove old files, some OI blocks will become idle.
20021         unlinkmany $myDIR/t- 10000
20022         # Create new files, idle OI blocks should be reused.
20023         createmany -o $myDIR/t- 2000
20024         do_facet $SINGLEMDS sync
20025         # Make sure journal flushed.
20026         sleep 6
20027         local blk2=$(do_facet $SINGLEMDS \
20028                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20029                      grep Blockcount | awk '{print $4}')
20030
20031         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20032 }
20033 run_test 228a "try to reuse idle OI blocks"
20034
20035 test_228b() {
20036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20037         remote_mds_nodsh && skip "remote MDS with nodsh"
20038         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20039
20040         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20041         local myDIR=$DIR/$tdir
20042
20043         mkdir -p $myDIR
20044         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20045         $LCTL set_param fail_loc=0x80001002
20046         createmany -o $myDIR/t- 10000
20047         $LCTL set_param fail_loc=0
20048         # The guard is current the largest FID holder
20049         touch $myDIR/guard
20050         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20051                     tr -d '[')
20052         local IDX=$(($SEQ % 64))
20053
20054         do_facet $SINGLEMDS sync
20055         # Make sure journal flushed.
20056         sleep 6
20057         local blk1=$(do_facet $SINGLEMDS \
20058                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20059                      grep Blockcount | awk '{print $4}')
20060
20061         # Remove old files, some OI blocks will become idle.
20062         unlinkmany $myDIR/t- 10000
20063
20064         # stop the MDT
20065         stop $SINGLEMDS || error "Fail to stop MDT."
20066         # remount the MDT
20067         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20068                 error "Fail to start MDT."
20069
20070         df $MOUNT || error "Fail to df."
20071         # Create new files, idle OI blocks should be reused.
20072         createmany -o $myDIR/t- 2000
20073         do_facet $SINGLEMDS sync
20074         # Make sure journal flushed.
20075         sleep 6
20076         local blk2=$(do_facet $SINGLEMDS \
20077                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20078                      grep Blockcount | awk '{print $4}')
20079
20080         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20081 }
20082 run_test 228b "idle OI blocks can be reused after MDT restart"
20083
20084 #LU-1881
20085 test_228c() {
20086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20087         remote_mds_nodsh && skip "remote MDS with nodsh"
20088         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20089
20090         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20091         local myDIR=$DIR/$tdir
20092
20093         mkdir -p $myDIR
20094         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20095         $LCTL set_param fail_loc=0x80001002
20096         # 20000 files can guarantee there are index nodes in the OI file
20097         createmany -o $myDIR/t- 20000
20098         $LCTL set_param fail_loc=0
20099         # The guard is current the largest FID holder
20100         touch $myDIR/guard
20101         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20102                     tr -d '[')
20103         local IDX=$(($SEQ % 64))
20104
20105         do_facet $SINGLEMDS sync
20106         # Make sure journal flushed.
20107         sleep 6
20108         local blk1=$(do_facet $SINGLEMDS \
20109                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20110                      grep Blockcount | awk '{print $4}')
20111
20112         # Remove old files, some OI blocks will become idle.
20113         unlinkmany $myDIR/t- 20000
20114         rm -f $myDIR/guard
20115         # The OI file should become empty now
20116
20117         # Create new files, idle OI blocks should be reused.
20118         createmany -o $myDIR/t- 2000
20119         do_facet $SINGLEMDS sync
20120         # Make sure journal flushed.
20121         sleep 6
20122         local blk2=$(do_facet $SINGLEMDS \
20123                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20124                      grep Blockcount | awk '{print $4}')
20125
20126         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20127 }
20128 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20129
20130 test_229() { # LU-2482, LU-3448
20131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20132         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20133         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20134                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20135
20136         rm -f $DIR/$tfile
20137
20138         # Create a file with a released layout and stripe count 2.
20139         $MULTIOP $DIR/$tfile H2c ||
20140                 error "failed to create file with released layout"
20141
20142         $LFS getstripe -v $DIR/$tfile
20143
20144         local pattern=$($LFS getstripe -L $DIR/$tfile)
20145         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20146
20147         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20148                 error "getstripe"
20149         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20150         stat $DIR/$tfile || error "failed to stat released file"
20151
20152         chown $RUNAS_ID $DIR/$tfile ||
20153                 error "chown $RUNAS_ID $DIR/$tfile failed"
20154
20155         chgrp $RUNAS_ID $DIR/$tfile ||
20156                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20157
20158         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20159         rm $DIR/$tfile || error "failed to remove released file"
20160 }
20161 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20162
20163 test_230a() {
20164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20165         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20166         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20167                 skip "Need MDS version at least 2.11.52"
20168
20169         local MDTIDX=1
20170
20171         test_mkdir $DIR/$tdir
20172         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20173         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20174         [ $mdt_idx -ne 0 ] &&
20175                 error "create local directory on wrong MDT $mdt_idx"
20176
20177         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20178                         error "create remote directory failed"
20179         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20180         [ $mdt_idx -ne $MDTIDX ] &&
20181                 error "create remote directory on wrong MDT $mdt_idx"
20182
20183         createmany -o $DIR/$tdir/test_230/t- 10 ||
20184                 error "create files on remote directory failed"
20185         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20186         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20187         rm -r $DIR/$tdir || error "unlink remote directory failed"
20188 }
20189 run_test 230a "Create remote directory and files under the remote directory"
20190
20191 test_230b() {
20192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20194         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20195                 skip "Need MDS version at least 2.11.52"
20196
20197         local MDTIDX=1
20198         local mdt_index
20199         local i
20200         local file
20201         local pid
20202         local stripe_count
20203         local migrate_dir=$DIR/$tdir/migrate_dir
20204         local other_dir=$DIR/$tdir/other_dir
20205
20206         test_mkdir $DIR/$tdir
20207         test_mkdir -i0 -c1 $migrate_dir
20208         test_mkdir -i0 -c1 $other_dir
20209         for ((i=0; i<10; i++)); do
20210                 mkdir -p $migrate_dir/dir_${i}
20211                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20212                         error "create files under remote dir failed $i"
20213         done
20214
20215         cp /etc/passwd $migrate_dir/$tfile
20216         cp /etc/passwd $other_dir/$tfile
20217         chattr +SAD $migrate_dir
20218         chattr +SAD $migrate_dir/$tfile
20219
20220         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20221         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20222         local old_dir_mode=$(stat -c%f $migrate_dir)
20223         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20224
20225         mkdir -p $migrate_dir/dir_default_stripe2
20226         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20227         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20228
20229         mkdir -p $other_dir
20230         ln $migrate_dir/$tfile $other_dir/luna
20231         ln $migrate_dir/$tfile $migrate_dir/sofia
20232         ln $other_dir/$tfile $migrate_dir/david
20233         ln -s $migrate_dir/$tfile $other_dir/zachary
20234         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20235         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20236
20237         local len
20238         local lnktgt
20239
20240         # inline symlink
20241         for len in 58 59 60; do
20242                 lnktgt=$(str_repeat 'l' $len)
20243                 touch $migrate_dir/$lnktgt
20244                 ln -s $lnktgt $migrate_dir/${len}char_ln
20245         done
20246
20247         # PATH_MAX
20248         for len in 4094 4095; do
20249                 lnktgt=$(str_repeat 'l' $len)
20250                 ln -s $lnktgt $migrate_dir/${len}char_ln
20251         done
20252
20253         # NAME_MAX
20254         for len in 254 255; do
20255                 touch $migrate_dir/$(str_repeat 'l' $len)
20256         done
20257
20258         $LFS migrate -m $MDTIDX $migrate_dir ||
20259                 error "fails on migrating remote dir to MDT1"
20260
20261         echo "migratate to MDT1, then checking.."
20262         for ((i = 0; i < 10; i++)); do
20263                 for file in $(find $migrate_dir/dir_${i}); do
20264                         mdt_index=$($LFS getstripe -m $file)
20265                         # broken symlink getstripe will fail
20266                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20267                                 error "$file is not on MDT${MDTIDX}"
20268                 done
20269         done
20270
20271         # the multiple link file should still in MDT0
20272         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20273         [ $mdt_index == 0 ] ||
20274                 error "$file is not on MDT${MDTIDX}"
20275
20276         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20277         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20278                 error " expect $old_dir_flag get $new_dir_flag"
20279
20280         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20281         [ "$old_file_flag" = "$new_file_flag" ] ||
20282                 error " expect $old_file_flag get $new_file_flag"
20283
20284         local new_dir_mode=$(stat -c%f $migrate_dir)
20285         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20286                 error "expect mode $old_dir_mode get $new_dir_mode"
20287
20288         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20289         [ "$old_file_mode" = "$new_file_mode" ] ||
20290                 error "expect mode $old_file_mode get $new_file_mode"
20291
20292         diff /etc/passwd $migrate_dir/$tfile ||
20293                 error "$tfile different after migration"
20294
20295         diff /etc/passwd $other_dir/luna ||
20296                 error "luna different after migration"
20297
20298         diff /etc/passwd $migrate_dir/sofia ||
20299                 error "sofia different after migration"
20300
20301         diff /etc/passwd $migrate_dir/david ||
20302                 error "david different after migration"
20303
20304         diff /etc/passwd $other_dir/zachary ||
20305                 error "zachary different after migration"
20306
20307         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20308                 error "${tfile}_ln different after migration"
20309
20310         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20311                 error "${tfile}_ln_other different after migration"
20312
20313         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20314         [ $stripe_count = 2 ] ||
20315                 error "dir strpe_count $d != 2 after migration."
20316
20317         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20318         [ $stripe_count = 2 ] ||
20319                 error "file strpe_count $d != 2 after migration."
20320
20321         #migrate back to MDT0
20322         MDTIDX=0
20323
20324         $LFS migrate -m $MDTIDX $migrate_dir ||
20325                 error "fails on migrating remote dir to MDT0"
20326
20327         echo "migrate back to MDT0, checking.."
20328         for file in $(find $migrate_dir); do
20329                 mdt_index=$($LFS getstripe -m $file)
20330                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20331                         error "$file is not on MDT${MDTIDX}"
20332         done
20333
20334         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20335         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20336                 error " expect $old_dir_flag get $new_dir_flag"
20337
20338         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20339         [ "$old_file_flag" = "$new_file_flag" ] ||
20340                 error " expect $old_file_flag get $new_file_flag"
20341
20342         local new_dir_mode=$(stat -c%f $migrate_dir)
20343         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20344                 error "expect mode $old_dir_mode get $new_dir_mode"
20345
20346         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20347         [ "$old_file_mode" = "$new_file_mode" ] ||
20348                 error "expect mode $old_file_mode get $new_file_mode"
20349
20350         diff /etc/passwd ${migrate_dir}/$tfile ||
20351                 error "$tfile different after migration"
20352
20353         diff /etc/passwd ${other_dir}/luna ||
20354                 error "luna different after migration"
20355
20356         diff /etc/passwd ${migrate_dir}/sofia ||
20357                 error "sofia different after migration"
20358
20359         diff /etc/passwd ${other_dir}/zachary ||
20360                 error "zachary different after migration"
20361
20362         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20363                 error "${tfile}_ln different after migration"
20364
20365         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20366                 error "${tfile}_ln_other different after migration"
20367
20368         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20369         [ $stripe_count = 2 ] ||
20370                 error "dir strpe_count $d != 2 after migration."
20371
20372         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20373         [ $stripe_count = 2 ] ||
20374                 error "file strpe_count $d != 2 after migration."
20375
20376         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20377 }
20378 run_test 230b "migrate directory"
20379
20380 test_230c() {
20381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20383         remote_mds_nodsh && skip "remote MDS with nodsh"
20384         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20385                 skip "Need MDS version at least 2.11.52"
20386
20387         local MDTIDX=1
20388         local total=3
20389         local mdt_index
20390         local file
20391         local migrate_dir=$DIR/$tdir/migrate_dir
20392
20393         #If migrating directory fails in the middle, all entries of
20394         #the directory is still accessiable.
20395         test_mkdir $DIR/$tdir
20396         test_mkdir -i0 -c1 $migrate_dir
20397         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20398         stat $migrate_dir
20399         createmany -o $migrate_dir/f $total ||
20400                 error "create files under ${migrate_dir} failed"
20401
20402         # fail after migrating top dir, and this will fail only once, so the
20403         # first sub file migration will fail (currently f3), others succeed.
20404         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20405         do_facet mds1 lctl set_param fail_loc=0x1801
20406         local t=$(ls $migrate_dir | wc -l)
20407         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20408                 error "migrate should fail"
20409         local u=$(ls $migrate_dir | wc -l)
20410         [ "$u" == "$t" ] || error "$u != $t during migration"
20411
20412         # add new dir/file should succeed
20413         mkdir $migrate_dir/dir ||
20414                 error "mkdir failed under migrating directory"
20415         touch $migrate_dir/file ||
20416                 error "create file failed under migrating directory"
20417
20418         # add file with existing name should fail
20419         for file in $migrate_dir/f*; do
20420                 stat $file > /dev/null || error "stat $file failed"
20421                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20422                         error "open(O_CREAT|O_EXCL) $file should fail"
20423                 $MULTIOP $file m && error "create $file should fail"
20424                 touch $DIR/$tdir/remote_dir/$tfile ||
20425                         error "touch $tfile failed"
20426                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20427                         error "link $file should fail"
20428                 mdt_index=$($LFS getstripe -m $file)
20429                 if [ $mdt_index == 0 ]; then
20430                         # file failed to migrate is not allowed to rename to
20431                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20432                                 error "rename to $file should fail"
20433                 else
20434                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20435                                 error "rename to $file failed"
20436                 fi
20437                 echo hello >> $file || error "write $file failed"
20438         done
20439
20440         # resume migration with different options should fail
20441         $LFS migrate -m 0 $migrate_dir &&
20442                 error "migrate -m 0 $migrate_dir should fail"
20443
20444         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20445                 error "migrate -c 2 $migrate_dir should fail"
20446
20447         # resume migration should succeed
20448         $LFS migrate -m $MDTIDX $migrate_dir ||
20449                 error "migrate $migrate_dir failed"
20450
20451         echo "Finish migration, then checking.."
20452         for file in $(find $migrate_dir); do
20453                 mdt_index=$($LFS getstripe -m $file)
20454                 [ $mdt_index == $MDTIDX ] ||
20455                         error "$file is not on MDT${MDTIDX}"
20456         done
20457
20458         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20459 }
20460 run_test 230c "check directory accessiblity if migration failed"
20461
20462 test_230d() {
20463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20465         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20466                 skip "Need MDS version at least 2.11.52"
20467         # LU-11235
20468         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20469
20470         local migrate_dir=$DIR/$tdir/migrate_dir
20471         local old_index
20472         local new_index
20473         local old_count
20474         local new_count
20475         local new_hash
20476         local mdt_index
20477         local i
20478         local j
20479
20480         old_index=$((RANDOM % MDSCOUNT))
20481         old_count=$((MDSCOUNT - old_index))
20482         new_index=$((RANDOM % MDSCOUNT))
20483         new_count=$((MDSCOUNT - new_index))
20484         new_hash=1 # for all_char
20485
20486         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20487         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20488
20489         test_mkdir $DIR/$tdir
20490         test_mkdir -i $old_index -c $old_count $migrate_dir
20491
20492         for ((i=0; i<100; i++)); do
20493                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20494                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20495                         error "create files under remote dir failed $i"
20496         done
20497
20498         echo -n "Migrate from MDT$old_index "
20499         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20500         echo -n "to MDT$new_index"
20501         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20502         echo
20503
20504         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20505         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20506                 error "migrate remote dir error"
20507
20508         echo "Finish migration, then checking.."
20509         for file in $(find $migrate_dir -maxdepth 1); do
20510                 mdt_index=$($LFS getstripe -m $file)
20511                 if [ $mdt_index -lt $new_index ] ||
20512                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20513                         error "$file is on MDT$mdt_index"
20514                 fi
20515         done
20516
20517         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20518 }
20519 run_test 230d "check migrate big directory"
20520
20521 test_230e() {
20522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20524         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20525                 skip "Need MDS version at least 2.11.52"
20526
20527         local i
20528         local j
20529         local a_fid
20530         local b_fid
20531
20532         mkdir_on_mdt0 $DIR/$tdir
20533         mkdir $DIR/$tdir/migrate_dir
20534         mkdir $DIR/$tdir/other_dir
20535         touch $DIR/$tdir/migrate_dir/a
20536         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20537         ls $DIR/$tdir/other_dir
20538
20539         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20540                 error "migrate dir fails"
20541
20542         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20543         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20544
20545         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20546         [ $mdt_index == 0 ] || error "a is not on MDT0"
20547
20548         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20549                 error "migrate dir fails"
20550
20551         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20552         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20553
20554         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20555         [ $mdt_index == 1 ] || error "a is not on MDT1"
20556
20557         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20558         [ $mdt_index == 1 ] || error "b is not on MDT1"
20559
20560         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20561         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20562
20563         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20564
20565         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20566 }
20567 run_test 230e "migrate mulitple local link files"
20568
20569 test_230f() {
20570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20572         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20573                 skip "Need MDS version at least 2.11.52"
20574
20575         local a_fid
20576         local ln_fid
20577
20578         mkdir -p $DIR/$tdir
20579         mkdir $DIR/$tdir/migrate_dir
20580         $LFS mkdir -i1 $DIR/$tdir/other_dir
20581         touch $DIR/$tdir/migrate_dir/a
20582         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20583         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20584         ls $DIR/$tdir/other_dir
20585
20586         # a should be migrated to MDT1, since no other links on MDT0
20587         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20588                 error "#1 migrate dir fails"
20589         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20590         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20591         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20592         [ $mdt_index == 1 ] || error "a is not on MDT1"
20593
20594         # a should stay on MDT1, because it is a mulitple link file
20595         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20596                 error "#2 migrate dir fails"
20597         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20598         [ $mdt_index == 1 ] || error "a is not on MDT1"
20599
20600         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20601                 error "#3 migrate dir fails"
20602
20603         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20604         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20605         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20606
20607         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20608         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20609
20610         # a should be migrated to MDT0, since no other links on MDT1
20611         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20612                 error "#4 migrate dir fails"
20613         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20614         [ $mdt_index == 0 ] || error "a is not on MDT0"
20615
20616         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20617 }
20618 run_test 230f "migrate mulitple remote link files"
20619
20620 test_230g() {
20621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20623         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20624                 skip "Need MDS version at least 2.11.52"
20625
20626         mkdir -p $DIR/$tdir/migrate_dir
20627
20628         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20629                 error "migrating dir to non-exist MDT succeeds"
20630         true
20631 }
20632 run_test 230g "migrate dir to non-exist MDT"
20633
20634 test_230h() {
20635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20636         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20637         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20638                 skip "Need MDS version at least 2.11.52"
20639
20640         local mdt_index
20641
20642         mkdir -p $DIR/$tdir/migrate_dir
20643
20644         $LFS migrate -m1 $DIR &&
20645                 error "migrating mountpoint1 should fail"
20646
20647         $LFS migrate -m1 $DIR/$tdir/.. &&
20648                 error "migrating mountpoint2 should fail"
20649
20650         # same as mv
20651         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20652                 error "migrating $tdir/migrate_dir/.. should fail"
20653
20654         true
20655 }
20656 run_test 230h "migrate .. and root"
20657
20658 test_230i() {
20659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20662                 skip "Need MDS version at least 2.11.52"
20663
20664         mkdir -p $DIR/$tdir/migrate_dir
20665
20666         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20667                 error "migration fails with a tailing slash"
20668
20669         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20670                 error "migration fails with two tailing slashes"
20671 }
20672 run_test 230i "lfs migrate -m tolerates trailing slashes"
20673
20674 test_230j() {
20675         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20676         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20677                 skip "Need MDS version at least 2.11.52"
20678
20679         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20680         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20681                 error "create $tfile failed"
20682         cat /etc/passwd > $DIR/$tdir/$tfile
20683
20684         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20685
20686         cmp /etc/passwd $DIR/$tdir/$tfile ||
20687                 error "DoM file mismatch after migration"
20688 }
20689 run_test 230j "DoM file data not changed after dir migration"
20690
20691 test_230k() {
20692         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20693         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20694                 skip "Need MDS version at least 2.11.56"
20695
20696         local total=20
20697         local files_on_starting_mdt=0
20698
20699         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20700         $LFS getdirstripe $DIR/$tdir
20701         for i in $(seq $total); do
20702                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20703                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20704                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20705         done
20706
20707         echo "$files_on_starting_mdt files on MDT0"
20708
20709         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20710         $LFS getdirstripe $DIR/$tdir
20711
20712         files_on_starting_mdt=0
20713         for i in $(seq $total); do
20714                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20715                         error "file $tfile.$i mismatch after migration"
20716                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20717                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20718         done
20719
20720         echo "$files_on_starting_mdt files on MDT1 after migration"
20721         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20722
20723         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20724         $LFS getdirstripe $DIR/$tdir
20725
20726         files_on_starting_mdt=0
20727         for i in $(seq $total); do
20728                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20729                         error "file $tfile.$i mismatch after 2nd migration"
20730                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20731                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20732         done
20733
20734         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20735         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20736
20737         true
20738 }
20739 run_test 230k "file data not changed after dir migration"
20740
20741 test_230l() {
20742         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20743         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20744                 skip "Need MDS version at least 2.11.56"
20745
20746         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20747         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20748                 error "create files under remote dir failed $i"
20749         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20750 }
20751 run_test 230l "readdir between MDTs won't crash"
20752
20753 test_230m() {
20754         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20755         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20756                 skip "Need MDS version at least 2.11.56"
20757
20758         local MDTIDX=1
20759         local mig_dir=$DIR/$tdir/migrate_dir
20760         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20761         local shortstr="b"
20762         local val
20763
20764         echo "Creating files and dirs with xattrs"
20765         test_mkdir $DIR/$tdir
20766         test_mkdir -i0 -c1 $mig_dir
20767         mkdir $mig_dir/dir
20768         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20769                 error "cannot set xattr attr1 on dir"
20770         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20771                 error "cannot set xattr attr2 on dir"
20772         touch $mig_dir/dir/f0
20773         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20774                 error "cannot set xattr attr1 on file"
20775         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20776                 error "cannot set xattr attr2 on file"
20777         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20778         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20779         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20780         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20781         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20782         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20783         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20784         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20785         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20786
20787         echo "Migrating to MDT1"
20788         $LFS migrate -m $MDTIDX $mig_dir ||
20789                 error "fails on migrating dir to MDT1"
20790
20791         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20792         echo "Checking xattrs"
20793         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20794         [ "$val" = $longstr ] ||
20795                 error "expecting xattr1 $longstr on dir, found $val"
20796         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20797         [ "$val" = $shortstr ] ||
20798                 error "expecting xattr2 $shortstr on dir, found $val"
20799         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20800         [ "$val" = $longstr ] ||
20801                 error "expecting xattr1 $longstr on file, found $val"
20802         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20803         [ "$val" = $shortstr ] ||
20804                 error "expecting xattr2 $shortstr on file, found $val"
20805 }
20806 run_test 230m "xattrs not changed after dir migration"
20807
20808 test_230n() {
20809         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20810         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20811                 skip "Need MDS version at least 2.13.53"
20812
20813         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20814         cat /etc/hosts > $DIR/$tdir/$tfile
20815         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20816         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20817
20818         cmp /etc/hosts $DIR/$tdir/$tfile ||
20819                 error "File data mismatch after migration"
20820 }
20821 run_test 230n "Dir migration with mirrored file"
20822
20823 test_230o() {
20824         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20825         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20826                 skip "Need MDS version at least 2.13.52"
20827
20828         local mdts=$(comma_list $(mdts_nodes))
20829         local timeout=100
20830         local restripe_status
20831         local delta
20832         local i
20833
20834         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20835
20836         # in case "crush" hash type is not set
20837         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20838
20839         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20840                            mdt.*MDT0000.enable_dir_restripe)
20841         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20842         stack_trap "do_nodes $mdts $LCTL set_param \
20843                     mdt.*.enable_dir_restripe=$restripe_status"
20844
20845         mkdir $DIR/$tdir
20846         createmany -m $DIR/$tdir/f 100 ||
20847                 error "create files under remote dir failed $i"
20848         createmany -d $DIR/$tdir/d 100 ||
20849                 error "create dirs under remote dir failed $i"
20850
20851         for i in $(seq 2 $MDSCOUNT); do
20852                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20853                 $LFS setdirstripe -c $i $DIR/$tdir ||
20854                         error "split -c $i $tdir failed"
20855                 wait_update $HOSTNAME \
20856                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20857                         error "dir split not finished"
20858                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20859                         awk '/migrate/ {sum += $2} END { print sum }')
20860                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20861                 # delta is around total_files/stripe_count
20862                 (( $delta < 200 / (i - 1) + 4 )) ||
20863                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20864         done
20865 }
20866 run_test 230o "dir split"
20867
20868 test_230p() {
20869         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20870         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20871                 skip "Need MDS version at least 2.13.52"
20872
20873         local mdts=$(comma_list $(mdts_nodes))
20874         local timeout=100
20875         local restripe_status
20876         local delta
20877         local c
20878
20879         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20880
20881         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20882
20883         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20884                            mdt.*MDT0000.enable_dir_restripe)
20885         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20886         stack_trap "do_nodes $mdts $LCTL set_param \
20887                     mdt.*.enable_dir_restripe=$restripe_status"
20888
20889         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20890         createmany -m $DIR/$tdir/f 100 ||
20891                 error "create files under remote dir failed"
20892         createmany -d $DIR/$tdir/d 100 ||
20893                 error "create dirs under remote dir failed"
20894
20895         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20896                 local mdt_hash="crush"
20897
20898                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20899                 $LFS setdirstripe -c $c $DIR/$tdir ||
20900                         error "split -c $c $tdir failed"
20901                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20902                         mdt_hash="$mdt_hash,fixed"
20903                 elif [ $c -eq 1 ]; then
20904                         mdt_hash="none"
20905                 fi
20906                 wait_update $HOSTNAME \
20907                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20908                         error "dir merge not finished"
20909                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20910                         awk '/migrate/ {sum += $2} END { print sum }')
20911                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20912                 # delta is around total_files/stripe_count
20913                 (( delta < 200 / c + 4 )) ||
20914                         error "$delta files migrated >= $((200 / c + 4))"
20915         done
20916 }
20917 run_test 230p "dir merge"
20918
20919 test_230q() {
20920         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20921         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20922                 skip "Need MDS version at least 2.13.52"
20923
20924         local mdts=$(comma_list $(mdts_nodes))
20925         local saved_threshold=$(do_facet mds1 \
20926                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20927         local saved_delta=$(do_facet mds1 \
20928                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20929         local threshold=100
20930         local delta=2
20931         local total=0
20932         local stripe_count=0
20933         local stripe_index
20934         local nr_files
20935         local create
20936
20937         # test with fewer files on ZFS
20938         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20939
20940         stack_trap "do_nodes $mdts $LCTL set_param \
20941                     mdt.*.dir_split_count=$saved_threshold"
20942         stack_trap "do_nodes $mdts $LCTL set_param \
20943                     mdt.*.dir_split_delta=$saved_delta"
20944         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20945         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20946         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20947         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20948         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20949         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20950
20951         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20952         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20953
20954         create=$((threshold * 3 / 2))
20955         while [ $stripe_count -lt $MDSCOUNT ]; do
20956                 createmany -m $DIR/$tdir/f $total $create ||
20957                         error "create sub files failed"
20958                 stat $DIR/$tdir > /dev/null
20959                 total=$((total + create))
20960                 stripe_count=$((stripe_count + delta))
20961                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20962
20963                 wait_update $HOSTNAME \
20964                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20965                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20966
20967                 wait_update $HOSTNAME \
20968                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20969                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20970
20971                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20972                 echo "$nr_files/$total files on MDT$stripe_index after split"
20973                 # allow 10% margin of imbalance with crush hash
20974                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20975                         error "$nr_files files on MDT$stripe_index after split"
20976
20977                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20978                 [ $nr_files -eq $total ] ||
20979                         error "total sub files $nr_files != $total"
20980         done
20981
20982         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20983
20984         echo "fixed layout directory won't auto split"
20985         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20986         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20987                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20988         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20989                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20990 }
20991 run_test 230q "dir auto split"
20992
20993 test_230r() {
20994         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20995         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20996         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20997                 skip "Need MDS version at least 2.13.54"
20998
20999         # maximum amount of local locks:
21000         # parent striped dir - 2 locks
21001         # new stripe in parent to migrate to - 1 lock
21002         # source and target - 2 locks
21003         # Total 5 locks for regular file
21004         mkdir -p $DIR/$tdir
21005         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21006         touch $DIR/$tdir/dir1/eee
21007
21008         # create 4 hardlink for 4 more locks
21009         # Total: 9 locks > RS_MAX_LOCKS (8)
21010         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21011         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21012         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21013         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21014         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21015         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21016         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21017         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21018
21019         cancel_lru_locks mdc
21020
21021         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21022                 error "migrate dir fails"
21023
21024         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21025 }
21026 run_test 230r "migrate with too many local locks"
21027
21028 test_230s() {
21029         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21030                 skip "Need MDS version at least 2.14.52"
21031
21032         local mdts=$(comma_list $(mdts_nodes))
21033         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21034                                 mdt.*MDT0000.enable_dir_restripe)
21035
21036         stack_trap "do_nodes $mdts $LCTL set_param \
21037                     mdt.*.enable_dir_restripe=$restripe_status"
21038
21039         local st
21040         for st in 0 1; do
21041                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21042                 test_mkdir $DIR/$tdir
21043                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21044                         error "$LFS mkdir should return EEXIST if target exists"
21045                 rmdir $DIR/$tdir
21046         done
21047 }
21048 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21049
21050 test_230t()
21051 {
21052         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21053         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21054                 skip "Need MDS version at least 2.14.50"
21055
21056         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21057         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21058         $LFS project -p 1 -s $DIR/$tdir ||
21059                 error "set $tdir project id failed"
21060         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21061                 error "set subdir project id failed"
21062         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21063 }
21064 run_test 230t "migrate directory with project ID set"
21065
21066 test_230u()
21067 {
21068         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21069         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21070                 skip "Need MDS version at least 2.14.53"
21071
21072         local count
21073
21074         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21075         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21076         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21077         for i in $(seq 0 $((MDSCOUNT - 1))); do
21078                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21079                 echo "$count dirs migrated to MDT$i"
21080         done
21081         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21082         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21083 }
21084 run_test 230u "migrate directory by QOS"
21085
21086 test_230v()
21087 {
21088         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21089         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21090                 skip "Need MDS version at least 2.14.53"
21091
21092         local count
21093
21094         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21095         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21096         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21097         for i in $(seq 0 $((MDSCOUNT - 1))); do
21098                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21099                 echo "$count subdirs migrated to MDT$i"
21100                 (( i == 3 )) && (( count > 0 )) &&
21101                         error "subdir shouldn't be migrated to MDT3"
21102         done
21103         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21104         (( count == 3 )) || error "dirs migrated to $count MDTs"
21105 }
21106 run_test 230v "subdir migrated to the MDT where its parent is located"
21107
21108 test_230w() {
21109         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21110         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21111                 skip "Need MDS version at least 2.15.0"
21112
21113         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21114         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21115         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21116
21117         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21118                 error "migrate failed"
21119
21120         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21121                 error "$tdir stripe count mismatch"
21122
21123         for i in $(seq 0 9); do
21124                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21125                         error "d$i is striped"
21126         done
21127 }
21128 run_test 230w "non-recursive mode dir migration"
21129
21130 test_230x() {
21131         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21132         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21133                 skip "Need MDS version at least 2.15.0"
21134
21135         mkdir -p $DIR/$tdir || error "mkdir failed"
21136         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21137
21138         local mdt_name=$(mdtname_from_index 0)
21139         local low=$(do_facet mds2 $LCTL get_param -n \
21140                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21141         local high=$(do_facet mds2 $LCTL get_param -n \
21142                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21143         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21144         local maxage=$(do_facet mds2 $LCTL get_param -n \
21145                 osp.*$mdt_name-osp-MDT0001.maxage)
21146
21147         stack_trap "do_facet mds2 $LCTL set_param -n \
21148                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21149                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21150         stack_trap "do_facet mds2 $LCTL set_param -n \
21151                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21152
21153         do_facet mds2 $LCTL set_param -n \
21154                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21155         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21156         sleep 4
21157         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21158                 error "migrate $tdir should fail"
21159
21160         do_facet mds2 $LCTL set_param -n \
21161                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21162         do_facet mds2 $LCTL set_param -n \
21163                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21164         sleep 4
21165         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21166                 error "migrate failed"
21167         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21168                 error "$tdir stripe count mismatch"
21169 }
21170 run_test 230x "dir migration check space"
21171
21172 test_231a()
21173 {
21174         # For simplicity this test assumes that max_pages_per_rpc
21175         # is the same across all OSCs
21176         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21177         local bulk_size=$((max_pages * PAGE_SIZE))
21178         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21179                                        head -n 1)
21180
21181         mkdir -p $DIR/$tdir
21182         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21183                 error "failed to set stripe with -S ${brw_size}M option"
21184
21185         # clear the OSC stats
21186         $LCTL set_param osc.*.stats=0 &>/dev/null
21187         stop_writeback
21188
21189         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21190         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21191                 oflag=direct &>/dev/null || error "dd failed"
21192
21193         sync; sleep 1; sync # just to be safe
21194         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21195         if [ x$nrpcs != "x1" ]; then
21196                 $LCTL get_param osc.*.stats
21197                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21198         fi
21199
21200         start_writeback
21201         # Drop the OSC cache, otherwise we will read from it
21202         cancel_lru_locks osc
21203
21204         # clear the OSC stats
21205         $LCTL set_param osc.*.stats=0 &>/dev/null
21206
21207         # Client reads $bulk_size.
21208         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21209                 iflag=direct &>/dev/null || error "dd failed"
21210
21211         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21212         if [ x$nrpcs != "x1" ]; then
21213                 $LCTL get_param osc.*.stats
21214                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21215         fi
21216 }
21217 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21218
21219 test_231b() {
21220         mkdir -p $DIR/$tdir
21221         local i
21222         for i in {0..1023}; do
21223                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21224                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21225                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21226         done
21227         sync
21228 }
21229 run_test 231b "must not assert on fully utilized OST request buffer"
21230
21231 test_232a() {
21232         mkdir -p $DIR/$tdir
21233         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21234
21235         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21236         do_facet ost1 $LCTL set_param fail_loc=0x31c
21237
21238         # ignore dd failure
21239         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21240
21241         do_facet ost1 $LCTL set_param fail_loc=0
21242         umount_client $MOUNT || error "umount failed"
21243         mount_client $MOUNT || error "mount failed"
21244         stop ost1 || error "cannot stop ost1"
21245         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21246 }
21247 run_test 232a "failed lock should not block umount"
21248
21249 test_232b() {
21250         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21251                 skip "Need MDS version at least 2.10.58"
21252
21253         mkdir -p $DIR/$tdir
21254         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21255         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21256         sync
21257         cancel_lru_locks osc
21258
21259         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21260         do_facet ost1 $LCTL set_param fail_loc=0x31c
21261
21262         # ignore failure
21263         $LFS data_version $DIR/$tdir/$tfile || true
21264
21265         do_facet ost1 $LCTL set_param fail_loc=0
21266         umount_client $MOUNT || error "umount failed"
21267         mount_client $MOUNT || error "mount failed"
21268         stop ost1 || error "cannot stop ost1"
21269         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21270 }
21271 run_test 232b "failed data version lock should not block umount"
21272
21273 test_233a() {
21274         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21275                 skip "Need MDS version at least 2.3.64"
21276         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21277
21278         local fid=$($LFS path2fid $MOUNT)
21279
21280         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21281                 error "cannot access $MOUNT using its FID '$fid'"
21282 }
21283 run_test 233a "checking that OBF of the FS root succeeds"
21284
21285 test_233b() {
21286         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21287                 skip "Need MDS version at least 2.5.90"
21288         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21289
21290         local fid=$($LFS path2fid $MOUNT/.lustre)
21291
21292         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21293                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21294
21295         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21296         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21297                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21298 }
21299 run_test 233b "checking that OBF of the FS .lustre succeeds"
21300
21301 test_234() {
21302         local p="$TMP/sanityN-$TESTNAME.parameters"
21303         save_lustre_params client "llite.*.xattr_cache" > $p
21304         lctl set_param llite.*.xattr_cache 1 ||
21305                 skip_env "xattr cache is not supported"
21306
21307         mkdir -p $DIR/$tdir || error "mkdir failed"
21308         touch $DIR/$tdir/$tfile || error "touch failed"
21309         # OBD_FAIL_LLITE_XATTR_ENOMEM
21310         $LCTL set_param fail_loc=0x1405
21311         getfattr -n user.attr $DIR/$tdir/$tfile &&
21312                 error "getfattr should have failed with ENOMEM"
21313         $LCTL set_param fail_loc=0x0
21314         rm -rf $DIR/$tdir
21315
21316         restore_lustre_params < $p
21317         rm -f $p
21318 }
21319 run_test 234 "xattr cache should not crash on ENOMEM"
21320
21321 test_235() {
21322         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21323                 skip "Need MDS version at least 2.4.52"
21324
21325         flock_deadlock $DIR/$tfile
21326         local RC=$?
21327         case $RC in
21328                 0)
21329                 ;;
21330                 124) error "process hangs on a deadlock"
21331                 ;;
21332                 *) error "error executing flock_deadlock $DIR/$tfile"
21333                 ;;
21334         esac
21335 }
21336 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21337
21338 #LU-2935
21339 test_236() {
21340         check_swap_layouts_support
21341
21342         local ref1=/etc/passwd
21343         local ref2=/etc/group
21344         local file1=$DIR/$tdir/f1
21345         local file2=$DIR/$tdir/f2
21346
21347         test_mkdir -c1 $DIR/$tdir
21348         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21349         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21350         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21351         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21352         local fd=$(free_fd)
21353         local cmd="exec $fd<>$file2"
21354         eval $cmd
21355         rm $file2
21356         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21357                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21358         cmd="exec $fd>&-"
21359         eval $cmd
21360         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21361
21362         #cleanup
21363         rm -rf $DIR/$tdir
21364 }
21365 run_test 236 "Layout swap on open unlinked file"
21366
21367 # LU-4659 linkea consistency
21368 test_238() {
21369         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21370                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21371                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21372                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21373
21374         touch $DIR/$tfile
21375         ln $DIR/$tfile $DIR/$tfile.lnk
21376         touch $DIR/$tfile.new
21377         mv $DIR/$tfile.new $DIR/$tfile
21378         local fid1=$($LFS path2fid $DIR/$tfile)
21379         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21380         local path1=$($LFS fid2path $FSNAME "$fid1")
21381         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21382         local path2=$($LFS fid2path $FSNAME "$fid2")
21383         [ $tfile.lnk == $path2 ] ||
21384                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21385         rm -f $DIR/$tfile*
21386 }
21387 run_test 238 "Verify linkea consistency"
21388
21389 test_239A() { # was test_239
21390         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21391                 skip "Need MDS version at least 2.5.60"
21392
21393         local list=$(comma_list $(mdts_nodes))
21394
21395         mkdir -p $DIR/$tdir
21396         createmany -o $DIR/$tdir/f- 5000
21397         unlinkmany $DIR/$tdir/f- 5000
21398         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21399                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21400         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21401                         osp.*MDT*.sync_in_flight" | calc_sum)
21402         [ "$changes" -eq 0 ] || error "$changes not synced"
21403 }
21404 run_test 239A "osp_sync test"
21405
21406 test_239a() { #LU-5297
21407         remote_mds_nodsh && skip "remote MDS with nodsh"
21408
21409         touch $DIR/$tfile
21410         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21411         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21412         chgrp $RUNAS_GID $DIR/$tfile
21413         wait_delete_completed
21414 }
21415 run_test 239a "process invalid osp sync record correctly"
21416
21417 test_239b() { #LU-5297
21418         remote_mds_nodsh && skip "remote MDS with nodsh"
21419
21420         touch $DIR/$tfile1
21421         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21422         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21423         chgrp $RUNAS_GID $DIR/$tfile1
21424         wait_delete_completed
21425         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21426         touch $DIR/$tfile2
21427         chgrp $RUNAS_GID $DIR/$tfile2
21428         wait_delete_completed
21429 }
21430 run_test 239b "process osp sync record with ENOMEM error correctly"
21431
21432 test_240() {
21433         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21434         remote_mds_nodsh && skip "remote MDS with nodsh"
21435
21436         mkdir -p $DIR/$tdir
21437
21438         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21439                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21440         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21441                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21442
21443         umount_client $MOUNT || error "umount failed"
21444         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21445         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21446         mount_client $MOUNT || error "failed to mount client"
21447
21448         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21449         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21450 }
21451 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21452
21453 test_241_bio() {
21454         local count=$1
21455         local bsize=$2
21456
21457         for LOOP in $(seq $count); do
21458                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21459                 cancel_lru_locks $OSC || true
21460         done
21461 }
21462
21463 test_241_dio() {
21464         local count=$1
21465         local bsize=$2
21466
21467         for LOOP in $(seq $1); do
21468                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21469                         2>/dev/null
21470         done
21471 }
21472
21473 test_241a() { # was test_241
21474         local bsize=$PAGE_SIZE
21475
21476         (( bsize < 40960 )) && bsize=40960
21477         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21478         ls -la $DIR/$tfile
21479         cancel_lru_locks $OSC
21480         test_241_bio 1000 $bsize &
21481         PID=$!
21482         test_241_dio 1000 $bsize
21483         wait $PID
21484 }
21485 run_test 241a "bio vs dio"
21486
21487 test_241b() {
21488         local bsize=$PAGE_SIZE
21489
21490         (( bsize < 40960 )) && bsize=40960
21491         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21492         ls -la $DIR/$tfile
21493         test_241_dio 1000 $bsize &
21494         PID=$!
21495         test_241_dio 1000 $bsize
21496         wait $PID
21497 }
21498 run_test 241b "dio vs dio"
21499
21500 test_242() {
21501         remote_mds_nodsh && skip "remote MDS with nodsh"
21502
21503         mkdir_on_mdt0 $DIR/$tdir
21504         touch $DIR/$tdir/$tfile
21505
21506         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21507         do_facet mds1 lctl set_param fail_loc=0x105
21508         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21509
21510         do_facet mds1 lctl set_param fail_loc=0
21511         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21512 }
21513 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21514
21515 test_243()
21516 {
21517         test_mkdir $DIR/$tdir
21518         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21519 }
21520 run_test 243 "various group lock tests"
21521
21522 test_244a()
21523 {
21524         test_mkdir $DIR/$tdir
21525         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21526         sendfile_grouplock $DIR/$tdir/$tfile || \
21527                 error "sendfile+grouplock failed"
21528         rm -rf $DIR/$tdir
21529 }
21530 run_test 244a "sendfile with group lock tests"
21531
21532 test_244b()
21533 {
21534         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21535
21536         local threads=50
21537         local size=$((1024*1024))
21538
21539         test_mkdir $DIR/$tdir
21540         for i in $(seq 1 $threads); do
21541                 local file=$DIR/$tdir/file_$((i / 10))
21542                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21543                 local pids[$i]=$!
21544         done
21545         for i in $(seq 1 $threads); do
21546                 wait ${pids[$i]}
21547         done
21548 }
21549 run_test 244b "multi-threaded write with group lock"
21550
21551 test_245a() {
21552         local flagname="multi_mod_rpcs"
21553         local connect_data_name="max_mod_rpcs"
21554         local out
21555
21556         # check if multiple modify RPCs flag is set
21557         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21558                 grep "connect_flags:")
21559         echo "$out"
21560
21561         echo "$out" | grep -qw $flagname
21562         if [ $? -ne 0 ]; then
21563                 echo "connect flag $flagname is not set"
21564                 return
21565         fi
21566
21567         # check if multiple modify RPCs data is set
21568         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21569         echo "$out"
21570
21571         echo "$out" | grep -qw $connect_data_name ||
21572                 error "import should have connect data $connect_data_name"
21573 }
21574 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21575
21576 test_245b() {
21577         local flagname="multi_mod_rpcs"
21578         local connect_data_name="max_mod_rpcs"
21579         local out
21580
21581         remote_mds_nodsh && skip "remote MDS with nodsh"
21582         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21583
21584         # check if multiple modify RPCs flag is set
21585         out=$(do_facet mds1 \
21586               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21587               grep "connect_flags:")
21588         echo "$out"
21589
21590         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21591
21592         # check if multiple modify RPCs data is set
21593         out=$(do_facet mds1 \
21594               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21595
21596         [[ "$out" =~ $connect_data_name ]] ||
21597                 {
21598                         echo "$out"
21599                         error "missing connect data $connect_data_name"
21600                 }
21601 }
21602 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21603
21604 cleanup_247() {
21605         local submount=$1
21606
21607         trap 0
21608         umount_client $submount
21609         rmdir $submount
21610 }
21611
21612 test_247a() {
21613         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21614                 grep -q subtree ||
21615                 skip_env "Fileset feature is not supported"
21616
21617         local submount=${MOUNT}_$tdir
21618
21619         mkdir $MOUNT/$tdir
21620         mkdir -p $submount || error "mkdir $submount failed"
21621         FILESET="$FILESET/$tdir" mount_client $submount ||
21622                 error "mount $submount failed"
21623         trap "cleanup_247 $submount" EXIT
21624         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21625         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21626                 error "read $MOUNT/$tdir/$tfile failed"
21627         cleanup_247 $submount
21628 }
21629 run_test 247a "mount subdir as fileset"
21630
21631 test_247b() {
21632         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21633                 skip_env "Fileset feature is not supported"
21634
21635         local submount=${MOUNT}_$tdir
21636
21637         rm -rf $MOUNT/$tdir
21638         mkdir -p $submount || error "mkdir $submount failed"
21639         SKIP_FILESET=1
21640         FILESET="$FILESET/$tdir" mount_client $submount &&
21641                 error "mount $submount should fail"
21642         rmdir $submount
21643 }
21644 run_test 247b "mount subdir that dose not exist"
21645
21646 test_247c() {
21647         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21648                 skip_env "Fileset feature is not supported"
21649
21650         local submount=${MOUNT}_$tdir
21651
21652         mkdir -p $MOUNT/$tdir/dir1
21653         mkdir -p $submount || error "mkdir $submount failed"
21654         trap "cleanup_247 $submount" EXIT
21655         FILESET="$FILESET/$tdir" mount_client $submount ||
21656                 error "mount $submount failed"
21657         local fid=$($LFS path2fid $MOUNT/)
21658         $LFS fid2path $submount $fid && error "fid2path should fail"
21659         cleanup_247 $submount
21660 }
21661 run_test 247c "running fid2path outside subdirectory root"
21662
21663 test_247d() {
21664         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21665                 skip "Fileset feature is not supported"
21666
21667         local submount=${MOUNT}_$tdir
21668
21669         mkdir -p $MOUNT/$tdir/dir1
21670         mkdir -p $submount || error "mkdir $submount failed"
21671         FILESET="$FILESET/$tdir" mount_client $submount ||
21672                 error "mount $submount failed"
21673         trap "cleanup_247 $submount" EXIT
21674
21675         local td=$submount/dir1
21676         local fid=$($LFS path2fid $td)
21677         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21678
21679         # check that we get the same pathname back
21680         local rootpath
21681         local found
21682         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21683                 echo "$rootpath $fid"
21684                 found=$($LFS fid2path $rootpath "$fid")
21685                 [ -n "$found" ] || error "fid2path should succeed"
21686                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21687         done
21688         # check wrong root path format
21689         rootpath=$submount"_wrong"
21690         found=$($LFS fid2path $rootpath "$fid")
21691         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21692
21693         cleanup_247 $submount
21694 }
21695 run_test 247d "running fid2path inside subdirectory root"
21696
21697 # LU-8037
21698 test_247e() {
21699         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21700                 grep -q subtree ||
21701                 skip "Fileset feature is not supported"
21702
21703         local submount=${MOUNT}_$tdir
21704
21705         mkdir $MOUNT/$tdir
21706         mkdir -p $submount || error "mkdir $submount failed"
21707         FILESET="$FILESET/.." mount_client $submount &&
21708                 error "mount $submount should fail"
21709         rmdir $submount
21710 }
21711 run_test 247e "mount .. as fileset"
21712
21713 test_247f() {
21714         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21715         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21716                 skip "Need at least version 2.13.52"
21717         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21718                 skip "Need at least version 2.14.50"
21719         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21720                 grep -q subtree ||
21721                 skip "Fileset feature is not supported"
21722
21723         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21724         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21725                 error "mkdir remote failed"
21726         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21727                 error "mkdir remote/subdir failed"
21728         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21729                 error "mkdir striped failed"
21730         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21731
21732         local submount=${MOUNT}_$tdir
21733
21734         mkdir -p $submount || error "mkdir $submount failed"
21735         stack_trap "rmdir $submount"
21736
21737         local dir
21738         local stat
21739         local fileset=$FILESET
21740         local mdts=$(comma_list $(mdts_nodes))
21741
21742         stat=$(do_facet mds1 $LCTL get_param -n \
21743                 mdt.*MDT0000.enable_remote_subdir_mount)
21744         stack_trap "do_nodes $mdts $LCTL set_param \
21745                 mdt.*.enable_remote_subdir_mount=$stat"
21746
21747         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21748         stack_trap "umount_client $submount"
21749         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21750                 error "mount remote dir $dir should fail"
21751
21752         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21753                 $tdir/striped/. ; do
21754                 FILESET="$fileset/$dir" mount_client $submount ||
21755                         error "mount $dir failed"
21756                 umount_client $submount
21757         done
21758
21759         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21760         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21761                 error "mount $tdir/remote failed"
21762 }
21763 run_test 247f "mount striped or remote directory as fileset"
21764
21765 test_247g() {
21766         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21767         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21768                 skip "Need at least version 2.14.50"
21769
21770         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21771                 error "mkdir $tdir failed"
21772         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21773
21774         local submount=${MOUNT}_$tdir
21775
21776         mkdir -p $submount || error "mkdir $submount failed"
21777         stack_trap "rmdir $submount"
21778
21779         FILESET="$fileset/$tdir" mount_client $submount ||
21780                 error "mount $dir failed"
21781         stack_trap "umount $submount"
21782
21783         local mdts=$(comma_list $(mdts_nodes))
21784
21785         local nrpcs
21786
21787         stat $submount > /dev/null
21788         cancel_lru_locks $MDC
21789         stat $submount > /dev/null
21790         stat $submount/$tfile > /dev/null
21791         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21792         stat $submount/$tfile > /dev/null
21793         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21794                 awk '/getattr/ {sum += $2} END {print sum}')
21795
21796         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21797 }
21798 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21799
21800 test_248a() {
21801         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21802         [ -z "$fast_read_sav" ] && skip "no fast read support"
21803
21804         # create a large file for fast read verification
21805         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21806
21807         # make sure the file is created correctly
21808         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21809                 { rm -f $DIR/$tfile; skip "file creation error"; }
21810
21811         echo "Test 1: verify that fast read is 4 times faster on cache read"
21812
21813         # small read with fast read enabled
21814         $LCTL set_param -n llite.*.fast_read=1
21815         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21816                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21817                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21818         # small read with fast read disabled
21819         $LCTL set_param -n llite.*.fast_read=0
21820         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21821                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21822                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21823
21824         # verify that fast read is 4 times faster for cache read
21825         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21826                 error_not_in_vm "fast read was not 4 times faster: " \
21827                            "$t_fast vs $t_slow"
21828
21829         echo "Test 2: verify the performance between big and small read"
21830         $LCTL set_param -n llite.*.fast_read=1
21831
21832         # 1k non-cache read
21833         cancel_lru_locks osc
21834         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21835                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21836                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21837
21838         # 1M non-cache read
21839         cancel_lru_locks osc
21840         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21841                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21842                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21843
21844         # verify that big IO is not 4 times faster than small IO
21845         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21846                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21847
21848         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21849         rm -f $DIR/$tfile
21850 }
21851 run_test 248a "fast read verification"
21852
21853 test_248b() {
21854         # Default short_io_bytes=16384, try both smaller and larger sizes.
21855         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21856         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21857         echo "bs=53248 count=113 normal buffered write"
21858         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21859                 error "dd of initial data file failed"
21860         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21861
21862         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21863         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21864                 error "dd with sync normal writes failed"
21865         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21866
21867         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21868         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21869                 error "dd with sync small writes failed"
21870         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21871
21872         cancel_lru_locks osc
21873
21874         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21875         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21876         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21877         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21878                 iflag=direct || error "dd with O_DIRECT small read failed"
21879         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21880         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21881                 error "compare $TMP/$tfile.1 failed"
21882
21883         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21884         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21885
21886         # just to see what the maximum tunable value is, and test parsing
21887         echo "test invalid parameter 2MB"
21888         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21889                 error "too-large short_io_bytes allowed"
21890         echo "test maximum parameter 512KB"
21891         # if we can set a larger short_io_bytes, run test regardless of version
21892         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21893                 # older clients may not allow setting it this large, that's OK
21894                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21895                         skip "Need at least client version 2.13.50"
21896                 error "medium short_io_bytes failed"
21897         fi
21898         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21899         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21900
21901         echo "test large parameter 64KB"
21902         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21903         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21904
21905         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21906         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21907                 error "dd with sync large writes failed"
21908         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21909
21910         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21911         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21912         num=$((113 * 4096 / PAGE_SIZE))
21913         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21914         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21915                 error "dd with O_DIRECT large writes failed"
21916         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21917                 error "compare $DIR/$tfile.3 failed"
21918
21919         cancel_lru_locks osc
21920
21921         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21922         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21923                 error "dd with O_DIRECT large read failed"
21924         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21925                 error "compare $TMP/$tfile.2 failed"
21926
21927         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21928         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21929                 error "dd with O_DIRECT large read failed"
21930         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21931                 error "compare $TMP/$tfile.3 failed"
21932 }
21933 run_test 248b "test short_io read and write for both small and large sizes"
21934
21935 test_249() { # LU-7890
21936         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21937                 skip "Need at least version 2.8.54"
21938
21939         rm -f $DIR/$tfile
21940         $LFS setstripe -c 1 $DIR/$tfile
21941         # Offset 2T == 4k * 512M
21942         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21943                 error "dd to 2T offset failed"
21944 }
21945 run_test 249 "Write above 2T file size"
21946
21947 test_250() {
21948         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21949          && skip "no 16TB file size limit on ZFS"
21950
21951         $LFS setstripe -c 1 $DIR/$tfile
21952         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21953         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21954         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21955         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21956                 conv=notrunc,fsync && error "append succeeded"
21957         return 0
21958 }
21959 run_test 250 "Write above 16T limit"
21960
21961 test_251() {
21962         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21963
21964         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21965         #Skip once - writing the first stripe will succeed
21966         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21967         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21968                 error "short write happened"
21969
21970         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21971         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21972                 error "short read happened"
21973
21974         rm -f $DIR/$tfile
21975 }
21976 run_test 251 "Handling short read and write correctly"
21977
21978 test_252() {
21979         remote_mds_nodsh && skip "remote MDS with nodsh"
21980         remote_ost_nodsh && skip "remote OST with nodsh"
21981         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21982                 skip_env "ldiskfs only test"
21983         fi
21984
21985         local tgt
21986         local dev
21987         local out
21988         local uuid
21989         local num
21990         local gen
21991
21992         # check lr_reader on OST0000
21993         tgt=ost1
21994         dev=$(facet_device $tgt)
21995         out=$(do_facet $tgt $LR_READER $dev)
21996         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21997         echo "$out"
21998         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21999         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22000                 error "Invalid uuid returned by $LR_READER on target $tgt"
22001         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22002
22003         # check lr_reader -c on MDT0000
22004         tgt=mds1
22005         dev=$(facet_device $tgt)
22006         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22007                 skip "$LR_READER does not support additional options"
22008         fi
22009         out=$(do_facet $tgt $LR_READER -c $dev)
22010         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22011         echo "$out"
22012         num=$(echo "$out" | grep -c "mdtlov")
22013         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22014                 error "Invalid number of mdtlov clients returned by $LR_READER"
22015         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22016
22017         # check lr_reader -cr on MDT0000
22018         out=$(do_facet $tgt $LR_READER -cr $dev)
22019         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22020         echo "$out"
22021         echo "$out" | grep -q "^reply_data:$" ||
22022                 error "$LR_READER should have returned 'reply_data' section"
22023         num=$(echo "$out" | grep -c "client_generation")
22024         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22025 }
22026 run_test 252 "check lr_reader tool"
22027
22028 test_253() {
22029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22030         remote_mds_nodsh && skip "remote MDS with nodsh"
22031         remote_mgs_nodsh && skip "remote MGS with nodsh"
22032
22033         local ostidx=0
22034         local rc=0
22035         local ost_name=$(ostname_from_index $ostidx)
22036
22037         # on the mdt's osc
22038         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22039         do_facet $SINGLEMDS $LCTL get_param -n \
22040                 osp.$mdtosc_proc1.reserved_mb_high ||
22041                 skip  "remote MDS does not support reserved_mb_high"
22042
22043         rm -rf $DIR/$tdir
22044         wait_mds_ost_sync
22045         wait_delete_completed
22046         mkdir $DIR/$tdir
22047
22048         pool_add $TESTNAME || error "Pool creation failed"
22049         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22050
22051         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22052                 error "Setstripe failed"
22053
22054         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22055
22056         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22057                     grep "watermarks")
22058         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22059
22060         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22061                         osp.$mdtosc_proc1.prealloc_status)
22062         echo "prealloc_status $oa_status"
22063
22064         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22065                 error "File creation should fail"
22066
22067         #object allocation was stopped, but we still able to append files
22068         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22069                 oflag=append || error "Append failed"
22070
22071         rm -f $DIR/$tdir/$tfile.0
22072
22073         # For this test, we want to delete the files we created to go out of
22074         # space but leave the watermark, so we remain nearly out of space
22075         ost_watermarks_enospc_delete_files $tfile $ostidx
22076
22077         wait_delete_completed
22078
22079         sleep_maxage
22080
22081         for i in $(seq 10 12); do
22082                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22083                         2>/dev/null || error "File creation failed after rm"
22084         done
22085
22086         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22087                         osp.$mdtosc_proc1.prealloc_status)
22088         echo "prealloc_status $oa_status"
22089
22090         if (( oa_status != 0 )); then
22091                 error "Object allocation still disable after rm"
22092         fi
22093 }
22094 run_test 253 "Check object allocation limit"
22095
22096 test_254() {
22097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22098         remote_mds_nodsh && skip "remote MDS with nodsh"
22099
22100         local mdt=$(facet_svc $SINGLEMDS)
22101
22102         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22103                 skip "MDS does not support changelog_size"
22104
22105         local cl_user
22106
22107         changelog_register || error "changelog_register failed"
22108
22109         changelog_clear 0 || error "changelog_clear failed"
22110
22111         local size1=$(do_facet $SINGLEMDS \
22112                       $LCTL get_param -n mdd.$mdt.changelog_size)
22113         echo "Changelog size $size1"
22114
22115         rm -rf $DIR/$tdir
22116         $LFS mkdir -i 0 $DIR/$tdir
22117         # change something
22118         mkdir -p $DIR/$tdir/pics/2008/zachy
22119         touch $DIR/$tdir/pics/2008/zachy/timestamp
22120         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22121         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22122         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22123         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22124         rm $DIR/$tdir/pics/desktop.jpg
22125
22126         local size2=$(do_facet $SINGLEMDS \
22127                       $LCTL get_param -n mdd.$mdt.changelog_size)
22128         echo "Changelog size after work $size2"
22129
22130         (( $size2 > $size1 )) ||
22131                 error "new Changelog size=$size2 less than old size=$size1"
22132 }
22133 run_test 254 "Check changelog size"
22134
22135 ladvise_no_type()
22136 {
22137         local type=$1
22138         local file=$2
22139
22140         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22141                 awk -F: '{print $2}' | grep $type > /dev/null
22142         if [ $? -ne 0 ]; then
22143                 return 0
22144         fi
22145         return 1
22146 }
22147
22148 ladvise_no_ioctl()
22149 {
22150         local file=$1
22151
22152         lfs ladvise -a willread $file > /dev/null 2>&1
22153         if [ $? -eq 0 ]; then
22154                 return 1
22155         fi
22156
22157         lfs ladvise -a willread $file 2>&1 |
22158                 grep "Inappropriate ioctl for device" > /dev/null
22159         if [ $? -eq 0 ]; then
22160                 return 0
22161         fi
22162         return 1
22163 }
22164
22165 percent() {
22166         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22167 }
22168
22169 # run a random read IO workload
22170 # usage: random_read_iops <filename> <filesize> <iosize>
22171 random_read_iops() {
22172         local file=$1
22173         local fsize=$2
22174         local iosize=${3:-4096}
22175
22176         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22177                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22178 }
22179
22180 drop_file_oss_cache() {
22181         local file="$1"
22182         local nodes="$2"
22183
22184         $LFS ladvise -a dontneed $file 2>/dev/null ||
22185                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22186 }
22187
22188 ladvise_willread_performance()
22189 {
22190         local repeat=10
22191         local average_origin=0
22192         local average_cache=0
22193         local average_ladvise=0
22194
22195         for ((i = 1; i <= $repeat; i++)); do
22196                 echo "Iter $i/$repeat: reading without willread hint"
22197                 cancel_lru_locks osc
22198                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22199                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22200                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22201                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22202
22203                 cancel_lru_locks osc
22204                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22205                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22206                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22207
22208                 cancel_lru_locks osc
22209                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22210                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22211                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22212                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22213                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22214         done
22215         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22216         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22217         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22218
22219         speedup_cache=$(percent $average_cache $average_origin)
22220         speedup_ladvise=$(percent $average_ladvise $average_origin)
22221
22222         echo "Average uncached read: $average_origin"
22223         echo "Average speedup with OSS cached read: " \
22224                 "$average_cache = +$speedup_cache%"
22225         echo "Average speedup with ladvise willread: " \
22226                 "$average_ladvise = +$speedup_ladvise%"
22227
22228         local lowest_speedup=20
22229         if (( ${average_cache%.*} < $lowest_speedup )); then
22230                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22231                      " got $average_cache%. Skipping ladvise willread check."
22232                 return 0
22233         fi
22234
22235         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22236         # it is still good to run until then to exercise 'ladvise willread'
22237         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22238                 [ "$ost1_FSTYPE" = "zfs" ] &&
22239                 echo "osd-zfs does not support dontneed or drop_caches" &&
22240                 return 0
22241
22242         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22243         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22244                 error_not_in_vm "Speedup with willread is less than " \
22245                         "$lowest_speedup%, got $average_ladvise%"
22246 }
22247
22248 test_255a() {
22249         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22250                 skip "lustre < 2.8.54 does not support ladvise "
22251         remote_ost_nodsh && skip "remote OST with nodsh"
22252
22253         stack_trap "rm -f $DIR/$tfile"
22254         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22255
22256         ladvise_no_type willread $DIR/$tfile &&
22257                 skip "willread ladvise is not supported"
22258
22259         ladvise_no_ioctl $DIR/$tfile &&
22260                 skip "ladvise ioctl is not supported"
22261
22262         local size_mb=100
22263         local size=$((size_mb * 1048576))
22264         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22265                 error "dd to $DIR/$tfile failed"
22266
22267         lfs ladvise -a willread $DIR/$tfile ||
22268                 error "Ladvise failed with no range argument"
22269
22270         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22271                 error "Ladvise failed with no -l or -e argument"
22272
22273         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22274                 error "Ladvise failed with only -e argument"
22275
22276         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22277                 error "Ladvise failed with only -l argument"
22278
22279         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22280                 error "End offset should not be smaller than start offset"
22281
22282         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22283                 error "End offset should not be equal to start offset"
22284
22285         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22286                 error "Ladvise failed with overflowing -s argument"
22287
22288         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22289                 error "Ladvise failed with overflowing -e argument"
22290
22291         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22292                 error "Ladvise failed with overflowing -l argument"
22293
22294         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22295                 error "Ladvise succeeded with conflicting -l and -e arguments"
22296
22297         echo "Synchronous ladvise should wait"
22298         local delay=4
22299 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22300         do_nodes $(comma_list $(osts_nodes)) \
22301                 $LCTL set_param fail_val=$delay fail_loc=0x237
22302
22303         local start_ts=$SECONDS
22304         lfs ladvise -a willread $DIR/$tfile ||
22305                 error "Ladvise failed with no range argument"
22306         local end_ts=$SECONDS
22307         local inteval_ts=$((end_ts - start_ts))
22308
22309         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22310                 error "Synchronous advice didn't wait reply"
22311         fi
22312
22313         echo "Asynchronous ladvise shouldn't wait"
22314         local start_ts=$SECONDS
22315         lfs ladvise -a willread -b $DIR/$tfile ||
22316                 error "Ladvise failed with no range argument"
22317         local end_ts=$SECONDS
22318         local inteval_ts=$((end_ts - start_ts))
22319
22320         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22321                 error "Asynchronous advice blocked"
22322         fi
22323
22324         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22325         ladvise_willread_performance
22326 }
22327 run_test 255a "check 'lfs ladvise -a willread'"
22328
22329 facet_meminfo() {
22330         local facet=$1
22331         local info=$2
22332
22333         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22334 }
22335
22336 test_255b() {
22337         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22338                 skip "lustre < 2.8.54 does not support ladvise "
22339         remote_ost_nodsh && skip "remote OST with nodsh"
22340
22341         stack_trap "rm -f $DIR/$tfile"
22342         lfs setstripe -c 1 -i 0 $DIR/$tfile
22343
22344         ladvise_no_type dontneed $DIR/$tfile &&
22345                 skip "dontneed ladvise is not supported"
22346
22347         ladvise_no_ioctl $DIR/$tfile &&
22348                 skip "ladvise ioctl is not supported"
22349
22350         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22351                 [ "$ost1_FSTYPE" = "zfs" ] &&
22352                 skip "zfs-osd does not support 'ladvise dontneed'"
22353
22354         local size_mb=100
22355         local size=$((size_mb * 1048576))
22356         # In order to prevent disturbance of other processes, only check 3/4
22357         # of the memory usage
22358         local kibibytes=$((size_mb * 1024 * 3 / 4))
22359
22360         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22361                 error "dd to $DIR/$tfile failed"
22362
22363         #force write to complete before dropping OST cache & checking memory
22364         sync
22365
22366         local total=$(facet_meminfo ost1 MemTotal)
22367         echo "Total memory: $total KiB"
22368
22369         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22370         local before_read=$(facet_meminfo ost1 Cached)
22371         echo "Cache used before read: $before_read KiB"
22372
22373         lfs ladvise -a willread $DIR/$tfile ||
22374                 error "Ladvise willread failed"
22375         local after_read=$(facet_meminfo ost1 Cached)
22376         echo "Cache used after read: $after_read KiB"
22377
22378         lfs ladvise -a dontneed $DIR/$tfile ||
22379                 error "Ladvise dontneed again failed"
22380         local no_read=$(facet_meminfo ost1 Cached)
22381         echo "Cache used after dontneed ladvise: $no_read KiB"
22382
22383         if [ $total -lt $((before_read + kibibytes)) ]; then
22384                 echo "Memory is too small, abort checking"
22385                 return 0
22386         fi
22387
22388         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22389                 error "Ladvise willread should use more memory" \
22390                         "than $kibibytes KiB"
22391         fi
22392
22393         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22394                 error "Ladvise dontneed should release more memory" \
22395                         "than $kibibytes KiB"
22396         fi
22397 }
22398 run_test 255b "check 'lfs ladvise -a dontneed'"
22399
22400 test_255c() {
22401         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22402                 skip "lustre < 2.10.50 does not support lockahead"
22403
22404         local ost1_imp=$(get_osc_import_name client ost1)
22405         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22406                          cut -d'.' -f2)
22407         local count
22408         local new_count
22409         local difference
22410         local i
22411         local rc
22412
22413         test_mkdir -p $DIR/$tdir
22414         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22415
22416         #test 10 returns only success/failure
22417         i=10
22418         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22419         rc=$?
22420         if [ $rc -eq 255 ]; then
22421                 error "Ladvise test${i} failed, ${rc}"
22422         fi
22423
22424         #test 11 counts lock enqueue requests, all others count new locks
22425         i=11
22426         count=$(do_facet ost1 \
22427                 $LCTL get_param -n ost.OSS.ost.stats)
22428         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22429
22430         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22431         rc=$?
22432         if [ $rc -eq 255 ]; then
22433                 error "Ladvise test${i} failed, ${rc}"
22434         fi
22435
22436         new_count=$(do_facet ost1 \
22437                 $LCTL get_param -n ost.OSS.ost.stats)
22438         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22439                    awk '{ print $2 }')
22440
22441         difference="$((new_count - count))"
22442         if [ $difference -ne $rc ]; then
22443                 error "Ladvise test${i}, bad enqueue count, returned " \
22444                       "${rc}, actual ${difference}"
22445         fi
22446
22447         for i in $(seq 12 21); do
22448                 # If we do not do this, we run the risk of having too many
22449                 # locks and starting lock cancellation while we are checking
22450                 # lock counts.
22451                 cancel_lru_locks osc
22452
22453                 count=$($LCTL get_param -n \
22454                        ldlm.namespaces.$imp_name.lock_unused_count)
22455
22456                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22457                 rc=$?
22458                 if [ $rc -eq 255 ]; then
22459                         error "Ladvise test ${i} failed, ${rc}"
22460                 fi
22461
22462                 new_count=$($LCTL get_param -n \
22463                        ldlm.namespaces.$imp_name.lock_unused_count)
22464                 difference="$((new_count - count))"
22465
22466                 # Test 15 output is divided by 100 to map down to valid return
22467                 if [ $i -eq 15 ]; then
22468                         rc="$((rc * 100))"
22469                 fi
22470
22471                 if [ $difference -ne $rc ]; then
22472                         error "Ladvise test ${i}, bad lock count, returned " \
22473                               "${rc}, actual ${difference}"
22474                 fi
22475         done
22476
22477         #test 22 returns only success/failure
22478         i=22
22479         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22480         rc=$?
22481         if [ $rc -eq 255 ]; then
22482                 error "Ladvise test${i} failed, ${rc}"
22483         fi
22484 }
22485 run_test 255c "suite of ladvise lockahead tests"
22486
22487 test_256() {
22488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22489         remote_mds_nodsh && skip "remote MDS with nodsh"
22490         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22491         changelog_users $SINGLEMDS | grep "^cl" &&
22492                 skip "active changelog user"
22493
22494         local cl_user
22495         local cat_sl
22496         local mdt_dev
22497
22498         mdt_dev=$(facet_device $SINGLEMDS)
22499         echo $mdt_dev
22500
22501         changelog_register || error "changelog_register failed"
22502
22503         rm -rf $DIR/$tdir
22504         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22505
22506         changelog_clear 0 || error "changelog_clear failed"
22507
22508         # change something
22509         touch $DIR/$tdir/{1..10}
22510
22511         # stop the MDT
22512         stop $SINGLEMDS || error "Fail to stop MDT"
22513
22514         # remount the MDT
22515         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22516                 error "Fail to start MDT"
22517
22518         #after mount new plainllog is used
22519         touch $DIR/$tdir/{11..19}
22520         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22521         stack_trap "rm -f $tmpfile"
22522         cat_sl=$(do_facet $SINGLEMDS "sync; \
22523                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22524                  llog_reader $tmpfile | grep -c type=1064553b")
22525         do_facet $SINGLEMDS llog_reader $tmpfile
22526
22527         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22528
22529         changelog_clear 0 || error "changelog_clear failed"
22530
22531         cat_sl=$(do_facet $SINGLEMDS "sync; \
22532                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22533                  llog_reader $tmpfile | grep -c type=1064553b")
22534
22535         if (( cat_sl == 2 )); then
22536                 error "Empty plain llog was not deleted from changelog catalog"
22537         elif (( cat_sl != 1 )); then
22538                 error "Active plain llog shouldn't be deleted from catalog"
22539         fi
22540 }
22541 run_test 256 "Check llog delete for empty and not full state"
22542
22543 test_257() {
22544         remote_mds_nodsh && skip "remote MDS with nodsh"
22545         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22546                 skip "Need MDS version at least 2.8.55"
22547
22548         test_mkdir $DIR/$tdir
22549
22550         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22551                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22552         stat $DIR/$tdir
22553
22554 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22555         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22556         local facet=mds$((mdtidx + 1))
22557         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22558         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22559
22560         stop $facet || error "stop MDS failed"
22561         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22562                 error "start MDS fail"
22563         wait_recovery_complete $facet
22564 }
22565 run_test 257 "xattr locks are not lost"
22566
22567 # Verify we take the i_mutex when security requires it
22568 test_258a() {
22569 #define OBD_FAIL_IMUTEX_SEC 0x141c
22570         $LCTL set_param fail_loc=0x141c
22571         touch $DIR/$tfile
22572         chmod u+s $DIR/$tfile
22573         chmod a+rwx $DIR/$tfile
22574         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22575         RC=$?
22576         if [ $RC -ne 0 ]; then
22577                 error "error, failed to take i_mutex, rc=$?"
22578         fi
22579         rm -f $DIR/$tfile
22580 }
22581 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22582
22583 # Verify we do NOT take the i_mutex in the normal case
22584 test_258b() {
22585 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22586         $LCTL set_param fail_loc=0x141d
22587         touch $DIR/$tfile
22588         chmod a+rwx $DIR
22589         chmod a+rw $DIR/$tfile
22590         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22591         RC=$?
22592         if [ $RC -ne 0 ]; then
22593                 error "error, took i_mutex unnecessarily, rc=$?"
22594         fi
22595         rm -f $DIR/$tfile
22596
22597 }
22598 run_test 258b "verify i_mutex security behavior"
22599
22600 test_259() {
22601         local file=$DIR/$tfile
22602         local before
22603         local after
22604
22605         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22606
22607         stack_trap "rm -f $file" EXIT
22608
22609         wait_delete_completed
22610         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22611         echo "before: $before"
22612
22613         $LFS setstripe -i 0 -c 1 $file
22614         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22615         sync_all_data
22616         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22617         echo "after write: $after"
22618
22619 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22620         do_facet ost1 $LCTL set_param fail_loc=0x2301
22621         $TRUNCATE $file 0
22622         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22623         echo "after truncate: $after"
22624
22625         stop ost1
22626         do_facet ost1 $LCTL set_param fail_loc=0
22627         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22628         sleep 2
22629         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22630         echo "after restart: $after"
22631         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22632                 error "missing truncate?"
22633
22634         return 0
22635 }
22636 run_test 259 "crash at delayed truncate"
22637
22638 test_260() {
22639 #define OBD_FAIL_MDC_CLOSE               0x806
22640         $LCTL set_param fail_loc=0x80000806
22641         touch $DIR/$tfile
22642
22643 }
22644 run_test 260 "Check mdc_close fail"
22645
22646 ### Data-on-MDT sanity tests ###
22647 test_270a() {
22648         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22649                 skip "Need MDS version at least 2.10.55 for DoM"
22650
22651         # create DoM file
22652         local dom=$DIR/$tdir/dom_file
22653         local tmp=$DIR/$tdir/tmp_file
22654
22655         mkdir_on_mdt0 $DIR/$tdir
22656
22657         # basic checks for DoM component creation
22658         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22659                 error "Can set MDT layout to non-first entry"
22660
22661         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22662                 error "Can define multiple entries as MDT layout"
22663
22664         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22665
22666         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22667         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22668         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22669
22670         local mdtidx=$($LFS getstripe -m $dom)
22671         local mdtname=MDT$(printf %04x $mdtidx)
22672         local facet=mds$((mdtidx + 1))
22673         local space_check=1
22674
22675         # Skip free space checks with ZFS
22676         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22677
22678         # write
22679         sync
22680         local size_tmp=$((65536 * 3))
22681         local mdtfree1=$(do_facet $facet \
22682                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22683
22684         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22685         # check also direct IO along write
22686         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22687         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22688         sync
22689         cmp $tmp $dom || error "file data is different"
22690         [ $(stat -c%s $dom) == $size_tmp ] ||
22691                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22692         if [ $space_check == 1 ]; then
22693                 local mdtfree2=$(do_facet $facet \
22694                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22695
22696                 # increase in usage from by $size_tmp
22697                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22698                         error "MDT free space wrong after write: " \
22699                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22700         fi
22701
22702         # truncate
22703         local size_dom=10000
22704
22705         $TRUNCATE $dom $size_dom
22706         [ $(stat -c%s $dom) == $size_dom ] ||
22707                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22708         if [ $space_check == 1 ]; then
22709                 mdtfree1=$(do_facet $facet \
22710                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22711                 # decrease in usage from $size_tmp to new $size_dom
22712                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22713                   $(((size_tmp - size_dom) / 1024)) ] ||
22714                         error "MDT free space is wrong after truncate: " \
22715                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22716         fi
22717
22718         # append
22719         cat $tmp >> $dom
22720         sync
22721         size_dom=$((size_dom + size_tmp))
22722         [ $(stat -c%s $dom) == $size_dom ] ||
22723                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22724         if [ $space_check == 1 ]; then
22725                 mdtfree2=$(do_facet $facet \
22726                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22727                 # increase in usage by $size_tmp from previous
22728                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22729                         error "MDT free space is wrong after append: " \
22730                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22731         fi
22732
22733         # delete
22734         rm $dom
22735         if [ $space_check == 1 ]; then
22736                 mdtfree1=$(do_facet $facet \
22737                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22738                 # decrease in usage by $size_dom from previous
22739                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22740                         error "MDT free space is wrong after removal: " \
22741                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22742         fi
22743
22744         # combined striping
22745         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22746                 error "Can't create DoM + OST striping"
22747
22748         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22749         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22750         # check also direct IO along write
22751         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22752         sync
22753         cmp $tmp $dom || error "file data is different"
22754         [ $(stat -c%s $dom) == $size_tmp ] ||
22755                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22756         rm $dom $tmp
22757
22758         return 0
22759 }
22760 run_test 270a "DoM: basic functionality tests"
22761
22762 test_270b() {
22763         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22764                 skip "Need MDS version at least 2.10.55"
22765
22766         local dom=$DIR/$tdir/dom_file
22767         local max_size=1048576
22768
22769         mkdir -p $DIR/$tdir
22770         $LFS setstripe -E $max_size -L mdt $dom
22771
22772         # truncate over the limit
22773         $TRUNCATE $dom $(($max_size + 1)) &&
22774                 error "successful truncate over the maximum size"
22775         # write over the limit
22776         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22777                 error "successful write over the maximum size"
22778         # append over the limit
22779         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22780         echo "12345" >> $dom && error "successful append over the maximum size"
22781         rm $dom
22782
22783         return 0
22784 }
22785 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22786
22787 test_270c() {
22788         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22789                 skip "Need MDS version at least 2.10.55"
22790
22791         mkdir -p $DIR/$tdir
22792         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22793
22794         # check files inherit DoM EA
22795         touch $DIR/$tdir/first
22796         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22797                 error "bad pattern"
22798         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22799                 error "bad stripe count"
22800         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22801                 error "bad stripe size"
22802
22803         # check directory inherits DoM EA and uses it as default
22804         mkdir $DIR/$tdir/subdir
22805         touch $DIR/$tdir/subdir/second
22806         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22807                 error "bad pattern in sub-directory"
22808         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22809                 error "bad stripe count in sub-directory"
22810         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22811                 error "bad stripe size in sub-directory"
22812         return 0
22813 }
22814 run_test 270c "DoM: DoM EA inheritance tests"
22815
22816 test_270d() {
22817         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22818                 skip "Need MDS version at least 2.10.55"
22819
22820         mkdir -p $DIR/$tdir
22821         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22822
22823         # inherit default DoM striping
22824         mkdir $DIR/$tdir/subdir
22825         touch $DIR/$tdir/subdir/f1
22826
22827         # change default directory striping
22828         $LFS setstripe -c 1 $DIR/$tdir/subdir
22829         touch $DIR/$tdir/subdir/f2
22830         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22831                 error "wrong default striping in file 2"
22832         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22833                 error "bad pattern in file 2"
22834         return 0
22835 }
22836 run_test 270d "DoM: change striping from DoM to RAID0"
22837
22838 test_270e() {
22839         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22840                 skip "Need MDS version at least 2.10.55"
22841
22842         mkdir -p $DIR/$tdir/dom
22843         mkdir -p $DIR/$tdir/norm
22844         DOMFILES=20
22845         NORMFILES=10
22846         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22847         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22848
22849         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22850         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22851
22852         # find DoM files by layout
22853         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22854         [ $NUM -eq  $DOMFILES ] ||
22855                 error "lfs find -L: found $NUM, expected $DOMFILES"
22856         echo "Test 1: lfs find 20 DOM files by layout: OK"
22857
22858         # there should be 1 dir with default DOM striping
22859         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22860         [ $NUM -eq  1 ] ||
22861                 error "lfs find -L: found $NUM, expected 1 dir"
22862         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22863
22864         # find DoM files by stripe size
22865         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22866         [ $NUM -eq  $DOMFILES ] ||
22867                 error "lfs find -S: found $NUM, expected $DOMFILES"
22868         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22869
22870         # find files by stripe offset except DoM files
22871         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22872         [ $NUM -eq  $NORMFILES ] ||
22873                 error "lfs find -i: found $NUM, expected $NORMFILES"
22874         echo "Test 5: lfs find no DOM files by stripe index: OK"
22875         return 0
22876 }
22877 run_test 270e "DoM: lfs find with DoM files test"
22878
22879 test_270f() {
22880         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22881                 skip "Need MDS version at least 2.10.55"
22882
22883         local mdtname=${FSNAME}-MDT0000-mdtlov
22884         local dom=$DIR/$tdir/dom_file
22885         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22886                                                 lod.$mdtname.dom_stripesize)
22887         local dom_limit=131072
22888
22889         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22890         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22891                                                 lod.$mdtname.dom_stripesize)
22892         [ ${dom_limit} -eq ${dom_current} ] ||
22893                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22894
22895         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22896         $LFS setstripe -d $DIR/$tdir
22897         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22898                 error "Can't set directory default striping"
22899
22900         # exceed maximum stripe size
22901         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22902                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22903         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22904                 error "Able to create DoM component size more than LOD limit"
22905
22906         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22907         dom_current=$(do_facet mds1 $LCTL get_param -n \
22908                                                 lod.$mdtname.dom_stripesize)
22909         [ 0 -eq ${dom_current} ] ||
22910                 error "Can't set zero DoM stripe limit"
22911         rm $dom
22912
22913         # attempt to create DoM file on server with disabled DoM should
22914         # remove DoM entry from layout and be succeed
22915         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22916                 error "Can't create DoM file (DoM is disabled)"
22917         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22918                 error "File has DoM component while DoM is disabled"
22919         rm $dom
22920
22921         # attempt to create DoM file with only DoM stripe should return error
22922         $LFS setstripe -E $dom_limit -L mdt $dom &&
22923                 error "Able to create DoM-only file while DoM is disabled"
22924
22925         # too low values to be aligned with smallest stripe size 64K
22926         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22927         dom_current=$(do_facet mds1 $LCTL get_param -n \
22928                                                 lod.$mdtname.dom_stripesize)
22929         [ 30000 -eq ${dom_current} ] &&
22930                 error "Can set too small DoM stripe limit"
22931
22932         # 64K is a minimal stripe size in Lustre, expect limit of that size
22933         [ 65536 -eq ${dom_current} ] ||
22934                 error "Limit is not set to 64K but ${dom_current}"
22935
22936         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22937         dom_current=$(do_facet mds1 $LCTL get_param -n \
22938                                                 lod.$mdtname.dom_stripesize)
22939         echo $dom_current
22940         [ 2147483648 -eq ${dom_current} ] &&
22941                 error "Can set too large DoM stripe limit"
22942
22943         do_facet mds1 $LCTL set_param -n \
22944                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22945         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22946                 error "Can't create DoM component size after limit change"
22947         do_facet mds1 $LCTL set_param -n \
22948                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22949         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22950                 error "Can't create DoM file after limit decrease"
22951         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22952                 error "Can create big DoM component after limit decrease"
22953         touch ${dom}_def ||
22954                 error "Can't create file with old default layout"
22955
22956         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22957         return 0
22958 }
22959 run_test 270f "DoM: maximum DoM stripe size checks"
22960
22961 test_270g() {
22962         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22963                 skip "Need MDS version at least 2.13.52"
22964         local dom=$DIR/$tdir/$tfile
22965
22966         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22967         local lodname=${FSNAME}-MDT0000-mdtlov
22968
22969         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22970         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22971         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22972         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22973
22974         local dom_limit=1024
22975         local dom_threshold="50%"
22976
22977         $LFS setstripe -d $DIR/$tdir
22978         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22979                 error "Can't set directory default striping"
22980
22981         do_facet mds1 $LCTL set_param -n \
22982                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22983         # set 0 threshold and create DOM file to change tunable stripesize
22984         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22985         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22986                 error "Failed to create $dom file"
22987         # now tunable dom_cur_stripesize should reach maximum
22988         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22989                                         lod.${lodname}.dom_stripesize_cur_kb)
22990         [[ $dom_current == $dom_limit ]] ||
22991                 error "Current DOM stripesize is not maximum"
22992         rm $dom
22993
22994         # set threshold for further tests
22995         do_facet mds1 $LCTL set_param -n \
22996                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22997         echo "DOM threshold is $dom_threshold free space"
22998         local dom_def
22999         local dom_set
23000         # Spoof bfree to exceed threshold
23001         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23002         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23003         for spfree in 40 20 0 15 30 55; do
23004                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23005                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23006                         error "Failed to create $dom file"
23007                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23008                                         lod.${lodname}.dom_stripesize_cur_kb)
23009                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23010                 [[ $dom_def != $dom_current ]] ||
23011                         error "Default stripe size was not changed"
23012                 if (( spfree > 0 )) ; then
23013                         dom_set=$($LFS getstripe -S $dom)
23014                         (( dom_set == dom_def * 1024 )) ||
23015                                 error "DOM component size is still old"
23016                 else
23017                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23018                                 error "DoM component is set with no free space"
23019                 fi
23020                 rm $dom
23021                 dom_current=$dom_def
23022         done
23023 }
23024 run_test 270g "DoM: default DoM stripe size depends on free space"
23025
23026 test_270h() {
23027         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23028                 skip "Need MDS version at least 2.13.53"
23029
23030         local mdtname=${FSNAME}-MDT0000-mdtlov
23031         local dom=$DIR/$tdir/$tfile
23032         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23033
23034         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23035         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23036
23037         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23038         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23039                 error "can't create OST file"
23040         # mirrored file with DOM entry in the second mirror
23041         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23042                 error "can't create mirror with DoM component"
23043
23044         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23045
23046         # DOM component in the middle and has other enries in the same mirror,
23047         # should succeed but lost DoM component
23048         $LFS setstripe --copy=${dom}_1 $dom ||
23049                 error "Can't create file from OST|DOM mirror layout"
23050         # check new file has no DoM layout after all
23051         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23052                 error "File has DoM component while DoM is disabled"
23053 }
23054 run_test 270h "DoM: DoM stripe removal when disabled on server"
23055
23056 test_270i() {
23057         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23058                 skip "Need MDS version at least 2.14.54"
23059
23060         mkdir $DIR/$tdir
23061         # DoM with plain layout
23062         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23063                 error "default plain layout with DoM must fail"
23064         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23065                 error "setstripe plain file layout with DoM must fail"
23066         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23067                 error "default DoM layout with bad striping must fail"
23068         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23069                 error "setstripe to DoM layout with bad striping must fail"
23070         return 0
23071 }
23072 run_test 270i "DoM: setting invalid DoM striping should fail"
23073
23074 test_271a() {
23075         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23076                 skip "Need MDS version at least 2.10.55"
23077
23078         local dom=$DIR/$tdir/dom
23079
23080         mkdir -p $DIR/$tdir
23081
23082         $LFS setstripe -E 1024K -L mdt $dom
23083
23084         lctl set_param -n mdc.*.stats=clear
23085         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23086         cat $dom > /dev/null
23087         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23088         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23089         ls $dom
23090         rm -f $dom
23091 }
23092 run_test 271a "DoM: data is cached for read after write"
23093
23094 test_271b() {
23095         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23096                 skip "Need MDS version at least 2.10.55"
23097
23098         local dom=$DIR/$tdir/dom
23099
23100         mkdir -p $DIR/$tdir
23101
23102         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23103
23104         lctl set_param -n mdc.*.stats=clear
23105         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23106         cancel_lru_locks mdc
23107         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23108         # second stat to check size is cached on client
23109         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23110         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23111         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23112         rm -f $dom
23113 }
23114 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23115
23116 test_271ba() {
23117         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23118                 skip "Need MDS version at least 2.10.55"
23119
23120         local dom=$DIR/$tdir/dom
23121
23122         mkdir -p $DIR/$tdir
23123
23124         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23125
23126         lctl set_param -n mdc.*.stats=clear
23127         lctl set_param -n osc.*.stats=clear
23128         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23129         cancel_lru_locks mdc
23130         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23131         # second stat to check size is cached on client
23132         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23133         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23134         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23135         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23136         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23137         rm -f $dom
23138 }
23139 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23140
23141
23142 get_mdc_stats() {
23143         local mdtidx=$1
23144         local param=$2
23145         local mdt=MDT$(printf %04x $mdtidx)
23146
23147         if [ -z $param ]; then
23148                 lctl get_param -n mdc.*$mdt*.stats
23149         else
23150                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23151         fi
23152 }
23153
23154 test_271c() {
23155         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23156                 skip "Need MDS version at least 2.10.55"
23157
23158         local dom=$DIR/$tdir/dom
23159
23160         mkdir -p $DIR/$tdir
23161
23162         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23163
23164         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23165         local facet=mds$((mdtidx + 1))
23166
23167         cancel_lru_locks mdc
23168         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23169         createmany -o $dom 1000
23170         lctl set_param -n mdc.*.stats=clear
23171         smalliomany -w $dom 1000 200
23172         get_mdc_stats $mdtidx
23173         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23174         # Each file has 1 open, 1 IO enqueues, total 2000
23175         # but now we have also +1 getxattr for security.capability, total 3000
23176         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23177         unlinkmany $dom 1000
23178
23179         cancel_lru_locks mdc
23180         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23181         createmany -o $dom 1000
23182         lctl set_param -n mdc.*.stats=clear
23183         smalliomany -w $dom 1000 200
23184         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23185         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23186         # for OPEN and IO lock.
23187         [ $((enq - enq_2)) -ge 1000 ] ||
23188                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23189         unlinkmany $dom 1000
23190         return 0
23191 }
23192 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23193
23194 cleanup_271def_tests() {
23195         trap 0
23196         rm -f $1
23197 }
23198
23199 test_271d() {
23200         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23201                 skip "Need MDS version at least 2.10.57"
23202
23203         local dom=$DIR/$tdir/dom
23204         local tmp=$TMP/$tfile
23205         trap "cleanup_271def_tests $tmp" EXIT
23206
23207         mkdir -p $DIR/$tdir
23208
23209         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23210
23211         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23212
23213         cancel_lru_locks mdc
23214         dd if=/dev/urandom of=$tmp bs=1000 count=1
23215         dd if=$tmp of=$dom bs=1000 count=1
23216         cancel_lru_locks mdc
23217
23218         cat /etc/hosts >> $tmp
23219         lctl set_param -n mdc.*.stats=clear
23220
23221         # append data to the same file it should update local page
23222         echo "Append to the same page"
23223         cat /etc/hosts >> $dom
23224         local num=$(get_mdc_stats $mdtidx ost_read)
23225         local ra=$(get_mdc_stats $mdtidx req_active)
23226         local rw=$(get_mdc_stats $mdtidx req_waittime)
23227
23228         [ -z $num ] || error "$num READ RPC occured"
23229         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23230         echo "... DONE"
23231
23232         # compare content
23233         cmp $tmp $dom || error "file miscompare"
23234
23235         cancel_lru_locks mdc
23236         lctl set_param -n mdc.*.stats=clear
23237
23238         echo "Open and read file"
23239         cat $dom > /dev/null
23240         local num=$(get_mdc_stats $mdtidx ost_read)
23241         local ra=$(get_mdc_stats $mdtidx req_active)
23242         local rw=$(get_mdc_stats $mdtidx req_waittime)
23243
23244         [ -z $num ] || error "$num READ RPC occured"
23245         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23246         echo "... DONE"
23247
23248         # compare content
23249         cmp $tmp $dom || error "file miscompare"
23250
23251         return 0
23252 }
23253 run_test 271d "DoM: read on open (1K file in reply buffer)"
23254
23255 test_271f() {
23256         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23257                 skip "Need MDS version at least 2.10.57"
23258
23259         local dom=$DIR/$tdir/dom
23260         local tmp=$TMP/$tfile
23261         trap "cleanup_271def_tests $tmp" EXIT
23262
23263         mkdir -p $DIR/$tdir
23264
23265         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23266
23267         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23268
23269         cancel_lru_locks mdc
23270         dd if=/dev/urandom of=$tmp bs=265000 count=1
23271         dd if=$tmp of=$dom bs=265000 count=1
23272         cancel_lru_locks mdc
23273         cat /etc/hosts >> $tmp
23274         lctl set_param -n mdc.*.stats=clear
23275
23276         echo "Append to the same page"
23277         cat /etc/hosts >> $dom
23278         local num=$(get_mdc_stats $mdtidx ost_read)
23279         local ra=$(get_mdc_stats $mdtidx req_active)
23280         local rw=$(get_mdc_stats $mdtidx req_waittime)
23281
23282         [ -z $num ] || error "$num READ RPC occured"
23283         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23284         echo "... DONE"
23285
23286         # compare content
23287         cmp $tmp $dom || error "file miscompare"
23288
23289         cancel_lru_locks mdc
23290         lctl set_param -n mdc.*.stats=clear
23291
23292         echo "Open and read file"
23293         cat $dom > /dev/null
23294         local num=$(get_mdc_stats $mdtidx ost_read)
23295         local ra=$(get_mdc_stats $mdtidx req_active)
23296         local rw=$(get_mdc_stats $mdtidx req_waittime)
23297
23298         [ -z $num ] && num=0
23299         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23300         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23301         echo "... DONE"
23302
23303         # compare content
23304         cmp $tmp $dom || error "file miscompare"
23305
23306         return 0
23307 }
23308 run_test 271f "DoM: read on open (200K file and read tail)"
23309
23310 test_271g() {
23311         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23312                 skip "Skipping due to old client or server version"
23313
23314         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23315         # to get layout
23316         $CHECKSTAT -t file $DIR1/$tfile
23317
23318         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23319         MULTIOP_PID=$!
23320         sleep 1
23321         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23322         $LCTL set_param fail_loc=0x80000314
23323         rm $DIR1/$tfile || error "Unlink fails"
23324         RC=$?
23325         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23326         [ $RC -eq 0 ] || error "Failed write to stale object"
23327 }
23328 run_test 271g "Discard DoM data vs client flush race"
23329
23330 test_272a() {
23331         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23332                 skip "Need MDS version at least 2.11.50"
23333
23334         local dom=$DIR/$tdir/dom
23335         mkdir -p $DIR/$tdir
23336
23337         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23338         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23339                 error "failed to write data into $dom"
23340         local old_md5=$(md5sum $dom)
23341
23342         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23343                 error "failed to migrate to the same DoM component"
23344
23345         local new_md5=$(md5sum $dom)
23346
23347         [ "$old_md5" == "$new_md5" ] ||
23348                 error "md5sum differ: $old_md5, $new_md5"
23349
23350         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23351                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23352 }
23353 run_test 272a "DoM migration: new layout with the same DOM component"
23354
23355 test_272b() {
23356         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23357                 skip "Need MDS version at least 2.11.50"
23358
23359         local dom=$DIR/$tdir/dom
23360         mkdir -p $DIR/$tdir
23361         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23362
23363         local mdtidx=$($LFS getstripe -m $dom)
23364         local mdtname=MDT$(printf %04x $mdtidx)
23365         local facet=mds$((mdtidx + 1))
23366
23367         local mdtfree1=$(do_facet $facet \
23368                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23369         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23370                 error "failed to write data into $dom"
23371         local old_md5=$(md5sum $dom)
23372         cancel_lru_locks mdc
23373         local mdtfree1=$(do_facet $facet \
23374                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23375
23376         $LFS migrate -c2 $dom ||
23377                 error "failed to migrate to the new composite layout"
23378         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23379                 error "MDT stripe was not removed"
23380
23381         cancel_lru_locks mdc
23382         local new_md5=$(md5sum $dom)
23383         [ "$old_md5" == "$new_md5" ] ||
23384                 error "$old_md5 != $new_md5"
23385
23386         # Skip free space checks with ZFS
23387         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23388                 local mdtfree2=$(do_facet $facet \
23389                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23390                 [ $mdtfree2 -gt $mdtfree1 ] ||
23391                         error "MDT space is not freed after migration"
23392         fi
23393         return 0
23394 }
23395 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23396
23397 test_272c() {
23398         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23399                 skip "Need MDS version at least 2.11.50"
23400
23401         local dom=$DIR/$tdir/$tfile
23402         mkdir -p $DIR/$tdir
23403         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23404
23405         local mdtidx=$($LFS getstripe -m $dom)
23406         local mdtname=MDT$(printf %04x $mdtidx)
23407         local facet=mds$((mdtidx + 1))
23408
23409         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23410                 error "failed to write data into $dom"
23411         local old_md5=$(md5sum $dom)
23412         cancel_lru_locks mdc
23413         local mdtfree1=$(do_facet $facet \
23414                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23415
23416         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23417                 error "failed to migrate to the new composite layout"
23418         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23419                 error "MDT stripe was not removed"
23420
23421         cancel_lru_locks mdc
23422         local new_md5=$(md5sum $dom)
23423         [ "$old_md5" == "$new_md5" ] ||
23424                 error "$old_md5 != $new_md5"
23425
23426         # Skip free space checks with ZFS
23427         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23428                 local mdtfree2=$(do_facet $facet \
23429                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23430                 [ $mdtfree2 -gt $mdtfree1 ] ||
23431                         error "MDS space is not freed after migration"
23432         fi
23433         return 0
23434 }
23435 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23436
23437 test_272d() {
23438         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23439                 skip "Need MDS version at least 2.12.55"
23440
23441         local dom=$DIR/$tdir/$tfile
23442         mkdir -p $DIR/$tdir
23443         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23444
23445         local mdtidx=$($LFS getstripe -m $dom)
23446         local mdtname=MDT$(printf %04x $mdtidx)
23447         local facet=mds$((mdtidx + 1))
23448
23449         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23450                 error "failed to write data into $dom"
23451         local old_md5=$(md5sum $dom)
23452         cancel_lru_locks mdc
23453         local mdtfree1=$(do_facet $facet \
23454                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23455
23456         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23457                 error "failed mirroring to the new composite layout"
23458         $LFS mirror resync $dom ||
23459                 error "failed mirror resync"
23460         $LFS mirror split --mirror-id 1 -d $dom ||
23461                 error "failed mirror split"
23462
23463         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23464                 error "MDT stripe was not removed"
23465
23466         cancel_lru_locks mdc
23467         local new_md5=$(md5sum $dom)
23468         [ "$old_md5" == "$new_md5" ] ||
23469                 error "$old_md5 != $new_md5"
23470
23471         # Skip free space checks with ZFS
23472         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23473                 local mdtfree2=$(do_facet $facet \
23474                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23475                 [ $mdtfree2 -gt $mdtfree1 ] ||
23476                         error "MDS space is not freed after DOM mirror deletion"
23477         fi
23478         return 0
23479 }
23480 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23481
23482 test_272e() {
23483         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23484                 skip "Need MDS version at least 2.12.55"
23485
23486         local dom=$DIR/$tdir/$tfile
23487         mkdir -p $DIR/$tdir
23488         $LFS setstripe -c 2 $dom
23489
23490         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23491                 error "failed to write data into $dom"
23492         local old_md5=$(md5sum $dom)
23493         cancel_lru_locks
23494
23495         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23496                 error "failed mirroring to the DOM layout"
23497         $LFS mirror resync $dom ||
23498                 error "failed mirror resync"
23499         $LFS mirror split --mirror-id 1 -d $dom ||
23500                 error "failed mirror split"
23501
23502         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23503                 error "MDT stripe wasn't set"
23504
23505         cancel_lru_locks
23506         local new_md5=$(md5sum $dom)
23507         [ "$old_md5" == "$new_md5" ] ||
23508                 error "$old_md5 != $new_md5"
23509
23510         return 0
23511 }
23512 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23513
23514 test_272f() {
23515         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23516                 skip "Need MDS version at least 2.12.55"
23517
23518         local dom=$DIR/$tdir/$tfile
23519         mkdir -p $DIR/$tdir
23520         $LFS setstripe -c 2 $dom
23521
23522         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23523                 error "failed to write data into $dom"
23524         local old_md5=$(md5sum $dom)
23525         cancel_lru_locks
23526
23527         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23528                 error "failed migrating to the DOM file"
23529
23530         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23531                 error "MDT stripe wasn't set"
23532
23533         cancel_lru_locks
23534         local new_md5=$(md5sum $dom)
23535         [ "$old_md5" != "$new_md5" ] &&
23536                 error "$old_md5 != $new_md5"
23537
23538         return 0
23539 }
23540 run_test 272f "DoM migration: OST-striped file to DOM file"
23541
23542 test_273a() {
23543         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23544                 skip "Need MDS version at least 2.11.50"
23545
23546         # Layout swap cannot be done if either file has DOM component,
23547         # this will never be supported, migration should be used instead
23548
23549         local dom=$DIR/$tdir/$tfile
23550         mkdir -p $DIR/$tdir
23551
23552         $LFS setstripe -c2 ${dom}_plain
23553         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23554         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23555                 error "can swap layout with DoM component"
23556         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23557                 error "can swap layout with DoM component"
23558
23559         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23560         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23561                 error "can swap layout with DoM component"
23562         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23563                 error "can swap layout with DoM component"
23564         return 0
23565 }
23566 run_test 273a "DoM: layout swapping should fail with DOM"
23567
23568 test_273b() {
23569         mkdir -p $DIR/$tdir
23570         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23571
23572 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23573         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23574
23575         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23576 }
23577 run_test 273b "DoM: race writeback and object destroy"
23578
23579 test_275() {
23580         remote_ost_nodsh && skip "remote OST with nodsh"
23581         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23582                 skip "Need OST version >= 2.10.57"
23583
23584         local file=$DIR/$tfile
23585         local oss
23586
23587         oss=$(comma_list $(osts_nodes))
23588
23589         dd if=/dev/urandom of=$file bs=1M count=2 ||
23590                 error "failed to create a file"
23591         cancel_lru_locks osc
23592
23593         #lock 1
23594         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23595                 error "failed to read a file"
23596
23597 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23598         $LCTL set_param fail_loc=0x8000031f
23599
23600         cancel_lru_locks osc &
23601         sleep 1
23602
23603 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23604         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23605         #IO takes another lock, but matches the PENDING one
23606         #and places it to the IO RPC
23607         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23608                 error "failed to read a file with PENDING lock"
23609 }
23610 run_test 275 "Read on a canceled duplicate lock"
23611
23612 test_276() {
23613         remote_ost_nodsh && skip "remote OST with nodsh"
23614         local pid
23615
23616         do_facet ost1 "(while true; do \
23617                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23618                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23619         pid=$!
23620
23621         for LOOP in $(seq 20); do
23622                 stop ost1
23623                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23624         done
23625         kill -9 $pid
23626         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23627                 rm $TMP/sanity_276_pid"
23628 }
23629 run_test 276 "Race between mount and obd_statfs"
23630
23631 test_277() {
23632         $LCTL set_param ldlm.namespaces.*.lru_size=0
23633         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23634         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23635                         grep ^used_mb | awk '{print $2}')
23636         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23638                 oflag=direct conv=notrunc
23639         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23640                         grep ^used_mb | awk '{print $2}')
23641         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23642 }
23643 run_test 277 "Direct IO shall drop page cache"
23644
23645 test_278() {
23646         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23647         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23648         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23649                 skip "needs the same host for mdt1 mdt2" && return
23650
23651         local pid1
23652         local pid2
23653
23654 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23655         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23656         stop mds2 &
23657         pid2=$!
23658
23659         stop mds1
23660
23661         echo "Starting MDTs"
23662         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23663         wait $pid2
23664 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23665 #will return NULL
23666         do_facet mds2 $LCTL set_param fail_loc=0
23667
23668         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23669         wait_recovery_complete mds2
23670 }
23671 run_test 278 "Race starting MDS between MDTs stop/start"
23672
23673 test_280() {
23674         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23675                 skip "Need MGS version at least 2.13.52"
23676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23677         combined_mgs_mds || skip "needs combined MGS/MDT"
23678
23679         umount_client $MOUNT
23680 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23681         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23682
23683         mount_client $MOUNT &
23684         sleep 1
23685         stop mgs || error "stop mgs failed"
23686         #for a race mgs would crash
23687         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23688         # make sure we unmount client before remounting
23689         wait
23690         umount_client $MOUNT
23691         mount_client $MOUNT || error "mount client failed"
23692 }
23693 run_test 280 "Race between MGS umount and client llog processing"
23694
23695 cleanup_test_300() {
23696         trap 0
23697         umask $SAVE_UMASK
23698 }
23699 test_striped_dir() {
23700         local mdt_index=$1
23701         local stripe_count
23702         local stripe_index
23703
23704         mkdir -p $DIR/$tdir
23705
23706         SAVE_UMASK=$(umask)
23707         trap cleanup_test_300 RETURN EXIT
23708
23709         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23710                                                 $DIR/$tdir/striped_dir ||
23711                 error "set striped dir error"
23712
23713         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23714         [ "$mode" = "755" ] || error "expect 755 got $mode"
23715
23716         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23717                 error "getdirstripe failed"
23718         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23719         if [ "$stripe_count" != "2" ]; then
23720                 error "1:stripe_count is $stripe_count, expect 2"
23721         fi
23722         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23723         if [ "$stripe_count" != "2" ]; then
23724                 error "2:stripe_count is $stripe_count, expect 2"
23725         fi
23726
23727         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23728         if [ "$stripe_index" != "$mdt_index" ]; then
23729                 error "stripe_index is $stripe_index, expect $mdt_index"
23730         fi
23731
23732         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23733                 error "nlink error after create striped dir"
23734
23735         mkdir $DIR/$tdir/striped_dir/a
23736         mkdir $DIR/$tdir/striped_dir/b
23737
23738         stat $DIR/$tdir/striped_dir/a ||
23739                 error "create dir under striped dir failed"
23740         stat $DIR/$tdir/striped_dir/b ||
23741                 error "create dir under striped dir failed"
23742
23743         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23744                 error "nlink error after mkdir"
23745
23746         rmdir $DIR/$tdir/striped_dir/a
23747         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23748                 error "nlink error after rmdir"
23749
23750         rmdir $DIR/$tdir/striped_dir/b
23751         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23752                 error "nlink error after rmdir"
23753
23754         chattr +i $DIR/$tdir/striped_dir
23755         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23756                 error "immutable flags not working under striped dir!"
23757         chattr -i $DIR/$tdir/striped_dir
23758
23759         rmdir $DIR/$tdir/striped_dir ||
23760                 error "rmdir striped dir error"
23761
23762         cleanup_test_300
23763
23764         true
23765 }
23766
23767 test_300a() {
23768         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23769                 skip "skipped for lustre < 2.7.0"
23770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23771         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23772
23773         test_striped_dir 0 || error "failed on striped dir on MDT0"
23774         test_striped_dir 1 || error "failed on striped dir on MDT0"
23775 }
23776 run_test 300a "basic striped dir sanity test"
23777
23778 test_300b() {
23779         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23780                 skip "skipped for lustre < 2.7.0"
23781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23783
23784         local i
23785         local mtime1
23786         local mtime2
23787         local mtime3
23788
23789         test_mkdir $DIR/$tdir || error "mkdir fail"
23790         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23791                 error "set striped dir error"
23792         for i in {0..9}; do
23793                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23794                 sleep 1
23795                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23796                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23797                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23798                 sleep 1
23799                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23800                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23801                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23802         done
23803         true
23804 }
23805 run_test 300b "check ctime/mtime for striped dir"
23806
23807 test_300c() {
23808         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23809                 skip "skipped for lustre < 2.7.0"
23810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23812
23813         local file_count
23814
23815         mkdir_on_mdt0 $DIR/$tdir
23816         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23817                 error "set striped dir error"
23818
23819         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23820                 error "chown striped dir failed"
23821
23822         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23823                 error "create 5k files failed"
23824
23825         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23826
23827         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23828
23829         rm -rf $DIR/$tdir
23830 }
23831 run_test 300c "chown && check ls under striped directory"
23832
23833 test_300d() {
23834         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23835                 skip "skipped for lustre < 2.7.0"
23836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23838
23839         local stripe_count
23840         local file
23841
23842         mkdir -p $DIR/$tdir
23843         $LFS setstripe -c 2 $DIR/$tdir
23844
23845         #local striped directory
23846         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23847                 error "set striped dir error"
23848         #look at the directories for debug purposes
23849         ls -l $DIR/$tdir
23850         $LFS getdirstripe $DIR/$tdir
23851         ls -l $DIR/$tdir/striped_dir
23852         $LFS getdirstripe $DIR/$tdir/striped_dir
23853         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23854                 error "create 10 files failed"
23855
23856         #remote striped directory
23857         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23858                 error "set striped dir error"
23859         #look at the directories for debug purposes
23860         ls -l $DIR/$tdir
23861         $LFS getdirstripe $DIR/$tdir
23862         ls -l $DIR/$tdir/remote_striped_dir
23863         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23864         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23865                 error "create 10 files failed"
23866
23867         for file in $(find $DIR/$tdir); do
23868                 stripe_count=$($LFS getstripe -c $file)
23869                 [ $stripe_count -eq 2 ] ||
23870                         error "wrong stripe $stripe_count for $file"
23871         done
23872
23873         rm -rf $DIR/$tdir
23874 }
23875 run_test 300d "check default stripe under striped directory"
23876
23877 test_300e() {
23878         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23879                 skip "Need MDS version at least 2.7.55"
23880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23881         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23882
23883         local stripe_count
23884         local file
23885
23886         mkdir -p $DIR/$tdir
23887
23888         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23889                 error "set striped dir error"
23890
23891         touch $DIR/$tdir/striped_dir/a
23892         touch $DIR/$tdir/striped_dir/b
23893         touch $DIR/$tdir/striped_dir/c
23894
23895         mkdir $DIR/$tdir/striped_dir/dir_a
23896         mkdir $DIR/$tdir/striped_dir/dir_b
23897         mkdir $DIR/$tdir/striped_dir/dir_c
23898
23899         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23900                 error "set striped adir under striped dir error"
23901
23902         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23903                 error "set striped bdir under striped dir error"
23904
23905         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23906                 error "set striped cdir under striped dir error"
23907
23908         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23909                 error "rename dir under striped dir fails"
23910
23911         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23912                 error "rename dir under different stripes fails"
23913
23914         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23915                 error "rename file under striped dir should succeed"
23916
23917         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23918                 error "rename dir under striped dir should succeed"
23919
23920         rm -rf $DIR/$tdir
23921 }
23922 run_test 300e "check rename under striped directory"
23923
23924 test_300f() {
23925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23926         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23927         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23928                 skip "Need MDS version at least 2.7.55"
23929
23930         local stripe_count
23931         local file
23932
23933         rm -rf $DIR/$tdir
23934         mkdir -p $DIR/$tdir
23935
23936         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23937                 error "set striped dir error"
23938
23939         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23940                 error "set striped dir error"
23941
23942         touch $DIR/$tdir/striped_dir/a
23943         mkdir $DIR/$tdir/striped_dir/dir_a
23944         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23945                 error "create striped dir under striped dir fails"
23946
23947         touch $DIR/$tdir/striped_dir1/b
23948         mkdir $DIR/$tdir/striped_dir1/dir_b
23949         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23950                 error "create striped dir under striped dir fails"
23951
23952         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23953                 error "rename dir under different striped dir should fail"
23954
23955         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23956                 error "rename striped dir under diff striped dir should fail"
23957
23958         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23959                 error "rename file under diff striped dirs fails"
23960
23961         rm -rf $DIR/$tdir
23962 }
23963 run_test 300f "check rename cross striped directory"
23964
23965 test_300_check_default_striped_dir()
23966 {
23967         local dirname=$1
23968         local default_count=$2
23969         local default_index=$3
23970         local stripe_count
23971         local stripe_index
23972         local dir_stripe_index
23973         local dir
23974
23975         echo "checking $dirname $default_count $default_index"
23976         $LFS setdirstripe -D -c $default_count -i $default_index \
23977                                 -H all_char $DIR/$tdir/$dirname ||
23978                 error "set default stripe on striped dir error"
23979         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23980         [ $stripe_count -eq $default_count ] ||
23981                 error "expect $default_count get $stripe_count for $dirname"
23982
23983         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23984         [ $stripe_index -eq $default_index ] ||
23985                 error "expect $default_index get $stripe_index for $dirname"
23986
23987         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23988                                                 error "create dirs failed"
23989
23990         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23991         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23992         for dir in $(find $DIR/$tdir/$dirname/*); do
23993                 stripe_count=$($LFS getdirstripe -c $dir)
23994                 (( $stripe_count == $default_count )) ||
23995                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23996                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23997                 error "stripe count $default_count != $stripe_count for $dir"
23998
23999                 stripe_index=$($LFS getdirstripe -i $dir)
24000                 [ $default_index -eq -1 ] ||
24001                         [ $stripe_index -eq $default_index ] ||
24002                         error "$stripe_index != $default_index for $dir"
24003
24004                 #check default stripe
24005                 stripe_count=$($LFS getdirstripe -D -c $dir)
24006                 [ $stripe_count -eq $default_count ] ||
24007                 error "default count $default_count != $stripe_count for $dir"
24008
24009                 stripe_index=$($LFS getdirstripe -D -i $dir)
24010                 [ $stripe_index -eq $default_index ] ||
24011                 error "default index $default_index != $stripe_index for $dir"
24012         done
24013         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24014 }
24015
24016 test_300g() {
24017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24018         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24019                 skip "Need MDS version at least 2.7.55"
24020
24021         local dir
24022         local stripe_count
24023         local stripe_index
24024
24025         mkdir_on_mdt0 $DIR/$tdir
24026         mkdir $DIR/$tdir/normal_dir
24027
24028         #Checking when client cache stripe index
24029         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24030         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24031                 error "create striped_dir failed"
24032
24033         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24034                 error "create dir0 fails"
24035         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24036         [ $stripe_index -eq 0 ] ||
24037                 error "dir0 expect index 0 got $stripe_index"
24038
24039         mkdir $DIR/$tdir/striped_dir/dir1 ||
24040                 error "create dir1 fails"
24041         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24042         [ $stripe_index -eq 1 ] ||
24043                 error "dir1 expect index 1 got $stripe_index"
24044
24045         #check default stripe count/stripe index
24046         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24047         test_300_check_default_striped_dir normal_dir 1 0
24048         test_300_check_default_striped_dir normal_dir -1 1
24049         test_300_check_default_striped_dir normal_dir 2 -1
24050
24051         #delete default stripe information
24052         echo "delete default stripeEA"
24053         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24054                 error "set default stripe on striped dir error"
24055
24056         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24057         for dir in $(find $DIR/$tdir/normal_dir/*); do
24058                 stripe_count=$($LFS getdirstripe -c $dir)
24059                 [ $stripe_count -eq 0 ] ||
24060                         error "expect 1 get $stripe_count for $dir"
24061         done
24062 }
24063 run_test 300g "check default striped directory for normal directory"
24064
24065 test_300h() {
24066         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24067         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24068                 skip "Need MDS version at least 2.7.55"
24069
24070         local dir
24071         local stripe_count
24072
24073         mkdir $DIR/$tdir
24074         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24075                 error "set striped dir error"
24076
24077         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24078         test_300_check_default_striped_dir striped_dir 1 0
24079         test_300_check_default_striped_dir striped_dir -1 1
24080         test_300_check_default_striped_dir striped_dir 2 -1
24081
24082         #delete default stripe information
24083         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24084                 error "set default stripe on striped dir error"
24085
24086         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24087         for dir in $(find $DIR/$tdir/striped_dir/*); do
24088                 stripe_count=$($LFS getdirstripe -c $dir)
24089                 [ $stripe_count -eq 0 ] ||
24090                         error "expect 1 get $stripe_count for $dir"
24091         done
24092 }
24093 run_test 300h "check default striped directory for striped directory"
24094
24095 test_300i() {
24096         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24097         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24098         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24099                 skip "Need MDS version at least 2.7.55"
24100
24101         local stripe_count
24102         local file
24103
24104         mkdir $DIR/$tdir
24105
24106         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24107                 error "set striped dir error"
24108
24109         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24110                 error "create files under striped dir failed"
24111
24112         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24113                 error "set striped hashdir error"
24114
24115         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24116                 error "create dir0 under hash dir failed"
24117         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24118                 error "create dir1 under hash dir failed"
24119         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24120                 error "create dir2 under hash dir failed"
24121
24122         # unfortunately, we need to umount to clear dir layout cache for now
24123         # once we fully implement dir layout, we can drop this
24124         umount_client $MOUNT || error "umount failed"
24125         mount_client $MOUNT || error "mount failed"
24126
24127         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24128         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24129         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24130
24131         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24132                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24133                         error "create crush2 dir $tdir/hashdir/d3 failed"
24134                 $LFS find -H crush2 $DIR/$tdir/hashdir
24135                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24136                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24137
24138                 # mkdir with an invalid hash type (hash=fail_val) from client
24139                 # should be replaced on MDS with a valid (default) hash type
24140                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24141                 $LCTL set_param fail_loc=0x1901 fail_val=99
24142                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24143
24144                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24145                 local expect=$(do_facet mds1 \
24146                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24147                 [[ $hash == $expect ]] ||
24148                         error "d99 hash '$hash' != expected hash '$expect'"
24149         fi
24150
24151         #set the stripe to be unknown hash type on read
24152         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24153         $LCTL set_param fail_loc=0x1901 fail_val=99
24154         for ((i = 0; i < 10; i++)); do
24155                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24156                         error "stat f-$i failed"
24157                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24158         done
24159
24160         touch $DIR/$tdir/striped_dir/f0 &&
24161                 error "create under striped dir with unknown hash should fail"
24162
24163         $LCTL set_param fail_loc=0
24164
24165         umount_client $MOUNT || error "umount failed"
24166         mount_client $MOUNT || error "mount failed"
24167
24168         return 0
24169 }
24170 run_test 300i "client handle unknown hash type striped directory"
24171
24172 test_300j() {
24173         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24175         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24176                 skip "Need MDS version at least 2.7.55"
24177
24178         local stripe_count
24179         local file
24180
24181         mkdir $DIR/$tdir
24182
24183         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24184         $LCTL set_param fail_loc=0x1702
24185         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24186                 error "set striped dir error"
24187
24188         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24189                 error "create files under striped dir failed"
24190
24191         $LCTL set_param fail_loc=0
24192
24193         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24194
24195         return 0
24196 }
24197 run_test 300j "test large update record"
24198
24199 test_300k() {
24200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24201         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24202         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24203                 skip "Need MDS version at least 2.7.55"
24204
24205         # this test needs a huge transaction
24206         local kb
24207         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24208              osd*.$FSNAME-MDT0000.kbytestotal")
24209         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24210
24211         local stripe_count
24212         local file
24213
24214         mkdir $DIR/$tdir
24215
24216         #define OBD_FAIL_LARGE_STRIPE   0x1703
24217         $LCTL set_param fail_loc=0x1703
24218         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24219                 error "set striped dir error"
24220         $LCTL set_param fail_loc=0
24221
24222         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24223                 error "getstripeddir fails"
24224         rm -rf $DIR/$tdir/striped_dir ||
24225                 error "unlink striped dir fails"
24226
24227         return 0
24228 }
24229 run_test 300k "test large striped directory"
24230
24231 test_300l() {
24232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24234         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24235                 skip "Need MDS version at least 2.7.55"
24236
24237         local stripe_index
24238
24239         test_mkdir -p $DIR/$tdir/striped_dir
24240         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24241                         error "chown $RUNAS_ID failed"
24242         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24243                 error "set default striped dir failed"
24244
24245         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24246         $LCTL set_param fail_loc=0x80000158
24247         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24248
24249         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24250         [ $stripe_index -eq 1 ] ||
24251                 error "expect 1 get $stripe_index for $dir"
24252 }
24253 run_test 300l "non-root user to create dir under striped dir with stale layout"
24254
24255 test_300m() {
24256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24257         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24258         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24259                 skip "Need MDS version at least 2.7.55"
24260
24261         mkdir -p $DIR/$tdir/striped_dir
24262         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24263                 error "set default stripes dir error"
24264
24265         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24266
24267         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24268         [ $stripe_count -eq 0 ] ||
24269                         error "expect 0 get $stripe_count for a"
24270
24271         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24272                 error "set default stripes dir error"
24273
24274         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24275
24276         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24277         [ $stripe_count -eq 0 ] ||
24278                         error "expect 0 get $stripe_count for b"
24279
24280         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24281                 error "set default stripes dir error"
24282
24283         mkdir $DIR/$tdir/striped_dir/c &&
24284                 error "default stripe_index is invalid, mkdir c should fails"
24285
24286         rm -rf $DIR/$tdir || error "rmdir fails"
24287 }
24288 run_test 300m "setstriped directory on single MDT FS"
24289
24290 cleanup_300n() {
24291         local list=$(comma_list $(mdts_nodes))
24292
24293         trap 0
24294         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24295 }
24296
24297 test_300n() {
24298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24300         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24301                 skip "Need MDS version at least 2.7.55"
24302         remote_mds_nodsh && skip "remote MDS with nodsh"
24303
24304         local stripe_index
24305         local list=$(comma_list $(mdts_nodes))
24306
24307         trap cleanup_300n RETURN EXIT
24308         mkdir -p $DIR/$tdir
24309         chmod 777 $DIR/$tdir
24310         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24311                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24312                 error "create striped dir succeeds with gid=0"
24313
24314         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24315         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24316                 error "create striped dir fails with gid=-1"
24317
24318         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24319         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24320                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24321                 error "set default striped dir succeeds with gid=0"
24322
24323
24324         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24325         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24326                 error "set default striped dir fails with gid=-1"
24327
24328
24329         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24330         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24331                                         error "create test_dir fails"
24332         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24333                                         error "create test_dir1 fails"
24334         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24335                                         error "create test_dir2 fails"
24336         cleanup_300n
24337 }
24338 run_test 300n "non-root user to create dir under striped dir with default EA"
24339
24340 test_300o() {
24341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24343         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24344                 skip "Need MDS version at least 2.7.55"
24345
24346         local numfree1
24347         local numfree2
24348
24349         mkdir -p $DIR/$tdir
24350
24351         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24352         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24353         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24354                 skip "not enough free inodes $numfree1 $numfree2"
24355         fi
24356
24357         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24358         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24359         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24360                 skip "not enough free space $numfree1 $numfree2"
24361         fi
24362
24363         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24364                 error "setdirstripe fails"
24365
24366         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24367                 error "create dirs fails"
24368
24369         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24370         ls $DIR/$tdir/striped_dir > /dev/null ||
24371                 error "ls striped dir fails"
24372         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24373                 error "unlink big striped dir fails"
24374 }
24375 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24376
24377 test_300p() {
24378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24380         remote_mds_nodsh && skip "remote MDS with nodsh"
24381
24382         mkdir_on_mdt0 $DIR/$tdir
24383
24384         #define OBD_FAIL_OUT_ENOSPC     0x1704
24385         do_facet mds2 lctl set_param fail_loc=0x80001704
24386         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24387                  && error "create striped directory should fail"
24388
24389         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24390
24391         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24392         true
24393 }
24394 run_test 300p "create striped directory without space"
24395
24396 test_300q() {
24397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24399
24400         local fd=$(free_fd)
24401         local cmd="exec $fd<$tdir"
24402         cd $DIR
24403         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24404         eval $cmd
24405         cmd="exec $fd<&-"
24406         trap "eval $cmd" EXIT
24407         cd $tdir || error "cd $tdir fails"
24408         rmdir  ../$tdir || error "rmdir $tdir fails"
24409         mkdir local_dir && error "create dir succeeds"
24410         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24411         eval $cmd
24412         return 0
24413 }
24414 run_test 300q "create remote directory under orphan directory"
24415
24416 test_300r() {
24417         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24418                 skip "Need MDS version at least 2.7.55" && return
24419         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24420
24421         mkdir $DIR/$tdir
24422
24423         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24424                 error "set striped dir error"
24425
24426         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24427                 error "getstripeddir fails"
24428
24429         local stripe_count
24430         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24431                       awk '/lmv_stripe_count:/ { print $2 }')
24432
24433         [ $MDSCOUNT -ne $stripe_count ] &&
24434                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24435
24436         rm -rf $DIR/$tdir/striped_dir ||
24437                 error "unlink striped dir fails"
24438 }
24439 run_test 300r "test -1 striped directory"
24440
24441 test_300s_helper() {
24442         local count=$1
24443
24444         local stripe_dir=$DIR/$tdir/striped_dir.$count
24445
24446         $LFS mkdir -c $count $stripe_dir ||
24447                 error "lfs mkdir -c error"
24448
24449         $LFS getdirstripe $stripe_dir ||
24450                 error "lfs getdirstripe fails"
24451
24452         local stripe_count
24453         stripe_count=$($LFS getdirstripe $stripe_dir |
24454                       awk '/lmv_stripe_count:/ { print $2 }')
24455
24456         [ $count -ne $stripe_count ] &&
24457                 error_noexit "bad stripe count $stripe_count expected $count"
24458
24459         local dupe_stripes
24460         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24461                 awk '/0x/ {count[$1] += 1}; END {
24462                         for (idx in count) {
24463                                 if (count[idx]>1) {
24464                                         print "index " idx " count " count[idx]
24465                                 }
24466                         }
24467                 }')
24468
24469         if [[ -n "$dupe_stripes" ]] ; then
24470                 lfs getdirstripe $stripe_dir
24471                 error_noexit "Dupe MDT above: $dupe_stripes "
24472         fi
24473
24474         rm -rf $stripe_dir ||
24475                 error_noexit "unlink $stripe_dir fails"
24476 }
24477
24478 test_300s() {
24479         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24480                 skip "Need MDS version at least 2.7.55" && return
24481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24482
24483         mkdir $DIR/$tdir
24484         for count in $(seq 2 $MDSCOUNT); do
24485                 test_300s_helper $count
24486         done
24487 }
24488 run_test 300s "test lfs mkdir -c without -i"
24489
24490 test_300t() {
24491         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24492                 skip "need MDS 2.14.55 or later"
24493         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24494
24495         local testdir="$DIR/$tdir/striped_dir"
24496         local dir1=$testdir/dir1
24497         local dir2=$testdir/dir2
24498
24499         mkdir -p $testdir
24500
24501         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24502                 error "failed to set default stripe count for $testdir"
24503
24504         mkdir $dir1
24505         local stripe_count=$($LFS getdirstripe -c $dir1)
24506
24507         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24508
24509         local max_count=$((MDSCOUNT - 1))
24510         local mdts=$(comma_list $(mdts_nodes))
24511
24512         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24513         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24514
24515         mkdir $dir2
24516         stripe_count=$($LFS getdirstripe -c $dir2)
24517
24518         (( $stripe_count == $max_count )) || error "wrong stripe count"
24519 }
24520 run_test 300t "test max_mdt_stripecount"
24521
24522 prepare_remote_file() {
24523         mkdir $DIR/$tdir/src_dir ||
24524                 error "create remote source failed"
24525
24526         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24527                  error "cp to remote source failed"
24528         touch $DIR/$tdir/src_dir/a
24529
24530         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24531                 error "create remote target dir failed"
24532
24533         touch $DIR/$tdir/tgt_dir/b
24534
24535         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24536                 error "rename dir cross MDT failed!"
24537
24538         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24539                 error "src_child still exists after rename"
24540
24541         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24542                 error "missing file(a) after rename"
24543
24544         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24545                 error "diff after rename"
24546 }
24547
24548 test_310a() {
24549         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24551
24552         local remote_file=$DIR/$tdir/tgt_dir/b
24553
24554         mkdir -p $DIR/$tdir
24555
24556         prepare_remote_file || error "prepare remote file failed"
24557
24558         #open-unlink file
24559         $OPENUNLINK $remote_file $remote_file ||
24560                 error "openunlink $remote_file failed"
24561         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24562 }
24563 run_test 310a "open unlink remote file"
24564
24565 test_310b() {
24566         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24568
24569         local remote_file=$DIR/$tdir/tgt_dir/b
24570
24571         mkdir -p $DIR/$tdir
24572
24573         prepare_remote_file || error "prepare remote file failed"
24574
24575         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24576         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24577         $CHECKSTAT -t file $remote_file || error "check file failed"
24578 }
24579 run_test 310b "unlink remote file with multiple links while open"
24580
24581 test_310c() {
24582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24583         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24584
24585         local remote_file=$DIR/$tdir/tgt_dir/b
24586
24587         mkdir -p $DIR/$tdir
24588
24589         prepare_remote_file || error "prepare remote file failed"
24590
24591         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24592         multiop_bg_pause $remote_file O_uc ||
24593                         error "mulitop failed for remote file"
24594         MULTIPID=$!
24595         $MULTIOP $DIR/$tfile Ouc
24596         kill -USR1 $MULTIPID
24597         wait $MULTIPID
24598 }
24599 run_test 310c "open-unlink remote file with multiple links"
24600
24601 #LU-4825
24602 test_311() {
24603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24604         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24605         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24606                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24607         remote_mds_nodsh && skip "remote MDS with nodsh"
24608
24609         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24610         local mdts=$(comma_list $(mdts_nodes))
24611
24612         mkdir -p $DIR/$tdir
24613         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24614         createmany -o $DIR/$tdir/$tfile. 1000
24615
24616         # statfs data is not real time, let's just calculate it
24617         old_iused=$((old_iused + 1000))
24618
24619         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24620                         osp.*OST0000*MDT0000.create_count")
24621         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24622                                 osp.*OST0000*MDT0000.max_create_count")
24623         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24624
24625         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24626         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24627         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24628
24629         unlinkmany $DIR/$tdir/$tfile. 1000
24630
24631         do_nodes $mdts "$LCTL set_param -n \
24632                         osp.*OST0000*.max_create_count=$max_count"
24633         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24634                 do_nodes $mdts "$LCTL set_param -n \
24635                                 osp.*OST0000*.create_count=$count"
24636         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24637                         grep "=0" && error "create_count is zero"
24638
24639         local new_iused
24640         for i in $(seq 120); do
24641                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24642                 # system may be too busy to destroy all objs in time, use
24643                 # a somewhat small value to not fail autotest
24644                 [ $((old_iused - new_iused)) -gt 400 ] && break
24645                 sleep 1
24646         done
24647
24648         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24649         [ $((old_iused - new_iused)) -gt 400 ] ||
24650                 error "objs not destroyed after unlink"
24651 }
24652 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24653
24654 zfs_oid_to_objid()
24655 {
24656         local ost=$1
24657         local objid=$2
24658
24659         local vdevdir=$(dirname $(facet_vdevice $ost))
24660         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24661         local zfs_zapid=$(do_facet $ost $cmd |
24662                           grep -w "/O/0/d$((objid%32))" -C 5 |
24663                           awk '/Object/{getline; print $1}')
24664         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24665                           awk "/$objid = /"'{printf $3}')
24666
24667         echo $zfs_objid
24668 }
24669
24670 zfs_object_blksz() {
24671         local ost=$1
24672         local objid=$2
24673
24674         local vdevdir=$(dirname $(facet_vdevice $ost))
24675         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24676         local blksz=$(do_facet $ost $cmd $objid |
24677                       awk '/dblk/{getline; printf $4}')
24678
24679         case "${blksz: -1}" in
24680                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24681                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24682                 *) ;;
24683         esac
24684
24685         echo $blksz
24686 }
24687
24688 test_312() { # LU-4856
24689         remote_ost_nodsh && skip "remote OST with nodsh"
24690         [ "$ost1_FSTYPE" = "zfs" ] ||
24691                 skip_env "the test only applies to zfs"
24692
24693         local max_blksz=$(do_facet ost1 \
24694                           $ZFS get -p recordsize $(facet_device ost1) |
24695                           awk '!/VALUE/{print $3}')
24696
24697         # to make life a little bit easier
24698         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24699         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24700
24701         local tf=$DIR/$tdir/$tfile
24702         touch $tf
24703         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24704
24705         # Get ZFS object id
24706         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24707         # block size change by sequential overwrite
24708         local bs
24709
24710         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24711                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24712
24713                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24714                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24715         done
24716         rm -f $tf
24717
24718         # block size change by sequential append write
24719         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24720         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24721         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24722         local count
24723
24724         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24725                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24726                         oflag=sync conv=notrunc
24727
24728                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24729                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24730                         error "blksz error, actual $blksz, " \
24731                                 "expected: 2 * $count * $PAGE_SIZE"
24732         done
24733         rm -f $tf
24734
24735         # random write
24736         touch $tf
24737         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24738         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24739
24740         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24741         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24742         [ $blksz -eq $PAGE_SIZE ] ||
24743                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24744
24745         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24746         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24747         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24748
24749         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24750         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24751         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24752 }
24753 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24754
24755 test_313() {
24756         remote_ost_nodsh && skip "remote OST with nodsh"
24757
24758         local file=$DIR/$tfile
24759
24760         rm -f $file
24761         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24762
24763         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24764         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24765         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24766                 error "write should failed"
24767         do_facet ost1 "$LCTL set_param fail_loc=0"
24768         rm -f $file
24769 }
24770 run_test 313 "io should fail after last_rcvd update fail"
24771
24772 test_314() {
24773         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24774
24775         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24776         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24777         rm -f $DIR/$tfile
24778         wait_delete_completed
24779         do_facet ost1 "$LCTL set_param fail_loc=0"
24780 }
24781 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24782
24783 test_315() { # LU-618
24784         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24785
24786         local file=$DIR/$tfile
24787         rm -f $file
24788
24789         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24790                 error "multiop file write failed"
24791         $MULTIOP $file oO_RDONLY:r4063232_c &
24792         PID=$!
24793
24794         sleep 2
24795
24796         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24797         kill -USR1 $PID
24798
24799         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24800         rm -f $file
24801 }
24802 run_test 315 "read should be accounted"
24803
24804 test_316() {
24805         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24806         large_xattr_enabled || skip "ea_inode feature disabled"
24807
24808         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24809         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24810         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24811         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24812
24813         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24814 }
24815 run_test 316 "lfs migrate of file with large_xattr enabled"
24816
24817 test_317() {
24818         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24819                 skip "Need MDS version at least 2.11.53"
24820         if [ "$ost1_FSTYPE" == "zfs" ]; then
24821                 skip "LU-10370: no implementation for ZFS"
24822         fi
24823
24824         local trunc_sz
24825         local grant_blk_size
24826
24827         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24828                         awk '/grant_block_size:/ { print $2; exit; }')
24829         #
24830         # Create File of size 5M. Truncate it to below size's and verify
24831         # blocks count.
24832         #
24833         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24834                 error "Create file $DIR/$tfile failed"
24835         stack_trap "rm -f $DIR/$tfile" EXIT
24836
24837         for trunc_sz in 2097152 4097 4000 509 0; do
24838                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24839                         error "truncate $tfile to $trunc_sz failed"
24840                 local sz=$(stat --format=%s $DIR/$tfile)
24841                 local blk=$(stat --format=%b $DIR/$tfile)
24842                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24843                                      grant_blk_size) * 8))
24844
24845                 if [[ $blk -ne $trunc_blk ]]; then
24846                         $(which stat) $DIR/$tfile
24847                         error "Expected Block $trunc_blk got $blk for $tfile"
24848                 fi
24849
24850                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24851                         error "Expected Size $trunc_sz got $sz for $tfile"
24852         done
24853
24854         #
24855         # sparse file test
24856         # Create file with a hole and write actual 65536 bytes which aligned
24857         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24858         #
24859         local bs=65536
24860         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24861                 error "Create file : $DIR/$tfile"
24862
24863         #
24864         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24865         # blocks. The block count must drop to 8.
24866         #
24867         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24868                 ((bs - grant_blk_size) + 1)))
24869         $TRUNCATE $DIR/$tfile $trunc_sz ||
24870                 error "truncate $tfile to $trunc_sz failed"
24871
24872         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24873         sz=$(stat --format=%s $DIR/$tfile)
24874         blk=$(stat --format=%b $DIR/$tfile)
24875
24876         if [[ $blk -ne $trunc_bsz ]]; then
24877                 $(which stat) $DIR/$tfile
24878                 error "Expected Block $trunc_bsz got $blk for $tfile"
24879         fi
24880
24881         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24882                 error "Expected Size $trunc_sz got $sz for $tfile"
24883 }
24884 run_test 317 "Verify blocks get correctly update after truncate"
24885
24886 test_318() {
24887         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24888         local old_max_active=$($LCTL get_param -n \
24889                             ${llite_name}.max_read_ahead_async_active \
24890                             2>/dev/null)
24891
24892         $LCTL set_param llite.*.max_read_ahead_async_active=256
24893         local max_active=$($LCTL get_param -n \
24894                            ${llite_name}.max_read_ahead_async_active \
24895                            2>/dev/null)
24896         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24897
24898         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24899                 error "set max_read_ahead_async_active should succeed"
24900
24901         $LCTL set_param llite.*.max_read_ahead_async_active=512
24902         max_active=$($LCTL get_param -n \
24903                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24904         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24905
24906         # restore @max_active
24907         [ $old_max_active -ne 0 ] && $LCTL set_param \
24908                 llite.*.max_read_ahead_async_active=$old_max_active
24909
24910         local old_threshold=$($LCTL get_param -n \
24911                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24912         local max_per_file_mb=$($LCTL get_param -n \
24913                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24914
24915         local invalid=$(($max_per_file_mb + 1))
24916         $LCTL set_param \
24917                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24918                         && error "set $invalid should fail"
24919
24920         local valid=$(($invalid - 1))
24921         $LCTL set_param \
24922                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24923                         error "set $valid should succeed"
24924         local threshold=$($LCTL get_param -n \
24925                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24926         [ $threshold -eq $valid ] || error \
24927                 "expect threshold $valid got $threshold"
24928         $LCTL set_param \
24929                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24930 }
24931 run_test 318 "Verify async readahead tunables"
24932
24933 test_319() {
24934         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24935
24936         local before=$(date +%s)
24937         local evict
24938         local mdir=$DIR/$tdir
24939         local file=$mdir/xxx
24940
24941         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24942         touch $file
24943
24944 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24945         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24946         $LFS migrate -m1 $mdir &
24947
24948         sleep 1
24949         dd if=$file of=/dev/null
24950         wait
24951         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24952           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24953
24954         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24955 }
24956 run_test 319 "lost lease lock on migrate error"
24957
24958 test_398a() { # LU-4198
24959         local ost1_imp=$(get_osc_import_name client ost1)
24960         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24961                          cut -d'.' -f2)
24962
24963         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24964         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24965
24966         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24967         # request a new lock on client
24968         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24969
24970         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24971         #local lock_count=$($LCTL get_param -n \
24972         #                  ldlm.namespaces.$imp_name.lru_size)
24973         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24974
24975         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24976
24977         # no lock cached, should use lockless DIO and not enqueue new lock
24978         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24979                 conv=notrunc ||
24980                 error "dio write failed"
24981         lock_count=$($LCTL get_param -n \
24982                      ldlm.namespaces.$imp_name.lru_size)
24983         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24984
24985         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24986
24987         # no lock cached, should use locked DIO append
24988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24989                 conv=notrunc || error "DIO append failed"
24990         lock_count=$($LCTL get_param -n \
24991                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24992         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24993 }
24994 run_test 398a "direct IO should cancel lock otherwise lockless"
24995
24996 test_398b() { # LU-4198
24997         which fio || skip_env "no fio installed"
24998         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24999
25000         local size=48
25001         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25002
25003         local njobs=4
25004         # Single page, multiple pages, stripe size, 4*stripe size
25005         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25006                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25007                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25008                         --numjobs=$njobs --fallocate=none \
25009                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25010                         --filename=$DIR/$tfile &
25011                 bg_pid=$!
25012
25013                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25014                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25015                         --numjobs=$njobs --fallocate=none \
25016                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25017                         --filename=$DIR/$tfile || true
25018                 wait $bg_pid
25019         done
25020
25021         evict=$(do_facet client $LCTL get_param \
25022                 osc.$FSNAME-OST*-osc-*/state |
25023             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25024
25025         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25026                 (do_facet client $LCTL get_param \
25027                         osc.$FSNAME-OST*-osc-*/state;
25028                     error "eviction happened: $evict before:$before")
25029
25030         rm -f $DIR/$tfile
25031 }
25032 run_test 398b "DIO and buffer IO race"
25033
25034 test_398c() { # LU-4198
25035         local ost1_imp=$(get_osc_import_name client ost1)
25036         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25037                          cut -d'.' -f2)
25038
25039         which fio || skip_env "no fio installed"
25040
25041         saved_debug=$($LCTL get_param -n debug)
25042         $LCTL set_param debug=0
25043
25044         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25045         ((size /= 1024)) # by megabytes
25046         ((size /= 2)) # write half of the OST at most
25047         [ $size -gt 40 ] && size=40 #reduce test time anyway
25048
25049         $LFS setstripe -c 1 $DIR/$tfile
25050
25051         # it seems like ldiskfs reserves more space than necessary if the
25052         # writing blocks are not mapped, so it extends the file firstly
25053         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25054         cancel_lru_locks osc
25055
25056         # clear and verify rpc_stats later
25057         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25058
25059         local njobs=4
25060         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25061         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25062                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25063                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25064                 --filename=$DIR/$tfile
25065         [ $? -eq 0 ] || error "fio write error"
25066
25067         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25068                 error "Locks were requested while doing AIO"
25069
25070         # get the percentage of 1-page I/O
25071         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25072                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25073                 awk '{print $7}')
25074         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25075
25076         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25077         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25078                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25079                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25080                 --filename=$DIR/$tfile
25081         [ $? -eq 0 ] || error "fio mixed read write error"
25082
25083         echo "AIO with large block size ${size}M"
25084         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25085                 --numjobs=1 --fallocate=none --ioengine=libaio \
25086                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25087                 --filename=$DIR/$tfile
25088         [ $? -eq 0 ] || error "fio large block size failed"
25089
25090         rm -f $DIR/$tfile
25091         $LCTL set_param debug="$saved_debug"
25092 }
25093 run_test 398c "run fio to test AIO"
25094
25095 test_398d() { #  LU-13846
25096         which aiocp || skip_env "no aiocp installed"
25097         local aio_file=$DIR/$tfile.aio
25098
25099         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25100
25101         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25102         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25103         stack_trap "rm -f $DIR/$tfile $aio_file"
25104
25105         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25106
25107         # make sure we don't crash and fail properly
25108         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25109                 error "aio not aligned with PAGE SIZE should fail"
25110
25111         rm -f $DIR/$tfile $aio_file
25112 }
25113 run_test 398d "run aiocp to verify block size > stripe size"
25114
25115 test_398e() {
25116         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25117         touch $DIR/$tfile.new
25118         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25119 }
25120 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25121
25122 test_398f() { #  LU-14687
25123         which aiocp || skip_env "no aiocp installed"
25124         local aio_file=$DIR/$tfile.aio
25125
25126         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25127
25128         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25129         stack_trap "rm -f $DIR/$tfile $aio_file"
25130
25131         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25132         $LCTL set_param fail_loc=0x1418
25133         # make sure we don't crash and fail properly
25134         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25135                 error "aio with page allocation failure succeeded"
25136         $LCTL set_param fail_loc=0
25137         diff $DIR/$tfile $aio_file
25138         [[ $? != 0 ]] || error "no diff after failed aiocp"
25139 }
25140 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25141
25142 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25143 # stripe and i/o size must be > stripe size
25144 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25145 # single RPC in flight.  This test shows async DIO submission is working by
25146 # showing multiple RPCs in flight.
25147 test_398g() { #  LU-13798
25148         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25149
25150         # We need to do some i/o first to acquire enough grant to put our RPCs
25151         # in flight; otherwise a new connection may not have enough grant
25152         # available
25153         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25154                 error "parallel dio failed"
25155         stack_trap "rm -f $DIR/$tfile"
25156
25157         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25158         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25159         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25160         stack_trap "$LCTL set_param -n $pages_per_rpc"
25161
25162         # Recreate file so it's empty
25163         rm -f $DIR/$tfile
25164         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25165         #Pause rpc completion to guarantee we see multiple rpcs in flight
25166         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25167         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25168         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25169
25170         # Clear rpc stats
25171         $LCTL set_param osc.*.rpc_stats=c
25172
25173         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25174                 error "parallel dio failed"
25175         stack_trap "rm -f $DIR/$tfile"
25176
25177         $LCTL get_param osc.*-OST0000-*.rpc_stats
25178         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25179                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25180                 grep "8:" | awk '{print $8}')
25181         # We look at the "8 rpcs in flight" field, and verify A) it is present
25182         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25183         # as expected for an 8M DIO to a file with 1M stripes.
25184         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25185
25186         # Verify turning off parallel dio works as expected
25187         # Clear rpc stats
25188         $LCTL set_param osc.*.rpc_stats=c
25189         $LCTL set_param llite.*.parallel_dio=0
25190         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25191
25192         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25193                 error "dio with parallel dio disabled failed"
25194
25195         # Ideally, we would see only one RPC in flight here, but there is an
25196         # unavoidable race between i/o completion and RPC in flight counting,
25197         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25198         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25199         # So instead we just verify it's always < 8.
25200         $LCTL get_param osc.*-OST0000-*.rpc_stats
25201         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25202                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25203                 grep '^$' -B1 | grep . | awk '{print $1}')
25204         [ $ret != "8:" ] ||
25205                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25206 }
25207 run_test 398g "verify parallel dio async RPC submission"
25208
25209 test_398h() { #  LU-13798
25210         local dio_file=$DIR/$tfile.dio
25211
25212         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25213
25214         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25215         stack_trap "rm -f $DIR/$tfile $dio_file"
25216
25217         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25218                 error "parallel dio failed"
25219         diff $DIR/$tfile $dio_file
25220         [[ $? == 0 ]] || error "file diff after aiocp"
25221 }
25222 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25223
25224 test_398i() { #  LU-13798
25225         local dio_file=$DIR/$tfile.dio
25226
25227         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25228
25229         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25230         stack_trap "rm -f $DIR/$tfile $dio_file"
25231
25232         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25233         $LCTL set_param fail_loc=0x1418
25234         # make sure we don't crash and fail properly
25235         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25236                 error "parallel dio page allocation failure succeeded"
25237         diff $DIR/$tfile $dio_file
25238         [[ $? != 0 ]] || error "no diff after failed aiocp"
25239 }
25240 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25241
25242 test_398j() { #  LU-13798
25243         # Stripe size > RPC size but less than i/o size tests split across
25244         # stripes and RPCs for individual i/o op
25245         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25246
25247         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25248         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25249         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25250         stack_trap "$LCTL set_param -n $pages_per_rpc"
25251
25252         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25253                 error "parallel dio write failed"
25254         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25255
25256         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25257                 error "parallel dio read failed"
25258         diff $DIR/$tfile $DIR/$tfile.2
25259         [[ $? == 0 ]] || error "file diff after parallel dio read"
25260 }
25261 run_test 398j "test parallel dio where stripe size > rpc_size"
25262
25263 test_398k() { #  LU-13798
25264         wait_delete_completed
25265         wait_mds_ost_sync
25266
25267         # 4 stripe file; we will cause out of space on OST0
25268         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25269
25270         # Fill OST0 (if it's not too large)
25271         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25272                    head -n1)
25273         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25274                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25275         fi
25276         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25277         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25278                 error "dd should fill OST0"
25279         stack_trap "rm -f $DIR/$tfile.1"
25280
25281         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25282         err=$?
25283
25284         ls -la $DIR/$tfile
25285         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25286                 error "file is not 0 bytes in size"
25287
25288         # dd above should not succeed, but don't error until here so we can
25289         # get debug info above
25290         [[ $err != 0 ]] ||
25291                 error "parallel dio write with enospc succeeded"
25292         stack_trap "rm -f $DIR/$tfile"
25293 }
25294 run_test 398k "test enospc on first stripe"
25295
25296 test_398l() { #  LU-13798
25297         wait_delete_completed
25298         wait_mds_ost_sync
25299
25300         # 4 stripe file; we will cause out of space on OST0
25301         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25302         # happens on the second i/o chunk we issue
25303         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25304
25305         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25306         stack_trap "rm -f $DIR/$tfile"
25307
25308         # Fill OST0 (if it's not too large)
25309         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25310                    head -n1)
25311         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25312                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25313         fi
25314         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25315         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25316                 error "dd should fill OST0"
25317         stack_trap "rm -f $DIR/$tfile.1"
25318
25319         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25320         err=$?
25321         stack_trap "rm -f $DIR/$tfile.2"
25322
25323         # Check that short write completed as expected
25324         ls -la $DIR/$tfile.2
25325         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25326                 error "file is not 1M in size"
25327
25328         # dd above should not succeed, but don't error until here so we can
25329         # get debug info above
25330         [[ $err != 0 ]] ||
25331                 error "parallel dio write with enospc succeeded"
25332
25333         # Truncate source file to same length as output file and diff them
25334         $TRUNCATE $DIR/$tfile 1048576
25335         diff $DIR/$tfile $DIR/$tfile.2
25336         [[ $? == 0 ]] || error "data incorrect after short write"
25337 }
25338 run_test 398l "test enospc on intermediate stripe/RPC"
25339
25340 test_398m() { #  LU-13798
25341         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25342
25343         # Set up failure on OST0, the first stripe:
25344         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25345         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25346         # OST0 is on ost1, OST1 is on ost2.
25347         # So this fail_val specifies OST0
25348         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25349         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25350
25351         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25352                 error "parallel dio write with failure on first stripe succeeded"
25353         stack_trap "rm -f $DIR/$tfile"
25354         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25355
25356         # Place data in file for read
25357         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25358                 error "parallel dio write failed"
25359
25360         # Fail read on OST0, first stripe
25361         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25362         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25363         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25364                 error "parallel dio read with error on first stripe succeeded"
25365         rm -f $DIR/$tfile.2
25366         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25367
25368         # Switch to testing on OST1, second stripe
25369         # Clear file contents, maintain striping
25370         echo > $DIR/$tfile
25371         # Set up failure on OST1, second stripe:
25372         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25373         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25374
25375         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25376                 error "parallel dio write with failure on second stripe succeeded"
25377         stack_trap "rm -f $DIR/$tfile"
25378         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25379
25380         # Place data in file for read
25381         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25382                 error "parallel dio write failed"
25383
25384         # Fail read on OST1, second stripe
25385         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25386         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25387         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25388                 error "parallel dio read with error on second stripe succeeded"
25389         rm -f $DIR/$tfile.2
25390         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25391 }
25392 run_test 398m "test RPC failures with parallel dio"
25393
25394 # Parallel submission of DIO should not cause problems for append, but it's
25395 # important to verify.
25396 test_398n() { #  LU-13798
25397         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25398
25399         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25400                 error "dd to create source file failed"
25401         stack_trap "rm -f $DIR/$tfile"
25402
25403         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25404                 error "parallel dio write with failure on second stripe succeeded"
25405         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25406         diff $DIR/$tfile $DIR/$tfile.1
25407         [[ $? == 0 ]] || error "data incorrect after append"
25408
25409 }
25410 run_test 398n "test append with parallel DIO"
25411
25412 test_398o() {
25413         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25414 }
25415 run_test 398o "right kms with DIO"
25416
25417 test_fake_rw() {
25418         local read_write=$1
25419         if [ "$read_write" = "write" ]; then
25420                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25421         elif [ "$read_write" = "read" ]; then
25422                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25423         else
25424                 error "argument error"
25425         fi
25426
25427         # turn off debug for performance testing
25428         local saved_debug=$($LCTL get_param -n debug)
25429         $LCTL set_param debug=0
25430
25431         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25432
25433         # get ost1 size - $FSNAME-OST0000
25434         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25435         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25436         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25437
25438         if [ "$read_write" = "read" ]; then
25439                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25440         fi
25441
25442         local start_time=$(date +%s.%N)
25443         $dd_cmd bs=1M count=$blocks oflag=sync ||
25444                 error "real dd $read_write error"
25445         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25446
25447         if [ "$read_write" = "write" ]; then
25448                 rm -f $DIR/$tfile
25449         fi
25450
25451         # define OBD_FAIL_OST_FAKE_RW           0x238
25452         do_facet ost1 $LCTL set_param fail_loc=0x238
25453
25454         local start_time=$(date +%s.%N)
25455         $dd_cmd bs=1M count=$blocks oflag=sync ||
25456                 error "fake dd $read_write error"
25457         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25458
25459         if [ "$read_write" = "write" ]; then
25460                 # verify file size
25461                 cancel_lru_locks osc
25462                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25463                         error "$tfile size not $blocks MB"
25464         fi
25465         do_facet ost1 $LCTL set_param fail_loc=0
25466
25467         echo "fake $read_write $duration_fake vs. normal $read_write" \
25468                 "$duration in seconds"
25469         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25470                 error_not_in_vm "fake write is slower"
25471
25472         $LCTL set_param -n debug="$saved_debug"
25473         rm -f $DIR/$tfile
25474 }
25475 test_399a() { # LU-7655 for OST fake write
25476         remote_ost_nodsh && skip "remote OST with nodsh"
25477
25478         test_fake_rw write
25479 }
25480 run_test 399a "fake write should not be slower than normal write"
25481
25482 test_399b() { # LU-8726 for OST fake read
25483         remote_ost_nodsh && skip "remote OST with nodsh"
25484         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25485                 skip_env "ldiskfs only test"
25486         fi
25487
25488         test_fake_rw read
25489 }
25490 run_test 399b "fake read should not be slower than normal read"
25491
25492 test_400a() { # LU-1606, was conf-sanity test_74
25493         if ! which $CC > /dev/null 2>&1; then
25494                 skip_env "$CC is not installed"
25495         fi
25496
25497         local extra_flags=''
25498         local out=$TMP/$tfile
25499         local prefix=/usr/include/lustre
25500         local prog
25501
25502         # Oleg removes .c files in his test rig so test if any c files exist
25503         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25504                 skip_env "Needed .c test files are missing"
25505
25506         if ! [[ -d $prefix ]]; then
25507                 # Assume we're running in tree and fixup the include path.
25508                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25509                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25510                 extra_flags+=" -L$LUSTRE/utils/.libs"
25511         fi
25512
25513         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25514                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25515                         error "client api broken"
25516         done
25517         rm -f $out
25518 }
25519 run_test 400a "Lustre client api program can compile and link"
25520
25521 test_400b() { # LU-1606, LU-5011
25522         local header
25523         local out=$TMP/$tfile
25524         local prefix=/usr/include/linux/lustre
25525
25526         # We use a hard coded prefix so that this test will not fail
25527         # when run in tree. There are headers in lustre/include/lustre/
25528         # that are not packaged (like lustre_idl.h) and have more
25529         # complicated include dependencies (like config.h and lnet/types.h).
25530         # Since this test about correct packaging we just skip them when
25531         # they don't exist (see below) rather than try to fixup cppflags.
25532
25533         if ! which $CC > /dev/null 2>&1; then
25534                 skip_env "$CC is not installed"
25535         fi
25536
25537         for header in $prefix/*.h; do
25538                 if ! [[ -f "$header" ]]; then
25539                         continue
25540                 fi
25541
25542                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25543                         continue # lustre_ioctl.h is internal header
25544                 fi
25545
25546                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25547                         error "cannot compile '$header'"
25548         done
25549         rm -f $out
25550 }
25551 run_test 400b "packaged headers can be compiled"
25552
25553 test_401a() { #LU-7437
25554         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25555         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25556
25557         #count the number of parameters by "list_param -R"
25558         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25559         #count the number of parameters by listing proc files
25560         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25561         echo "proc_dirs='$proc_dirs'"
25562         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25563         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25564                       sort -u | wc -l)
25565
25566         [ $params -eq $procs ] ||
25567                 error "found $params parameters vs. $procs proc files"
25568
25569         # test the list_param -D option only returns directories
25570         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25571         #count the number of parameters by listing proc directories
25572         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25573                 sort -u | wc -l)
25574
25575         [ $params -eq $procs ] ||
25576                 error "found $params parameters vs. $procs proc files"
25577 }
25578 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25579
25580 test_401b() {
25581         # jobid_var may not allow arbitrary values, so use jobid_name
25582         # if available
25583         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25584                 local testname=jobid_name tmp='testing%p'
25585         else
25586                 local testname=jobid_var tmp=testing
25587         fi
25588
25589         local save=$($LCTL get_param -n $testname)
25590
25591         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25592                 error "no error returned when setting bad parameters"
25593
25594         local jobid_new=$($LCTL get_param -n foe $testname baz)
25595         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25596
25597         $LCTL set_param -n fog=bam $testname=$save bat=fog
25598         local jobid_old=$($LCTL get_param -n foe $testname bag)
25599         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25600 }
25601 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25602
25603 test_401c() {
25604         # jobid_var may not allow arbitrary values, so use jobid_name
25605         # if available
25606         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25607                 local testname=jobid_name
25608         else
25609                 local testname=jobid_var
25610         fi
25611
25612         local jobid_var_old=$($LCTL get_param -n $testname)
25613         local jobid_var_new
25614
25615         $LCTL set_param $testname= &&
25616                 error "no error returned for 'set_param a='"
25617
25618         jobid_var_new=$($LCTL get_param -n $testname)
25619         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25620                 error "$testname was changed by setting without value"
25621
25622         $LCTL set_param $testname &&
25623                 error "no error returned for 'set_param a'"
25624
25625         jobid_var_new=$($LCTL get_param -n $testname)
25626         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25627                 error "$testname was changed by setting without value"
25628 }
25629 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25630
25631 test_401d() {
25632         # jobid_var may not allow arbitrary values, so use jobid_name
25633         # if available
25634         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25635                 local testname=jobid_name new_value='foo=bar%p'
25636         else
25637                 local testname=jobid_var new_valuie=foo=bar
25638         fi
25639
25640         local jobid_var_old=$($LCTL get_param -n $testname)
25641         local jobid_var_new
25642
25643         $LCTL set_param $testname=$new_value ||
25644                 error "'set_param a=b' did not accept a value containing '='"
25645
25646         jobid_var_new=$($LCTL get_param -n $testname)
25647         [[ "$jobid_var_new" == "$new_value" ]] ||
25648                 error "'set_param a=b' failed on a value containing '='"
25649
25650         # Reset the $testname to test the other format
25651         $LCTL set_param $testname=$jobid_var_old
25652         jobid_var_new=$($LCTL get_param -n $testname)
25653         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25654                 error "failed to reset $testname"
25655
25656         $LCTL set_param $testname $new_value ||
25657                 error "'set_param a b' did not accept a value containing '='"
25658
25659         jobid_var_new=$($LCTL get_param -n $testname)
25660         [[ "$jobid_var_new" == "$new_value" ]] ||
25661                 error "'set_param a b' failed on a value containing '='"
25662
25663         $LCTL set_param $testname $jobid_var_old
25664         jobid_var_new=$($LCTL get_param -n $testname)
25665         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25666                 error "failed to reset $testname"
25667 }
25668 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25669
25670 test_401e() { # LU-14779
25671         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25672                 error "lctl list_param MGC* failed"
25673         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25674         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25675                 error "lctl get_param lru_size failed"
25676 }
25677 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25678
25679 test_402() {
25680         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25681         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25682                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25683         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25684                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25685                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25686         remote_mds_nodsh && skip "remote MDS with nodsh"
25687
25688         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25689 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25690         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25691         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25692                 echo "Touch failed - OK"
25693 }
25694 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25695
25696 test_403() {
25697         local file1=$DIR/$tfile.1
25698         local file2=$DIR/$tfile.2
25699         local tfile=$TMP/$tfile
25700
25701         rm -f $file1 $file2 $tfile
25702
25703         touch $file1
25704         ln $file1 $file2
25705
25706         # 30 sec OBD_TIMEOUT in ll_getattr()
25707         # right before populating st_nlink
25708         $LCTL set_param fail_loc=0x80001409
25709         stat -c %h $file1 > $tfile &
25710
25711         # create an alias, drop all locks and reclaim the dentry
25712         < $file2
25713         cancel_lru_locks mdc
25714         cancel_lru_locks osc
25715         sysctl -w vm.drop_caches=2
25716
25717         wait
25718
25719         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25720
25721         rm -f $tfile $file1 $file2
25722 }
25723 run_test 403 "i_nlink should not drop to zero due to aliasing"
25724
25725 test_404() { # LU-6601
25726         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25727                 skip "Need server version newer than 2.8.52"
25728         remote_mds_nodsh && skip "remote MDS with nodsh"
25729
25730         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25731                 awk '/osp .*-osc-MDT/ { print $4}')
25732
25733         local osp
25734         for osp in $mosps; do
25735                 echo "Deactivate: " $osp
25736                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25737                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25738                         awk -vp=$osp '$4 == p { print $2 }')
25739                 [ $stat = IN ] || {
25740                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25741                         error "deactivate error"
25742                 }
25743                 echo "Activate: " $osp
25744                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25745                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25746                         awk -vp=$osp '$4 == p { print $2 }')
25747                 [ $stat = UP ] || {
25748                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25749                         error "activate error"
25750                 }
25751         done
25752 }
25753 run_test 404 "validate manual {de}activated works properly for OSPs"
25754
25755 test_405() {
25756         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25757         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25758                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25759                         skip "Layout swap lock is not supported"
25760
25761         check_swap_layouts_support
25762         check_swap_layout_no_dom $DIR
25763
25764         test_mkdir $DIR/$tdir
25765         swap_lock_test -d $DIR/$tdir ||
25766                 error "One layout swap locked test failed"
25767 }
25768 run_test 405 "Various layout swap lock tests"
25769
25770 test_406() {
25771         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25772         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25773         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25775         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25776                 skip "Need MDS version at least 2.8.50"
25777
25778         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25779         local test_pool=$TESTNAME
25780
25781         pool_add $test_pool || error "pool_add failed"
25782         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25783                 error "pool_add_targets failed"
25784
25785         save_layout_restore_at_exit $MOUNT
25786
25787         # parent set default stripe count only, child will stripe from both
25788         # parent and fs default
25789         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25790                 error "setstripe $MOUNT failed"
25791         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25792         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25793         for i in $(seq 10); do
25794                 local f=$DIR/$tdir/$tfile.$i
25795                 touch $f || error "touch failed"
25796                 local count=$($LFS getstripe -c $f)
25797                 [ $count -eq $OSTCOUNT ] ||
25798                         error "$f stripe count $count != $OSTCOUNT"
25799                 local offset=$($LFS getstripe -i $f)
25800                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25801                 local size=$($LFS getstripe -S $f)
25802                 [ $size -eq $((def_stripe_size * 2)) ] ||
25803                         error "$f stripe size $size != $((def_stripe_size * 2))"
25804                 local pool=$($LFS getstripe -p $f)
25805                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25806         done
25807
25808         # change fs default striping, delete parent default striping, now child
25809         # will stripe from new fs default striping only
25810         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25811                 error "change $MOUNT default stripe failed"
25812         $LFS setstripe -c 0 $DIR/$tdir ||
25813                 error "delete $tdir default stripe failed"
25814         for i in $(seq 11 20); do
25815                 local f=$DIR/$tdir/$tfile.$i
25816                 touch $f || error "touch $f failed"
25817                 local count=$($LFS getstripe -c $f)
25818                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25819                 local offset=$($LFS getstripe -i $f)
25820                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25821                 local size=$($LFS getstripe -S $f)
25822                 [ $size -eq $def_stripe_size ] ||
25823                         error "$f stripe size $size != $def_stripe_size"
25824                 local pool=$($LFS getstripe -p $f)
25825                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25826         done
25827
25828         unlinkmany $DIR/$tdir/$tfile. 1 20
25829
25830         local f=$DIR/$tdir/$tfile
25831         pool_remove_all_targets $test_pool $f
25832         pool_remove $test_pool $f
25833 }
25834 run_test 406 "DNE support fs default striping"
25835
25836 test_407() {
25837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25838         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25839                 skip "Need MDS version at least 2.8.55"
25840         remote_mds_nodsh && skip "remote MDS with nodsh"
25841
25842         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25843                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25844         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25845                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25846         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25847
25848         #define OBD_FAIL_DT_TXN_STOP    0x2019
25849         for idx in $(seq $MDSCOUNT); do
25850                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25851         done
25852         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25853         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25854                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25855         true
25856 }
25857 run_test 407 "transaction fail should cause operation fail"
25858
25859 test_408() {
25860         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25861
25862         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25863         lctl set_param fail_loc=0x8000040a
25864         # let ll_prepare_partial_page() fail
25865         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25866
25867         rm -f $DIR/$tfile
25868
25869         # create at least 100 unused inodes so that
25870         # shrink_icache_memory(0) should not return 0
25871         touch $DIR/$tfile-{0..100}
25872         rm -f $DIR/$tfile-{0..100}
25873         sync
25874
25875         echo 2 > /proc/sys/vm/drop_caches
25876 }
25877 run_test 408 "drop_caches should not hang due to page leaks"
25878
25879 test_409()
25880 {
25881         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25882
25883         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25884         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25885         touch $DIR/$tdir/guard || error "(2) Fail to create"
25886
25887         local PREFIX=$(str_repeat 'A' 128)
25888         echo "Create 1K hard links start at $(date)"
25889         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25890                 error "(3) Fail to hard link"
25891
25892         echo "Links count should be right although linkEA overflow"
25893         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25894         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25895         [ $linkcount -eq 1001 ] ||
25896                 error "(5) Unexpected hard links count: $linkcount"
25897
25898         echo "List all links start at $(date)"
25899         ls -l $DIR/$tdir/foo > /dev/null ||
25900                 error "(6) Fail to list $DIR/$tdir/foo"
25901
25902         echo "Unlink hard links start at $(date)"
25903         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25904                 error "(7) Fail to unlink"
25905         echo "Unlink hard links finished at $(date)"
25906 }
25907 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25908
25909 test_410()
25910 {
25911         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25912                 skip "Need client version at least 2.9.59"
25913         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25914                 skip "Need MODULES build"
25915
25916         # Create a file, and stat it from the kernel
25917         local testfile=$DIR/$tfile
25918         touch $testfile
25919
25920         local run_id=$RANDOM
25921         local my_ino=$(stat --format "%i" $testfile)
25922
25923         # Try to insert the module. This will always fail as the
25924         # module is designed to not be inserted.
25925         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25926             &> /dev/null
25927
25928         # Anything but success is a test failure
25929         dmesg | grep -q \
25930             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25931             error "no inode match"
25932 }
25933 run_test 410 "Test inode number returned from kernel thread"
25934
25935 cleanup_test411_cgroup() {
25936         trap 0
25937         rmdir "$1"
25938 }
25939
25940 test_411() {
25941         local cg_basedir=/sys/fs/cgroup/memory
25942         # LU-9966
25943         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25944                 skip "no setup for cgroup"
25945
25946         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25947                 error "test file creation failed"
25948         cancel_lru_locks osc
25949
25950         # Create a very small memory cgroup to force a slab allocation error
25951         local cgdir=$cg_basedir/osc_slab_alloc
25952         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25953         trap "cleanup_test411_cgroup $cgdir" EXIT
25954         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25955         echo 1M > $cgdir/memory.limit_in_bytes
25956
25957         # Should not LBUG, just be killed by oom-killer
25958         # dd will return 0 even allocation failure in some environment.
25959         # So don't check return value
25960         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25961         cleanup_test411_cgroup $cgdir
25962
25963         return 0
25964 }
25965 run_test 411 "Slab allocation error with cgroup does not LBUG"
25966
25967 test_412() {
25968         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25969         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25970                 skip "Need server version at least 2.10.55"
25971
25972         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25973                 error "mkdir failed"
25974         $LFS getdirstripe $DIR/$tdir
25975         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25976         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25977                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25978         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25979         [ $stripe_count -eq 2 ] ||
25980                 error "expect 2 get $stripe_count"
25981
25982         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25983
25984         local index
25985         local index2
25986
25987         # subdirs should be on the same MDT as parent
25988         for i in $(seq 0 $((MDSCOUNT - 1))); do
25989                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25990                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25991                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25992                 (( index == i )) || error "mdt$i/sub on MDT$index"
25993         done
25994
25995         # stripe offset -1, ditto
25996         for i in {1..10}; do
25997                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25998                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25999                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26000                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26001                 (( index == index2 )) ||
26002                         error "qos$i on MDT$index, sub on MDT$index2"
26003         done
26004
26005         local testdir=$DIR/$tdir/inherit
26006
26007         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26008         # inherit 2 levels
26009         for i in 1 2; do
26010                 testdir=$testdir/s$i
26011                 mkdir $testdir || error "mkdir $testdir failed"
26012                 index=$($LFS getstripe -m $testdir)
26013                 (( index == 1 )) ||
26014                         error "$testdir on MDT$index"
26015         done
26016
26017         # not inherit any more
26018         testdir=$testdir/s3
26019         mkdir $testdir || error "mkdir $testdir failed"
26020         getfattr -d -m dmv $testdir | grep dmv &&
26021                 error "default LMV set on $testdir" || true
26022 }
26023 run_test 412 "mkdir on specific MDTs"
26024
26025 TEST413_COUNT=${TEST413_COUNT:-200}
26026 generate_uneven_mdts() {
26027         local threshold=$1
26028         local lmv_qos_maxage
26029         local lod_qos_maxage
26030         local ffree
26031         local bavail
26032         local max
26033         local min
26034         local max_index
26035         local min_index
26036         local tmp
26037         local i
26038
26039         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26040         $LCTL set_param lmv.*.qos_maxage=1
26041         stack_trap "$LCTL set_param \
26042                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26043         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26044                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26045         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26046                 lod.*.mdt_qos_maxage=1
26047         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26048                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26049
26050         echo
26051         echo "Check for uneven MDTs: "
26052
26053         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26054         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26055         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26056
26057         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26058         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26059         max_index=0
26060         min_index=0
26061         for ((i = 1; i < ${#ffree[@]}; i++)); do
26062                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26063                 if [ $tmp -gt $max ]; then
26064                         max=$tmp
26065                         max_index=$i
26066                 fi
26067                 if [ $tmp -lt $min ]; then
26068                         min=$tmp
26069                         min_index=$i
26070                 fi
26071         done
26072
26073         (( ${ffree[min_index]} > 0 )) ||
26074                 skip "no free files in MDT$min_index"
26075         (( ${ffree[min_index]} < 10000000 )) ||
26076                 skip "too many free files in MDT$min_index"
26077
26078         # Check if we need to generate uneven MDTs
26079         local diff=$(((max - min) * 100 / min))
26080         local testdir=$DIR/$tdir-fillmdt
26081         local start
26082
26083         i=0
26084         while (( diff < threshold )); do
26085                 mkdir -p $testdir
26086                 # generate uneven MDTs, create till $threshold% diff
26087                 echo -n "weight diff=$diff% must be > $threshold% ..."
26088                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26089                 testdir=$DIR/$tdir-fillmdt/$i
26090                 [ -d $testdir ] && continue
26091                 $LFS mkdir -i $min_index $testdir ||
26092                         error "mkdir $testdir failed"
26093                 $LFS setstripe -E 1M -L mdt $testdir ||
26094                         error "setstripe $testdir failed"
26095                 start=$SECONDS
26096                 for ((F=0; F < TEST413_COUNT; F++)); do
26097                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26098                                 /dev/null 2>&1 || error "dd $F failed"
26099                 done
26100                 sync; sleep 1; sync
26101
26102                 # wait for QOS to update
26103                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26104
26105                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26106                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26107                 max=$(((${ffree[max_index]} >> 8) *
26108                         (${bavail[max_index]} * bsize >> 16)))
26109                 min=$(((${ffree[min_index]} >> 8) *
26110                         (${bavail[min_index]} * bsize >> 16)))
26111                 diff=$(((max - min) * 100 / min))
26112                 i=$((i + 1))
26113         done
26114
26115         echo "MDT filesfree available: ${ffree[*]}"
26116         echo "MDT blocks available: ${bavail[*]}"
26117         echo "weight diff=$diff%"
26118 }
26119
26120 test_qos_mkdir() {
26121         local mkdir_cmd=$1
26122         local stripe_count=$2
26123         local mdts=$(comma_list $(mdts_nodes))
26124
26125         local testdir
26126         local lmv_qos_prio_free
26127         local lmv_qos_threshold_rr
26128         local lmv_qos_maxage
26129         local lod_qos_prio_free
26130         local lod_qos_threshold_rr
26131         local lod_qos_maxage
26132         local count
26133         local i
26134
26135         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26136         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26137         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26138                 head -n1)
26139         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26140         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26141         stack_trap "$LCTL set_param \
26142                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26143         stack_trap "$LCTL set_param \
26144                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26145         stack_trap "$LCTL set_param \
26146                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26147
26148         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26149                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26150         lod_qos_prio_free=${lod_qos_prio_free%%%}
26151         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26152                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26153         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26154         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26155                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26156         stack_trap "do_nodes $mdts $LCTL set_param \
26157                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26158         stack_trap "do_nodes $mdts $LCTL set_param \
26159                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26160         stack_trap "do_nodes $mdts $LCTL set_param \
26161                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26162
26163         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26164         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26165
26166         testdir=$DIR/$tdir-s$stripe_count/rr
26167
26168         local stripe_index=$($LFS getstripe -m $testdir)
26169         local test_mkdir_rr=true
26170
26171         getfattr -d -m dmv -e hex $testdir | grep dmv
26172         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26173                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26174                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26175                         test_mkdir_rr=false
26176         fi
26177
26178         echo
26179         $test_mkdir_rr &&
26180                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26181                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26182
26183         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26184         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26185                 eval $mkdir_cmd $testdir/subdir$i ||
26186                         error "$mkdir_cmd subdir$i failed"
26187         done
26188
26189         for (( i = 0; i < $MDSCOUNT; i++ )); do
26190                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26191                 echo "$count directories created on MDT$i"
26192                 if $test_mkdir_rr; then
26193                         (( $count == 100 )) ||
26194                                 error "subdirs are not evenly distributed"
26195                 elif (( $i == $stripe_index )); then
26196                         (( $count == 100 * MDSCOUNT )) ||
26197                                 error "$count subdirs created on MDT$i"
26198                 else
26199                         (( $count == 0 )) ||
26200                                 error "$count subdirs created on MDT$i"
26201                 fi
26202
26203                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26204                         count=$($LFS getdirstripe $testdir/* |
26205                                 grep -c -P "^\s+$i\t")
26206                         echo "$count stripes created on MDT$i"
26207                         # deviation should < 5% of average
26208                         (( $count >= 95 * stripe_count &&
26209                            $count <= 105 * stripe_count)) ||
26210                                 error "stripes are not evenly distributed"
26211                 fi
26212         done
26213
26214         echo
26215         echo "Check for uneven MDTs: "
26216
26217         local ffree
26218         local bavail
26219         local max
26220         local min
26221         local max_index
26222         local min_index
26223         local tmp
26224
26225         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26226         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26227         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26228
26229         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26230         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26231         max_index=0
26232         min_index=0
26233         for ((i = 1; i < ${#ffree[@]}; i++)); do
26234                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26235                 if [ $tmp -gt $max ]; then
26236                         max=$tmp
26237                         max_index=$i
26238                 fi
26239                 if [ $tmp -lt $min ]; then
26240                         min=$tmp
26241                         min_index=$i
26242                 fi
26243         done
26244
26245         (( ${ffree[min_index]} > 0 )) ||
26246                 skip "no free files in MDT$min_index"
26247         (( ${ffree[min_index]} < 10000000 )) ||
26248                 skip "too many free files in MDT$min_index"
26249
26250         echo "MDT filesfree available: ${ffree[*]}"
26251         echo "MDT blocks available: ${bavail[*]}"
26252         echo "weight diff=$(((max - min) * 100 / min))%"
26253         echo
26254         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26255
26256         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26257         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26258         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26259         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26260         # decrease statfs age, so that it can be updated in time
26261         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26262         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26263
26264         sleep 1
26265
26266         testdir=$DIR/$tdir-s$stripe_count/qos
26267         local num=200
26268
26269         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26270         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26271                 eval $mkdir_cmd $testdir/subdir$i ||
26272                         error "$mkdir_cmd subdir$i failed"
26273         done
26274
26275         max=0
26276         for (( i = 0; i < $MDSCOUNT; i++ )); do
26277                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26278                 (( count > max )) && max=$count
26279                 echo "$count directories created on MDT$i"
26280         done
26281
26282         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26283
26284         # D-value should > 10% of averge
26285         (( max - min > num / 10 )) ||
26286                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26287
26288         # ditto for stripes
26289         if (( stripe_count > 1 )); then
26290                 max=0
26291                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26292                         count=$($LFS getdirstripe $testdir/* |
26293                                 grep -c -P "^\s+$i\t")
26294                         (( count > max )) && max=$count
26295                         echo "$count stripes created on MDT$i"
26296                 done
26297
26298                 min=$($LFS getdirstripe $testdir/* |
26299                         grep -c -P "^\s+$min_index\t")
26300                 (( max - min > num * stripe_count / 10 )) ||
26301                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26302         fi
26303 }
26304
26305 most_full_mdt() {
26306         local ffree
26307         local bavail
26308         local bsize
26309         local min
26310         local min_index
26311         local tmp
26312
26313         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26314         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26315         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26316
26317         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26318         min_index=0
26319         for ((i = 1; i < ${#ffree[@]}; i++)); do
26320                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26321                 (( tmp < min )) && min=$tmp && min_index=$i
26322         done
26323
26324         echo -n $min_index
26325 }
26326
26327 test_413a() {
26328         [ $MDSCOUNT -lt 2 ] &&
26329                 skip "We need at least 2 MDTs for this test"
26330
26331         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26332                 skip "Need server version at least 2.12.52"
26333
26334         local stripe_count
26335
26336         generate_uneven_mdts 100
26337         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26338                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26339                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26340                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26341                         error "mkdir failed"
26342                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26343         done
26344 }
26345 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26346
26347 test_413b() {
26348         [ $MDSCOUNT -lt 2 ] &&
26349                 skip "We need at least 2 MDTs for this test"
26350
26351         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26352                 skip "Need server version at least 2.12.52"
26353
26354         local testdir
26355         local stripe_count
26356
26357         generate_uneven_mdts 100
26358         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26359                 testdir=$DIR/$tdir-s$stripe_count
26360                 mkdir $testdir || error "mkdir $testdir failed"
26361                 mkdir $testdir/rr || error "mkdir rr failed"
26362                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26363                         error "mkdir qos failed"
26364                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26365                         $testdir/rr || error "setdirstripe rr failed"
26366                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26367                         error "setdirstripe failed"
26368                 test_qos_mkdir "mkdir" $stripe_count
26369         done
26370 }
26371 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26372
26373 test_413c() {
26374         (( $MDSCOUNT >= 2 )) ||
26375                 skip "We need at least 2 MDTs for this test"
26376
26377         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26378                 skip "Need server version at least 2.14.51"
26379
26380         local testdir
26381         local inherit
26382         local inherit_rr
26383
26384         testdir=$DIR/${tdir}-s1
26385         mkdir $testdir || error "mkdir $testdir failed"
26386         mkdir $testdir/rr || error "mkdir rr failed"
26387         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26388         # default max_inherit is -1, default max_inherit_rr is 0
26389         $LFS setdirstripe -D -c 1 $testdir/rr ||
26390                 error "setdirstripe rr failed"
26391         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26392                 error "setdirstripe qos failed"
26393         test_qos_mkdir "mkdir" 1
26394
26395         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26396         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26397         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26398         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26399         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26400
26401         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26402         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26403         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26404         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26405         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26406         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26407         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26408                 error "level2 shouldn't have default LMV" || true
26409 }
26410 run_test 413c "mkdir with default LMV max inherit rr"
26411
26412 test_413d() {
26413         (( MDSCOUNT >= 2 )) ||
26414                 skip "We need at least 2 MDTs for this test"
26415
26416         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26417                 skip "Need server version at least 2.14.51"
26418
26419         local lmv_qos_threshold_rr
26420
26421         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26422                 head -n1)
26423         stack_trap "$LCTL set_param \
26424                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26425
26426         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26427         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26428         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26429                 error "$tdir shouldn't have default LMV"
26430         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26431                 error "mkdir sub failed"
26432
26433         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26434
26435         (( count == 100 )) || error "$count subdirs on MDT0"
26436 }
26437 run_test 413d "inherit ROOT default LMV"
26438
26439 test_413e() {
26440         (( MDSCOUNT >= 2 )) ||
26441                 skip "We need at least 2 MDTs for this test"
26442         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26443                 skip "Need server version at least 2.14.55"
26444
26445         local testdir=$DIR/$tdir
26446         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26447         local max_inherit
26448         local sub_max_inherit
26449
26450         mkdir -p $testdir || error "failed to create $testdir"
26451
26452         # set default max-inherit to -1 if stripe count is 0 or 1
26453         $LFS setdirstripe -D -c 1 $testdir ||
26454                 error "failed to set default LMV"
26455         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26456         (( max_inherit == -1 )) ||
26457                 error "wrong max_inherit value $max_inherit"
26458
26459         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26460         $LFS setdirstripe -D -c -1 $testdir ||
26461                 error "failed to set default LMV"
26462         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26463         (( max_inherit > 0 )) ||
26464                 error "wrong max_inherit value $max_inherit"
26465
26466         # and the subdir will decrease the max_inherit by 1
26467         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26468         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26469         (( sub_max_inherit == max_inherit - 1)) ||
26470                 error "wrong max-inherit of subdir $sub_max_inherit"
26471
26472         # check specified --max-inherit and warning message
26473         stack_trap "rm -f $tmpfile"
26474         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26475                 error "failed to set default LMV"
26476         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26477         (( max_inherit == -1 )) ||
26478                 error "wrong max_inherit value $max_inherit"
26479
26480         # check the warning messages
26481         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26482                 error "failed to detect warning string"
26483         fi
26484 }
26485 run_test 413e "check default max-inherit value"
26486
26487 test_fs_dmv_inherit()
26488 {
26489         local testdir=$DIR/$tdir
26490
26491         local count
26492         local inherit
26493         local inherit_rr
26494
26495         for i in 1 2 3; do
26496                 mkdir $testdir || error "mkdir $testdir failed"
26497                 count=$($LFS getdirstripe -D -c $testdir)
26498                 (( count == 1 )) ||
26499                         error "$testdir default LMV count mismatch $count != 1"
26500                 inherit=$($LFS getdirstripe -D -X $testdir)
26501                 (( inherit == 3 - i )) ||
26502                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26503                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26504                 (( inherit_rr == 3 - i )) ||
26505                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26506                 testdir=$testdir/sub
26507         done
26508
26509         mkdir $testdir || error "mkdir $testdir failed"
26510         count=$($LFS getdirstripe -D -c $testdir)
26511         (( count == 0 )) ||
26512                 error "$testdir default LMV count not zero: $count"
26513 }
26514
26515 test_413f() {
26516         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26517
26518         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26519                 skip "Need server version at least 2.14.55"
26520
26521         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26522                 error "dump $DIR default LMV failed"
26523         stack_trap "setfattr --restore=$TMP/dmv.ea"
26524
26525         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26526                 error "set $DIR default LMV failed"
26527
26528         test_fs_dmv_inherit
26529 }
26530 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26531
26532 test_413g() {
26533         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26534
26535         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26536         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26537                 error "dump $DIR default LMV failed"
26538         stack_trap "setfattr --restore=$TMP/dmv.ea"
26539
26540         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26541                 error "set $DIR default LMV failed"
26542
26543         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26544                 error "mount $MOUNT2 failed"
26545         stack_trap "umount_client $MOUNT2"
26546
26547         local saved_DIR=$DIR
26548
26549         export DIR=$MOUNT2
26550
26551         stack_trap "export DIR=$saved_DIR"
26552
26553         # first check filesystem-wide default LMV inheritance
26554         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26555
26556         # then check subdirs are spread to all MDTs
26557         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26558
26559         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26560
26561         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26562 }
26563 run_test 413g "enforce ROOT default LMV on subdir mount"
26564
26565 test_413h() {
26566         (( MDSCOUNT >= 2 )) ||
26567                 skip "We need at least 2 MDTs for this test"
26568
26569         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26570                 skip "Need server version at least 2.15.50.6"
26571
26572         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26573
26574         stack_trap "$LCTL set_param \
26575                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26576         $LCTL set_param lmv.*.qos_maxage=1
26577
26578         local depth=5
26579         local rr_depth=4
26580         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26581         local count=$((MDSCOUNT * 20))
26582
26583         generate_uneven_mdts 50
26584
26585         mkdir -p $dir || error "mkdir $dir failed"
26586         stack_trap "rm -rf $dir"
26587         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26588                 --max-inherit-rr=$rr_depth $dir
26589
26590         for ((d=0; d < depth + 2; d++)); do
26591                 log "dir=$dir:"
26592                 for ((sub=0; sub < count; sub++)); do
26593                         mkdir $dir/d$sub
26594                 done
26595                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26596                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26597                 # subdirs within $rr_depth should be created round-robin
26598                 if (( d < rr_depth )); then
26599                         (( ${num[0]} != count )) ||
26600                                 error "all objects created on MDT ${num[1]}"
26601                 fi
26602
26603                 dir=$dir/d0
26604         done
26605 }
26606 run_test 413h "don't stick to parent for round-robin dirs"
26607
26608 test_413z() {
26609         local pids=""
26610         local subdir
26611         local pid
26612
26613         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26614                 unlinkmany $subdir/f. $TEST413_COUNT &
26615                 pids="$pids $!"
26616         done
26617
26618         for pid in $pids; do
26619                 wait $pid
26620         done
26621 }
26622 run_test 413z "413 test cleanup"
26623
26624 test_414() {
26625 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26626         $LCTL set_param fail_loc=0x80000521
26627         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26628         rm -f $DIR/$tfile
26629 }
26630 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26631
26632 test_415() {
26633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26634         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26635                 skip "Need server version at least 2.11.52"
26636
26637         # LU-11102
26638         local total
26639         local setattr_pid
26640         local start_time
26641         local end_time
26642         local duration
26643
26644         total=500
26645         # this test may be slow on ZFS
26646         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26647
26648         # though this test is designed for striped directory, let's test normal
26649         # directory too since lock is always saved as CoS lock.
26650         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26651         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26652
26653         (
26654                 while true; do
26655                         touch $DIR/$tdir
26656                 done
26657         ) &
26658         setattr_pid=$!
26659
26660         start_time=$(date +%s)
26661         for i in $(seq $total); do
26662                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26663                         > /dev/null
26664         done
26665         end_time=$(date +%s)
26666         duration=$((end_time - start_time))
26667
26668         kill -9 $setattr_pid
26669
26670         echo "rename $total files took $duration sec"
26671         [ $duration -lt 100 ] || error "rename took $duration sec"
26672 }
26673 run_test 415 "lock revoke is not missing"
26674
26675 test_416() {
26676         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26677                 skip "Need server version at least 2.11.55"
26678
26679         # define OBD_FAIL_OSD_TXN_START    0x19a
26680         do_facet mds1 lctl set_param fail_loc=0x19a
26681
26682         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26683
26684         true
26685 }
26686 run_test 416 "transaction start failure won't cause system hung"
26687
26688 cleanup_417() {
26689         trap 0
26690         do_nodes $(comma_list $(mdts_nodes)) \
26691                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26692         do_nodes $(comma_list $(mdts_nodes)) \
26693                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26694         do_nodes $(comma_list $(mdts_nodes)) \
26695                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26696 }
26697
26698 test_417() {
26699         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26700         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26701                 skip "Need MDS version at least 2.11.56"
26702
26703         trap cleanup_417 RETURN EXIT
26704
26705         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26706         do_nodes $(comma_list $(mdts_nodes)) \
26707                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26708         $LFS migrate -m 0 $DIR/$tdir.1 &&
26709                 error "migrate dir $tdir.1 should fail"
26710
26711         do_nodes $(comma_list $(mdts_nodes)) \
26712                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26713         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26714                 error "create remote dir $tdir.2 should fail"
26715
26716         do_nodes $(comma_list $(mdts_nodes)) \
26717                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26718         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26719                 error "create striped dir $tdir.3 should fail"
26720         true
26721 }
26722 run_test 417 "disable remote dir, striped dir and dir migration"
26723
26724 # Checks that the outputs of df [-i] and lfs df [-i] match
26725 #
26726 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26727 check_lfs_df() {
26728         local dir=$2
26729         local inodes
26730         local df_out
26731         local lfs_df_out
26732         local count
26733         local passed=false
26734
26735         # blocks or inodes
26736         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26737
26738         for count in {1..100}; do
26739                 do_nodes "$CLIENTS" \
26740                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26741                 sync; sleep 0.2
26742
26743                 # read the lines of interest
26744                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26745                         error "df $inodes $dir | tail -n +2 failed"
26746                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26747                         error "lfs df $inodes $dir | grep summary: failed"
26748
26749                 # skip first substrings of each output as they are different
26750                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26751                 # compare the two outputs
26752                 passed=true
26753                 #  skip "available" on MDT until LU-13997 is fixed.
26754                 #for i in {1..5}; do
26755                 for i in 1 2 4 5; do
26756                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26757                 done
26758                 $passed && break
26759         done
26760
26761         if ! $passed; then
26762                 df -P $inodes $dir
26763                 echo
26764                 lfs df $inodes $dir
26765                 error "df and lfs df $1 output mismatch: "      \
26766                       "df ${inodes}: ${df_out[*]}, "            \
26767                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26768         fi
26769 }
26770
26771 test_418() {
26772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26773
26774         local dir=$DIR/$tdir
26775         local numfiles=$((RANDOM % 4096 + 2))
26776         local numblocks=$((RANDOM % 256 + 1))
26777
26778         wait_delete_completed
26779         test_mkdir $dir
26780
26781         # check block output
26782         check_lfs_df blocks $dir
26783         # check inode output
26784         check_lfs_df inodes $dir
26785
26786         # create a single file and retest
26787         echo "Creating a single file and testing"
26788         createmany -o $dir/$tfile- 1 &>/dev/null ||
26789                 error "creating 1 file in $dir failed"
26790         check_lfs_df blocks $dir
26791         check_lfs_df inodes $dir
26792
26793         # create a random number of files
26794         echo "Creating $((numfiles - 1)) files and testing"
26795         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26796                 error "creating $((numfiles - 1)) files in $dir failed"
26797
26798         # write a random number of blocks to the first test file
26799         echo "Writing $numblocks 4K blocks and testing"
26800         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26801                 count=$numblocks &>/dev/null ||
26802                 error "dd to $dir/${tfile}-0 failed"
26803
26804         # retest
26805         check_lfs_df blocks $dir
26806         check_lfs_df inodes $dir
26807
26808         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26809                 error "unlinking $numfiles files in $dir failed"
26810 }
26811 run_test 418 "df and lfs df outputs match"
26812
26813 test_419()
26814 {
26815         local dir=$DIR/$tdir
26816
26817         mkdir -p $dir
26818         touch $dir/file
26819
26820         cancel_lru_locks mdc
26821
26822         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26823         $LCTL set_param fail_loc=0x1410
26824         cat $dir/file
26825         $LCTL set_param fail_loc=0
26826         rm -rf $dir
26827 }
26828 run_test 419 "Verify open file by name doesn't crash kernel"
26829
26830 test_420()
26831 {
26832         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26833                 skip "Need MDS version at least 2.12.53"
26834
26835         local SAVE_UMASK=$(umask)
26836         local dir=$DIR/$tdir
26837         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26838
26839         mkdir -p $dir
26840         umask 0000
26841         mkdir -m03777 $dir/testdir
26842         ls -dn $dir/testdir
26843         # Need to remove trailing '.' when SELinux is enabled
26844         local dirperms=$(ls -dn $dir/testdir |
26845                          awk '{ sub(/\.$/, "", $1); print $1}')
26846         [ $dirperms == "drwxrwsrwt" ] ||
26847                 error "incorrect perms on $dir/testdir"
26848
26849         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26850                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26851         ls -n $dir/testdir/testfile
26852         local fileperms=$(ls -n $dir/testdir/testfile |
26853                           awk '{ sub(/\.$/, "", $1); print $1}')
26854         [ $fileperms == "-rwxr-xr-x" ] ||
26855                 error "incorrect perms on $dir/testdir/testfile"
26856
26857         umask $SAVE_UMASK
26858 }
26859 run_test 420 "clear SGID bit on non-directories for non-members"
26860
26861 test_421a() {
26862         local cnt
26863         local fid1
26864         local fid2
26865
26866         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26867                 skip "Need MDS version at least 2.12.54"
26868
26869         test_mkdir $DIR/$tdir
26870         createmany -o $DIR/$tdir/f 3
26871         cnt=$(ls -1 $DIR/$tdir | wc -l)
26872         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26873
26874         fid1=$(lfs path2fid $DIR/$tdir/f1)
26875         fid2=$(lfs path2fid $DIR/$tdir/f2)
26876         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26877
26878         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26879         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26880
26881         cnt=$(ls -1 $DIR/$tdir | wc -l)
26882         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26883
26884         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26885         createmany -o $DIR/$tdir/f 3
26886         cnt=$(ls -1 $DIR/$tdir | wc -l)
26887         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26888
26889         fid1=$(lfs path2fid $DIR/$tdir/f1)
26890         fid2=$(lfs path2fid $DIR/$tdir/f2)
26891         echo "remove using fsname $FSNAME"
26892         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26893
26894         cnt=$(ls -1 $DIR/$tdir | wc -l)
26895         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26896 }
26897 run_test 421a "simple rm by fid"
26898
26899 test_421b() {
26900         local cnt
26901         local FID1
26902         local FID2
26903
26904         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26905                 skip "Need MDS version at least 2.12.54"
26906
26907         test_mkdir $DIR/$tdir
26908         createmany -o $DIR/$tdir/f 3
26909         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26910         MULTIPID=$!
26911
26912         FID1=$(lfs path2fid $DIR/$tdir/f1)
26913         FID2=$(lfs path2fid $DIR/$tdir/f2)
26914         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26915
26916         kill -USR1 $MULTIPID
26917         wait
26918
26919         cnt=$(ls $DIR/$tdir | wc -l)
26920         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26921 }
26922 run_test 421b "rm by fid on open file"
26923
26924 test_421c() {
26925         local cnt
26926         local FIDS
26927
26928         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26929                 skip "Need MDS version at least 2.12.54"
26930
26931         test_mkdir $DIR/$tdir
26932         createmany -o $DIR/$tdir/f 3
26933         touch $DIR/$tdir/$tfile
26934         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26935         cnt=$(ls -1 $DIR/$tdir | wc -l)
26936         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26937
26938         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26939         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26940
26941         cnt=$(ls $DIR/$tdir | wc -l)
26942         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26943 }
26944 run_test 421c "rm by fid against hardlinked files"
26945
26946 test_421d() {
26947         local cnt
26948         local FIDS
26949
26950         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26951                 skip "Need MDS version at least 2.12.54"
26952
26953         test_mkdir $DIR/$tdir
26954         createmany -o $DIR/$tdir/f 4097
26955         cnt=$(ls -1 $DIR/$tdir | wc -l)
26956         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26957
26958         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26959         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26960
26961         cnt=$(ls $DIR/$tdir | wc -l)
26962         rm -rf $DIR/$tdir
26963         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26964 }
26965 run_test 421d "rmfid en masse"
26966
26967 test_421e() {
26968         local cnt
26969         local FID
26970
26971         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26972         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26973                 skip "Need MDS version at least 2.12.54"
26974
26975         mkdir -p $DIR/$tdir
26976         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26977         createmany -o $DIR/$tdir/striped_dir/f 512
26978         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26979         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26980
26981         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26982                 sed "s/[/][^:]*://g")
26983         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26984
26985         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26986         rm -rf $DIR/$tdir
26987         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26988 }
26989 run_test 421e "rmfid in DNE"
26990
26991 test_421f() {
26992         local cnt
26993         local FID
26994
26995         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26996                 skip "Need MDS version at least 2.12.54"
26997
26998         test_mkdir $DIR/$tdir
26999         touch $DIR/$tdir/f
27000         cnt=$(ls -1 $DIR/$tdir | wc -l)
27001         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27002
27003         FID=$(lfs path2fid $DIR/$tdir/f)
27004         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27005         # rmfid should fail
27006         cnt=$(ls -1 $DIR/$tdir | wc -l)
27007         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27008
27009         chmod a+rw $DIR/$tdir
27010         ls -la $DIR/$tdir
27011         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27012         # rmfid should fail
27013         cnt=$(ls -1 $DIR/$tdir | wc -l)
27014         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27015
27016         rm -f $DIR/$tdir/f
27017         $RUNAS touch $DIR/$tdir/f
27018         FID=$(lfs path2fid $DIR/$tdir/f)
27019         echo "rmfid as root"
27020         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27021         cnt=$(ls -1 $DIR/$tdir | wc -l)
27022         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27023
27024         rm -f $DIR/$tdir/f
27025         $RUNAS touch $DIR/$tdir/f
27026         cnt=$(ls -1 $DIR/$tdir | wc -l)
27027         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27028         FID=$(lfs path2fid $DIR/$tdir/f)
27029         # rmfid w/o user_fid2path mount option should fail
27030         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27031         cnt=$(ls -1 $DIR/$tdir | wc -l)
27032         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27033
27034         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27035         stack_trap "rmdir $tmpdir"
27036         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27037                 error "failed to mount client'"
27038         stack_trap "umount_client $tmpdir"
27039
27040         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27041         # rmfid should succeed
27042         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27043         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27044
27045         # rmfid shouldn't allow to remove files due to dir's permission
27046         chmod a+rwx $tmpdir/$tdir
27047         touch $tmpdir/$tdir/f
27048         ls -la $tmpdir/$tdir
27049         FID=$(lfs path2fid $tmpdir/$tdir/f)
27050         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27051         return 0
27052 }
27053 run_test 421f "rmfid checks permissions"
27054
27055 test_421g() {
27056         local cnt
27057         local FIDS
27058
27059         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27060         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27061                 skip "Need MDS version at least 2.12.54"
27062
27063         mkdir -p $DIR/$tdir
27064         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27065         createmany -o $DIR/$tdir/striped_dir/f 512
27066         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27067         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27068
27069         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27070                 sed "s/[/][^:]*://g")
27071
27072         rm -f $DIR/$tdir/striped_dir/f1*
27073         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27074         removed=$((512 - cnt))
27075
27076         # few files have been just removed, so we expect
27077         # rmfid to fail on their fids
27078         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27079         [ $removed != $errors ] && error "$errors != $removed"
27080
27081         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27082         rm -rf $DIR/$tdir
27083         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27084 }
27085 run_test 421g "rmfid to return errors properly"
27086
27087 test_422() {
27088         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27089         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27090         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27091         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27092         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27093
27094         local amc=$(at_max_get client)
27095         local amo=$(at_max_get mds1)
27096         local timeout=`lctl get_param -n timeout`
27097
27098         at_max_set 0 client
27099         at_max_set 0 mds1
27100
27101 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27102         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27103                         fail_val=$(((2*timeout + 10)*1000))
27104         touch $DIR/$tdir/d3/file &
27105         sleep 2
27106 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27107         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27108                         fail_val=$((2*timeout + 5))
27109         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27110         local pid=$!
27111         sleep 1
27112         kill -9 $pid
27113         sleep $((2 * timeout))
27114         echo kill $pid
27115         kill -9 $pid
27116         lctl mark touch
27117         touch $DIR/$tdir/d2/file3
27118         touch $DIR/$tdir/d2/file4
27119         touch $DIR/$tdir/d2/file5
27120
27121         wait
27122         at_max_set $amc client
27123         at_max_set $amo mds1
27124
27125         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27126         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27127                 error "Watchdog is always throttled"
27128 }
27129 run_test 422 "kill a process with RPC in progress"
27130
27131 stat_test() {
27132     df -h $MOUNT &
27133     df -h $MOUNT &
27134     df -h $MOUNT &
27135     df -h $MOUNT &
27136     df -h $MOUNT &
27137     df -h $MOUNT &
27138 }
27139
27140 test_423() {
27141     local _stats
27142     # ensure statfs cache is expired
27143     sleep 2;
27144
27145     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27146     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27147
27148     return 0
27149 }
27150 run_test 423 "statfs should return a right data"
27151
27152 test_424() {
27153 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27154         $LCTL set_param fail_loc=0x80000522
27155         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27156         rm -f $DIR/$tfile
27157 }
27158 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27159
27160 test_425() {
27161         test_mkdir -c -1 $DIR/$tdir
27162         $LFS setstripe -c -1 $DIR/$tdir
27163
27164         lru_resize_disable "" 100
27165         stack_trap "lru_resize_enable" EXIT
27166
27167         sleep 5
27168
27169         for i in $(seq $((MDSCOUNT * 125))); do
27170                 local t=$DIR/$tdir/$tfile_$i
27171
27172                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27173                         error_noexit "Create file $t"
27174         done
27175         stack_trap "rm -rf $DIR/$tdir" EXIT
27176
27177         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27178                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27179                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27180
27181                 [ $lock_count -le $lru_size ] ||
27182                         error "osc lock count $lock_count > lru size $lru_size"
27183         done
27184
27185         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27186                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27187                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27188
27189                 [ $lock_count -le $lru_size ] ||
27190                         error "mdc lock count $lock_count > lru size $lru_size"
27191         done
27192 }
27193 run_test 425 "lock count should not exceed lru size"
27194
27195 test_426() {
27196         splice-test -r $DIR/$tfile
27197         splice-test -rd $DIR/$tfile
27198         splice-test $DIR/$tfile
27199         splice-test -d $DIR/$tfile
27200 }
27201 run_test 426 "splice test on Lustre"
27202
27203 test_427() {
27204         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27205         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27206                 skip "Need MDS version at least 2.12.4"
27207         local log
27208
27209         mkdir $DIR/$tdir
27210         mkdir $DIR/$tdir/1
27211         mkdir $DIR/$tdir/2
27212         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27213         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27214
27215         $LFS getdirstripe $DIR/$tdir/1/dir
27216
27217         #first setfattr for creating updatelog
27218         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27219
27220 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27221         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27222         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27223         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27224
27225         sleep 2
27226         fail mds2
27227         wait_recovery_complete mds2 $((2*TIMEOUT))
27228
27229         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27230         echo $log | grep "get update log failed" &&
27231                 error "update log corruption is detected" || true
27232 }
27233 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27234
27235 test_428() {
27236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27237         local cache_limit=$CACHE_MAX
27238
27239         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27240         $LCTL set_param -n llite.*.max_cached_mb=64
27241
27242         mkdir $DIR/$tdir
27243         $LFS setstripe -c 1 $DIR/$tdir
27244         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27245         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27246         #test write
27247         for f in $(seq 4); do
27248                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27249         done
27250         wait
27251
27252         cancel_lru_locks osc
27253         # Test read
27254         for f in $(seq 4); do
27255                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27256         done
27257         wait
27258 }
27259 run_test 428 "large block size IO should not hang"
27260
27261 test_429() { # LU-7915 / LU-10948
27262         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27263         local testfile=$DIR/$tfile
27264         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27265         local new_flag=1
27266         local first_rpc
27267         local second_rpc
27268         local third_rpc
27269
27270         $LCTL get_param $ll_opencache_threshold_count ||
27271                 skip "client does not have opencache parameter"
27272
27273         set_opencache $new_flag
27274         stack_trap "restore_opencache"
27275         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27276                 error "enable opencache failed"
27277         touch $testfile
27278         # drop MDC DLM locks
27279         cancel_lru_locks mdc
27280         # clear MDC RPC stats counters
27281         $LCTL set_param $mdc_rpcstats=clear
27282
27283         # According to the current implementation, we need to run 3 times
27284         # open & close file to verify if opencache is enabled correctly.
27285         # 1st, RPCs are sent for lookup/open and open handle is released on
27286         #      close finally.
27287         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27288         #      so open handle won't be released thereafter.
27289         # 3rd, No RPC is sent out.
27290         $MULTIOP $testfile oc || error "multiop failed"
27291         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27292         echo "1st: $first_rpc RPCs in flight"
27293
27294         $MULTIOP $testfile oc || error "multiop failed"
27295         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27296         echo "2nd: $second_rpc RPCs in flight"
27297
27298         $MULTIOP $testfile oc || error "multiop failed"
27299         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27300         echo "3rd: $third_rpc RPCs in flight"
27301
27302         #verify no MDC RPC is sent
27303         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27304 }
27305 run_test 429 "verify if opencache flag on client side does work"
27306
27307 lseek_test_430() {
27308         local offset
27309         local file=$1
27310
27311         # data at [200K, 400K)
27312         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27313                 error "256K->512K dd fails"
27314         # data at [2M, 3M)
27315         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27316                 error "2M->3M dd fails"
27317         # data at [4M, 5M)
27318         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27319                 error "4M->5M dd fails"
27320         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27321         # start at first component hole #1
27322         printf "Seeking hole from 1000 ... "
27323         offset=$(lseek_test -l 1000 $file)
27324         echo $offset
27325         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27326         printf "Seeking data from 1000 ... "
27327         offset=$(lseek_test -d 1000 $file)
27328         echo $offset
27329         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27330
27331         # start at first component data block
27332         printf "Seeking hole from 300000 ... "
27333         offset=$(lseek_test -l 300000 $file)
27334         echo $offset
27335         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27336         printf "Seeking data from 300000 ... "
27337         offset=$(lseek_test -d 300000 $file)
27338         echo $offset
27339         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27340
27341         # start at the first component but beyond end of object size
27342         printf "Seeking hole from 1000000 ... "
27343         offset=$(lseek_test -l 1000000 $file)
27344         echo $offset
27345         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27346         printf "Seeking data from 1000000 ... "
27347         offset=$(lseek_test -d 1000000 $file)
27348         echo $offset
27349         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27350
27351         # start at second component stripe 2 (empty file)
27352         printf "Seeking hole from 1500000 ... "
27353         offset=$(lseek_test -l 1500000 $file)
27354         echo $offset
27355         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27356         printf "Seeking data from 1500000 ... "
27357         offset=$(lseek_test -d 1500000 $file)
27358         echo $offset
27359         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27360
27361         # start at second component stripe 1 (all data)
27362         printf "Seeking hole from 3000000 ... "
27363         offset=$(lseek_test -l 3000000 $file)
27364         echo $offset
27365         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27366         printf "Seeking data from 3000000 ... "
27367         offset=$(lseek_test -d 3000000 $file)
27368         echo $offset
27369         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27370
27371         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27372                 error "2nd dd fails"
27373         echo "Add data block at 640K...1280K"
27374
27375         # start at before new data block, in hole
27376         printf "Seeking hole from 600000 ... "
27377         offset=$(lseek_test -l 600000 $file)
27378         echo $offset
27379         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27380         printf "Seeking data from 600000 ... "
27381         offset=$(lseek_test -d 600000 $file)
27382         echo $offset
27383         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27384
27385         # start at the first component new data block
27386         printf "Seeking hole from 1000000 ... "
27387         offset=$(lseek_test -l 1000000 $file)
27388         echo $offset
27389         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27390         printf "Seeking data from 1000000 ... "
27391         offset=$(lseek_test -d 1000000 $file)
27392         echo $offset
27393         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27394
27395         # start at second component stripe 2, new data
27396         printf "Seeking hole from 1200000 ... "
27397         offset=$(lseek_test -l 1200000 $file)
27398         echo $offset
27399         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27400         printf "Seeking data from 1200000 ... "
27401         offset=$(lseek_test -d 1200000 $file)
27402         echo $offset
27403         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27404
27405         # start beyond file end
27406         printf "Using offset > filesize ... "
27407         lseek_test -l 4000000 $file && error "lseek should fail"
27408         printf "Using offset > filesize ... "
27409         lseek_test -d 4000000 $file && error "lseek should fail"
27410
27411         printf "Done\n\n"
27412 }
27413
27414 test_430a() {
27415         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27416                 skip "MDT does not support SEEK_HOLE"
27417
27418         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27419                 skip "OST does not support SEEK_HOLE"
27420
27421         local file=$DIR/$tdir/$tfile
27422
27423         mkdir -p $DIR/$tdir
27424
27425         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27426         # OST stripe #1 will have continuous data at [1M, 3M)
27427         # OST stripe #2 is empty
27428         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27429         lseek_test_430 $file
27430         rm $file
27431         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27432         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27433         lseek_test_430 $file
27434         rm $file
27435         $LFS setstripe -c2 -S 512K $file
27436         echo "Two stripes, stripe size 512K"
27437         lseek_test_430 $file
27438         rm $file
27439         # FLR with stale mirror
27440         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27441                        -N -c2 -S 1M $file
27442         echo "Mirrored file:"
27443         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27444         echo "Plain 2 stripes 1M"
27445         lseek_test_430 $file
27446         rm $file
27447 }
27448 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27449
27450 test_430b() {
27451         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27452                 skip "OST does not support SEEK_HOLE"
27453
27454         local offset
27455         local file=$DIR/$tdir/$tfile
27456
27457         mkdir -p $DIR/$tdir
27458         # Empty layout lseek should fail
27459         $MCREATE $file
27460         # seek from 0
27461         printf "Seeking hole from 0 ... "
27462         lseek_test -l 0 $file && error "lseek should fail"
27463         printf "Seeking data from 0 ... "
27464         lseek_test -d 0 $file && error "lseek should fail"
27465         rm $file
27466
27467         # 1M-hole file
27468         $LFS setstripe -E 1M -c2 -E eof $file
27469         $TRUNCATE $file 1048576
27470         printf "Seeking hole from 1000000 ... "
27471         offset=$(lseek_test -l 1000000 $file)
27472         echo $offset
27473         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27474         printf "Seeking data from 1000000 ... "
27475         lseek_test -d 1000000 $file && error "lseek should fail"
27476         rm $file
27477
27478         # full component followed by non-inited one
27479         $LFS setstripe -E 1M -c2 -E eof $file
27480         dd if=/dev/urandom of=$file bs=1M count=1
27481         printf "Seeking hole from 1000000 ... "
27482         offset=$(lseek_test -l 1000000 $file)
27483         echo $offset
27484         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27485         printf "Seeking hole from 1048576 ... "
27486         lseek_test -l 1048576 $file && error "lseek should fail"
27487         # init second component and truncate back
27488         echo "123" >> $file
27489         $TRUNCATE $file 1048576
27490         printf "Seeking hole from 1000000 ... "
27491         offset=$(lseek_test -l 1000000 $file)
27492         echo $offset
27493         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27494         printf "Seeking hole from 1048576 ... "
27495         lseek_test -l 1048576 $file && error "lseek should fail"
27496         # boundary checks for big values
27497         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27498         offset=$(lseek_test -d 0 $file.10g)
27499         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27500         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27501         offset=$(lseek_test -d 0 $file.100g)
27502         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27503         return 0
27504 }
27505 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27506
27507 test_430c() {
27508         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27509                 skip "OST does not support SEEK_HOLE"
27510
27511         local file=$DIR/$tdir/$tfile
27512         local start
27513
27514         mkdir -p $DIR/$tdir
27515         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27516
27517         # cp version 8.33+ prefers lseek over fiemap
27518         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27519                 start=$SECONDS
27520                 time cp $file /dev/null
27521                 (( SECONDS - start < 5 )) ||
27522                         error "cp: too long runtime $((SECONDS - start))"
27523
27524         fi
27525         # tar version 1.29+ supports SEEK_HOLE/DATA
27526         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27527                 start=$SECONDS
27528                 time tar cS $file - | cat > /dev/null
27529                 (( SECONDS - start < 5 )) ||
27530                         error "tar: too long runtime $((SECONDS - start))"
27531         fi
27532 }
27533 run_test 430c "lseek: external tools check"
27534
27535 test_431() { # LU-14187
27536         local file=$DIR/$tdir/$tfile
27537
27538         mkdir -p $DIR/$tdir
27539         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27540         dd if=/dev/urandom of=$file bs=4k count=1
27541         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27542         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27543         #define OBD_FAIL_OST_RESTART_IO 0x251
27544         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27545         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27546         cp $file $file.0
27547         cancel_lru_locks
27548         sync_all_data
27549         echo 3 > /proc/sys/vm/drop_caches
27550         diff  $file $file.0 || error "data diff"
27551 }
27552 run_test 431 "Restart transaction for IO"
27553
27554 cleanup_test_432() {
27555         do_facet mgs $LCTL nodemap_activate 0
27556         wait_nm_sync active
27557 }
27558
27559 test_432() {
27560         local tmpdir=$TMP/dir432
27561
27562         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27563                 skip "Need MDS version at least 2.14.52"
27564
27565         stack_trap cleanup_test_432 EXIT
27566         mkdir $DIR/$tdir
27567         mkdir $tmpdir
27568
27569         do_facet mgs $LCTL nodemap_activate 1
27570         wait_nm_sync active
27571         do_facet mgs $LCTL nodemap_modify --name default \
27572                 --property admin --value 1
27573         do_facet mgs $LCTL nodemap_modify --name default \
27574                 --property trusted --value 1
27575         cancel_lru_locks mdc
27576         wait_nm_sync default admin_nodemap
27577         wait_nm_sync default trusted_nodemap
27578
27579         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27580                grep -ci "Operation not permitted") -ne 0 ]; then
27581                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27582         fi
27583 }
27584 run_test 432 "mv dir from outside Lustre"
27585
27586 test_433() {
27587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27588
27589         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27590                 skip "inode cache not supported"
27591
27592         $LCTL set_param llite.*.inode_cache=0
27593         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27594
27595         local count=256
27596         local before
27597         local after
27598
27599         cancel_lru_locks mdc
27600         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27601         createmany -m $DIR/$tdir/f $count
27602         createmany -d $DIR/$tdir/d $count
27603         ls -l $DIR/$tdir > /dev/null
27604         stack_trap "rm -rf $DIR/$tdir"
27605
27606         before=$(num_objects)
27607         cancel_lru_locks mdc
27608         after=$(num_objects)
27609
27610         # sometimes even @before is less than 2 * count
27611         while (( before - after < count )); do
27612                 sleep 1
27613                 after=$(num_objects)
27614                 wait=$((wait + 1))
27615                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27616                 if (( wait > 60 )); then
27617                         error "inode slab grew from $before to $after"
27618                 fi
27619         done
27620
27621         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27622 }
27623 run_test 433 "ldlm lock cancel releases dentries and inodes"
27624
27625 test_434() {
27626         local file
27627         local getxattr_count
27628         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27629         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27630
27631         [[ $(getenforce) == "Disabled" ]] ||
27632                 skip "lsm selinux module have to be disabled for this test"
27633
27634         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27635                 error "fail to create $DIR/$tdir/ on MDT0000"
27636
27637         touch $DIR/$tdir/$tfile-{001..100}
27638
27639         # disable the xattr cache
27640         save_lustre_params client "llite.*.xattr_cache" > $p
27641         lctl set_param llite.*.xattr_cache=0
27642         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27643
27644         # clear clients mdc stats
27645         clear_stats $mdc_stat_param ||
27646                 error "fail to clear stats on mdc MDT0000"
27647
27648         for file in $DIR/$tdir/$tfile-{001..100}; do
27649                 getfattr -n security.selinux $file |&
27650                         grep -q "Operation not supported" ||
27651                         error "getxattr on security.selinux should return EOPNOTSUPP"
27652         done
27653
27654         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27655         (( getxattr_count < 100 )) ||
27656                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27657 }
27658 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27659
27660 prep_801() {
27661         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27662         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27663                 skip "Need server version at least 2.9.55"
27664
27665         start_full_debug_logging
27666 }
27667
27668 post_801() {
27669         stop_full_debug_logging
27670 }
27671
27672 barrier_stat() {
27673         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27674                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27675                            awk '/The barrier for/ { print $7 }')
27676                 echo $st
27677         else
27678                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27679                 echo \'$st\'
27680         fi
27681 }
27682
27683 barrier_expired() {
27684         local expired
27685
27686         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27687                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27688                           awk '/will be expired/ { print $7 }')
27689         else
27690                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27691         fi
27692
27693         echo $expired
27694 }
27695
27696 test_801a() {
27697         prep_801
27698
27699         echo "Start barrier_freeze at: $(date)"
27700         #define OBD_FAIL_BARRIER_DELAY          0x2202
27701         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27702         # Do not reduce barrier time - See LU-11873
27703         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27704
27705         sleep 2
27706         local b_status=$(barrier_stat)
27707         echo "Got barrier status at: $(date)"
27708         [ "$b_status" = "'freezing_p1'" ] ||
27709                 error "(1) unexpected barrier status $b_status"
27710
27711         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27712         wait
27713         b_status=$(barrier_stat)
27714         [ "$b_status" = "'frozen'" ] ||
27715                 error "(2) unexpected barrier status $b_status"
27716
27717         local expired=$(barrier_expired)
27718         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27719         sleep $((expired + 3))
27720
27721         b_status=$(barrier_stat)
27722         [ "$b_status" = "'expired'" ] ||
27723                 error "(3) unexpected barrier status $b_status"
27724
27725         # Do not reduce barrier time - See LU-11873
27726         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27727                 error "(4) fail to freeze barrier"
27728
27729         b_status=$(barrier_stat)
27730         [ "$b_status" = "'frozen'" ] ||
27731                 error "(5) unexpected barrier status $b_status"
27732
27733         echo "Start barrier_thaw at: $(date)"
27734         #define OBD_FAIL_BARRIER_DELAY          0x2202
27735         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27736         do_facet mgs $LCTL barrier_thaw $FSNAME &
27737
27738         sleep 2
27739         b_status=$(barrier_stat)
27740         echo "Got barrier status at: $(date)"
27741         [ "$b_status" = "'thawing'" ] ||
27742                 error "(6) unexpected barrier status $b_status"
27743
27744         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27745         wait
27746         b_status=$(barrier_stat)
27747         [ "$b_status" = "'thawed'" ] ||
27748                 error "(7) unexpected barrier status $b_status"
27749
27750         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27751         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27752         do_facet mgs $LCTL barrier_freeze $FSNAME
27753
27754         b_status=$(barrier_stat)
27755         [ "$b_status" = "'failed'" ] ||
27756                 error "(8) unexpected barrier status $b_status"
27757
27758         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27759         do_facet mgs $LCTL barrier_thaw $FSNAME
27760
27761         post_801
27762 }
27763 run_test 801a "write barrier user interfaces and stat machine"
27764
27765 test_801b() {
27766         prep_801
27767
27768         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27769         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27770         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27771         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27772         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27773
27774         cancel_lru_locks mdc
27775
27776         # 180 seconds should be long enough
27777         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27778
27779         local b_status=$(barrier_stat)
27780         [ "$b_status" = "'frozen'" ] ||
27781                 error "(6) unexpected barrier status $b_status"
27782
27783         mkdir $DIR/$tdir/d0/d10 &
27784         mkdir_pid=$!
27785
27786         touch $DIR/$tdir/d1/f13 &
27787         touch_pid=$!
27788
27789         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27790         ln_pid=$!
27791
27792         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27793         mv_pid=$!
27794
27795         rm -f $DIR/$tdir/d4/f12 &
27796         rm_pid=$!
27797
27798         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27799
27800         # To guarantee taht the 'stat' is not blocked
27801         b_status=$(barrier_stat)
27802         [ "$b_status" = "'frozen'" ] ||
27803                 error "(8) unexpected barrier status $b_status"
27804
27805         # let above commands to run at background
27806         sleep 5
27807
27808         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27809         ps -p $touch_pid || error "(10) touch should be blocked"
27810         ps -p $ln_pid || error "(11) link should be blocked"
27811         ps -p $mv_pid || error "(12) rename should be blocked"
27812         ps -p $rm_pid || error "(13) unlink should be blocked"
27813
27814         b_status=$(barrier_stat)
27815         [ "$b_status" = "'frozen'" ] ||
27816                 error "(14) unexpected barrier status $b_status"
27817
27818         do_facet mgs $LCTL barrier_thaw $FSNAME
27819         b_status=$(barrier_stat)
27820         [ "$b_status" = "'thawed'" ] ||
27821                 error "(15) unexpected barrier status $b_status"
27822
27823         wait $mkdir_pid || error "(16) mkdir should succeed"
27824         wait $touch_pid || error "(17) touch should succeed"
27825         wait $ln_pid || error "(18) link should succeed"
27826         wait $mv_pid || error "(19) rename should succeed"
27827         wait $rm_pid || error "(20) unlink should succeed"
27828
27829         post_801
27830 }
27831 run_test 801b "modification will be blocked by write barrier"
27832
27833 test_801c() {
27834         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27835
27836         prep_801
27837
27838         stop mds2 || error "(1) Fail to stop mds2"
27839
27840         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27841
27842         local b_status=$(barrier_stat)
27843         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27844                 do_facet mgs $LCTL barrier_thaw $FSNAME
27845                 error "(2) unexpected barrier status $b_status"
27846         }
27847
27848         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27849                 error "(3) Fail to rescan barrier bitmap"
27850
27851         # Do not reduce barrier time - See LU-11873
27852         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27853
27854         b_status=$(barrier_stat)
27855         [ "$b_status" = "'frozen'" ] ||
27856                 error "(4) unexpected barrier status $b_status"
27857
27858         do_facet mgs $LCTL barrier_thaw $FSNAME
27859         b_status=$(barrier_stat)
27860         [ "$b_status" = "'thawed'" ] ||
27861                 error "(5) unexpected barrier status $b_status"
27862
27863         local devname=$(mdsdevname 2)
27864
27865         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27866
27867         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27868                 error "(7) Fail to rescan barrier bitmap"
27869
27870         post_801
27871 }
27872 run_test 801c "rescan barrier bitmap"
27873
27874 test_802b() {
27875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27876         remote_mds_nodsh && skip "remote MDS with nodsh"
27877
27878         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27879                 skip "readonly option not available"
27880
27881         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27882
27883         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27884                 error "(2) Fail to copy"
27885
27886         # write back all cached data before setting MDT to readonly
27887         cancel_lru_locks
27888         sync_all_data
27889
27890         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27891         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27892
27893         echo "Modify should be refused"
27894         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27895
27896         echo "Read should be allowed"
27897         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27898                 error "(7) Read should succeed under ro mode"
27899
27900         # disable readonly
27901         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27902 }
27903 run_test 802b "be able to set MDTs to readonly"
27904
27905 test_803a() {
27906         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27907         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27908                 skip "MDS needs to be newer than 2.10.54"
27909
27910         mkdir_on_mdt0 $DIR/$tdir
27911         # Create some objects on all MDTs to trigger related logs objects
27912         for idx in $(seq $MDSCOUNT); do
27913                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27914                         $DIR/$tdir/dir${idx} ||
27915                         error "Fail to create $DIR/$tdir/dir${idx}"
27916         done
27917
27918         wait_delete_completed # ensure old test cleanups are finished
27919         sleep 3
27920         echo "before create:"
27921         $LFS df -i $MOUNT
27922         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27923
27924         for i in {1..10}; do
27925                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27926                         error "Fail to create $DIR/$tdir/foo$i"
27927         done
27928
27929         # sync ZFS-on-MDS to refresh statfs data
27930         wait_zfs_commit mds1
27931         sleep 3
27932         echo "after create:"
27933         $LFS df -i $MOUNT
27934         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27935
27936         # allow for an llog to be cleaned up during the test
27937         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27938                 error "before ($before_used) + 10 > after ($after_used)"
27939
27940         for i in {1..10}; do
27941                 rm -rf $DIR/$tdir/foo$i ||
27942                         error "Fail to remove $DIR/$tdir/foo$i"
27943         done
27944
27945         # sync ZFS-on-MDS to refresh statfs data
27946         wait_zfs_commit mds1
27947         wait_delete_completed
27948         sleep 3 # avoid MDT return cached statfs
27949         echo "after unlink:"
27950         $LFS df -i $MOUNT
27951         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27952
27953         # allow for an llog to be created during the test
27954         [ $after_used -le $((before_used + 1)) ] ||
27955                 error "after ($after_used) > before ($before_used) + 1"
27956 }
27957 run_test 803a "verify agent object for remote object"
27958
27959 test_803b() {
27960         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27961         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27962                 skip "MDS needs to be newer than 2.13.56"
27963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27964
27965         for i in $(seq 0 $((MDSCOUNT - 1))); do
27966                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27967         done
27968
27969         local before=0
27970         local after=0
27971
27972         local tmp
27973
27974         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27975         for i in $(seq 0 $((MDSCOUNT - 1))); do
27976                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27977                         awk '/getattr/ { print $2 }')
27978                 before=$((before + tmp))
27979         done
27980         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27981         for i in $(seq 0 $((MDSCOUNT - 1))); do
27982                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27983                         awk '/getattr/ { print $2 }')
27984                 after=$((after + tmp))
27985         done
27986
27987         [ $before -eq $after ] || error "getattr count $before != $after"
27988 }
27989 run_test 803b "remote object can getattr from cache"
27990
27991 test_804() {
27992         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27993         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27994                 skip "MDS needs to be newer than 2.10.54"
27995         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27996
27997         mkdir -p $DIR/$tdir
27998         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27999                 error "Fail to create $DIR/$tdir/dir0"
28000
28001         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28002         local dev=$(mdsdevname 2)
28003
28004         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28005                 grep ${fid} || error "NOT found agent entry for dir0"
28006
28007         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28008                 error "Fail to create $DIR/$tdir/dir1"
28009
28010         touch $DIR/$tdir/dir1/foo0 ||
28011                 error "Fail to create $DIR/$tdir/dir1/foo0"
28012         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28013         local rc=0
28014
28015         for idx in $(seq $MDSCOUNT); do
28016                 dev=$(mdsdevname $idx)
28017                 do_facet mds${idx} \
28018                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28019                         grep ${fid} && rc=$idx
28020         done
28021
28022         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28023                 error "Fail to rename foo0 to foo1"
28024         if [ $rc -eq 0 ]; then
28025                 for idx in $(seq $MDSCOUNT); do
28026                         dev=$(mdsdevname $idx)
28027                         do_facet mds${idx} \
28028                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28029                         grep ${fid} && rc=$idx
28030                 done
28031         fi
28032
28033         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28034                 error "Fail to rename foo1 to foo2"
28035         if [ $rc -eq 0 ]; then
28036                 for idx in $(seq $MDSCOUNT); do
28037                         dev=$(mdsdevname $idx)
28038                         do_facet mds${idx} \
28039                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28040                         grep ${fid} && rc=$idx
28041                 done
28042         fi
28043
28044         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28045
28046         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28047                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28048         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28049                 error "Fail to rename foo2 to foo0"
28050         unlink $DIR/$tdir/dir1/foo0 ||
28051                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28052         rm -rf $DIR/$tdir/dir0 ||
28053                 error "Fail to rm $DIR/$tdir/dir0"
28054
28055         for idx in $(seq $MDSCOUNT); do
28056                 rc=0
28057
28058                 stop mds${idx}
28059                 dev=$(mdsdevname $idx)
28060                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28061                         rc=$?
28062                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28063                         error "mount mds$idx failed"
28064                 df $MOUNT > /dev/null 2>&1
28065
28066                 # e2fsck should not return error
28067                 [ $rc -eq 0 ] ||
28068                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28069         done
28070 }
28071 run_test 804 "verify agent entry for remote entry"
28072
28073 cleanup_805() {
28074         do_facet $SINGLEMDS zfs set quota=$old $fsset
28075         unlinkmany $DIR/$tdir/f- 1000000
28076         trap 0
28077 }
28078
28079 test_805() {
28080         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28081         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28082         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28083                 skip "netfree not implemented before 0.7"
28084         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28085                 skip "Need MDS version at least 2.10.57"
28086
28087         local fsset
28088         local freekb
28089         local usedkb
28090         local old
28091         local quota
28092         local pref="osd-zfs.$FSNAME-MDT0000."
28093
28094         # limit available space on MDS dataset to meet nospace issue
28095         # quickly. then ZFS 0.7.2 can use reserved space if asked
28096         # properly (using netfree flag in osd_declare_destroy()
28097         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28098         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28099                 gawk '{print $3}')
28100         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28101         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28102         let "usedkb=usedkb-freekb"
28103         let "freekb=freekb/2"
28104         if let "freekb > 5000"; then
28105                 let "freekb=5000"
28106         fi
28107         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28108         trap cleanup_805 EXIT
28109         mkdir_on_mdt0 $DIR/$tdir
28110         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28111                 error "Can't set PFL layout"
28112         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28113         rm -rf $DIR/$tdir || error "not able to remove"
28114         do_facet $SINGLEMDS zfs set quota=$old $fsset
28115         trap 0
28116 }
28117 run_test 805 "ZFS can remove from full fs"
28118
28119 # Size-on-MDS test
28120 check_lsom_data()
28121 {
28122         local file=$1
28123         local expect=$(stat -c %s $file)
28124
28125         check_lsom_size $1 $expect
28126
28127         local blocks=$($LFS getsom -b $file)
28128         expect=$(stat -c %b $file)
28129         [[ $blocks == $expect ]] ||
28130                 error "$file expected blocks: $expect, got: $blocks"
28131 }
28132
28133 check_lsom_size()
28134 {
28135         local size
28136         local expect=$2
28137
28138         cancel_lru_locks mdc
28139
28140         size=$($LFS getsom -s $1)
28141         [[ $size == $expect ]] ||
28142                 error "$file expected size: $expect, got: $size"
28143 }
28144
28145 test_806() {
28146         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28147                 skip "Need MDS version at least 2.11.52"
28148
28149         local bs=1048576
28150
28151         touch $DIR/$tfile || error "touch $tfile failed"
28152
28153         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28154         save_lustre_params client "llite.*.xattr_cache" > $save
28155         lctl set_param llite.*.xattr_cache=0
28156         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28157
28158         # single-threaded write
28159         echo "Test SOM for single-threaded write"
28160         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28161                 error "write $tfile failed"
28162         check_lsom_size $DIR/$tfile $bs
28163
28164         local num=32
28165         local size=$(($num * $bs))
28166         local offset=0
28167         local i
28168
28169         echo "Test SOM for single client multi-threaded($num) write"
28170         $TRUNCATE $DIR/$tfile 0
28171         for ((i = 0; i < $num; i++)); do
28172                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28173                 local pids[$i]=$!
28174                 offset=$((offset + $bs))
28175         done
28176         for (( i=0; i < $num; i++ )); do
28177                 wait ${pids[$i]}
28178         done
28179         check_lsom_size $DIR/$tfile $size
28180
28181         $TRUNCATE $DIR/$tfile 0
28182         for ((i = 0; i < $num; i++)); do
28183                 offset=$((offset - $bs))
28184                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28185                 local pids[$i]=$!
28186         done
28187         for (( i=0; i < $num; i++ )); do
28188                 wait ${pids[$i]}
28189         done
28190         check_lsom_size $DIR/$tfile $size
28191
28192         # multi-client writes
28193         num=$(get_node_count ${CLIENTS//,/ })
28194         size=$(($num * $bs))
28195         offset=0
28196         i=0
28197
28198         echo "Test SOM for multi-client ($num) writes"
28199         $TRUNCATE $DIR/$tfile 0
28200         for client in ${CLIENTS//,/ }; do
28201                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28202                 local pids[$i]=$!
28203                 i=$((i + 1))
28204                 offset=$((offset + $bs))
28205         done
28206         for (( i=0; i < $num; i++ )); do
28207                 wait ${pids[$i]}
28208         done
28209         check_lsom_size $DIR/$tfile $offset
28210
28211         i=0
28212         $TRUNCATE $DIR/$tfile 0
28213         for client in ${CLIENTS//,/ }; do
28214                 offset=$((offset - $bs))
28215                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28216                 local pids[$i]=$!
28217                 i=$((i + 1))
28218         done
28219         for (( i=0; i < $num; i++ )); do
28220                 wait ${pids[$i]}
28221         done
28222         check_lsom_size $DIR/$tfile $size
28223
28224         # verify truncate
28225         echo "Test SOM for truncate"
28226         $TRUNCATE $DIR/$tfile 1048576
28227         check_lsom_size $DIR/$tfile 1048576
28228         $TRUNCATE $DIR/$tfile 1234
28229         check_lsom_size $DIR/$tfile 1234
28230
28231         # verify SOM blocks count
28232         echo "Verify SOM block count"
28233         $TRUNCATE $DIR/$tfile 0
28234         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28235                 error "failed to write file $tfile"
28236         check_lsom_data $DIR/$tfile
28237 }
28238 run_test 806 "Verify Lazy Size on MDS"
28239
28240 test_807() {
28241         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28242         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28243                 skip "Need MDS version at least 2.11.52"
28244
28245         # Registration step
28246         changelog_register || error "changelog_register failed"
28247         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28248         changelog_users $SINGLEMDS | grep -q $cl_user ||
28249                 error "User $cl_user not found in changelog_users"
28250
28251         rm -rf $DIR/$tdir || error "rm $tdir failed"
28252         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28253         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28254         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28255         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28256                 error "truncate $tdir/trunc failed"
28257
28258         local bs=1048576
28259         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28260                 error "write $tfile failed"
28261
28262         # multi-client wirtes
28263         local num=$(get_node_count ${CLIENTS//,/ })
28264         local offset=0
28265         local i=0
28266
28267         echo "Test SOM for multi-client ($num) writes"
28268         touch $DIR/$tfile || error "touch $tfile failed"
28269         $TRUNCATE $DIR/$tfile 0
28270         for client in ${CLIENTS//,/ }; do
28271                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28272                 local pids[$i]=$!
28273                 i=$((i + 1))
28274                 offset=$((offset + $bs))
28275         done
28276         for (( i=0; i < $num; i++ )); do
28277                 wait ${pids[$i]}
28278         done
28279
28280         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28281         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28282         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28283         check_lsom_data $DIR/$tdir/trunc
28284         check_lsom_data $DIR/$tdir/single_dd
28285         check_lsom_data $DIR/$tfile
28286
28287         rm -rf $DIR/$tdir
28288         # Deregistration step
28289         changelog_deregister || error "changelog_deregister failed"
28290 }
28291 run_test 807 "verify LSOM syncing tool"
28292
28293 check_som_nologged()
28294 {
28295         local lines=$($LFS changelog $FSNAME-MDT0000 |
28296                 grep 'x=trusted.som' | wc -l)
28297         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28298 }
28299
28300 test_808() {
28301         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28302                 skip "Need MDS version at least 2.11.55"
28303
28304         # Registration step
28305         changelog_register || error "changelog_register failed"
28306
28307         touch $DIR/$tfile || error "touch $tfile failed"
28308         check_som_nologged
28309
28310         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28311                 error "write $tfile failed"
28312         check_som_nologged
28313
28314         $TRUNCATE $DIR/$tfile 1234
28315         check_som_nologged
28316
28317         $TRUNCATE $DIR/$tfile 1048576
28318         check_som_nologged
28319
28320         # Deregistration step
28321         changelog_deregister || error "changelog_deregister failed"
28322 }
28323 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28324
28325 check_som_nodata()
28326 {
28327         $LFS getsom $1
28328         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28329 }
28330
28331 test_809() {
28332         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28333                 skip "Need MDS version at least 2.11.56"
28334
28335         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28336                 error "failed to create DoM-only file $DIR/$tfile"
28337         touch $DIR/$tfile || error "touch $tfile failed"
28338         check_som_nodata $DIR/$tfile
28339
28340         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28341                 error "write $tfile failed"
28342         check_som_nodata $DIR/$tfile
28343
28344         $TRUNCATE $DIR/$tfile 1234
28345         check_som_nodata $DIR/$tfile
28346
28347         $TRUNCATE $DIR/$tfile 4097
28348         check_som_nodata $DIR/$file
28349 }
28350 run_test 809 "Verify no SOM xattr store for DoM-only files"
28351
28352 test_810() {
28353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28354         $GSS && skip_env "could not run with gss"
28355         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28356                 skip "OST < 2.12.58 doesn't align checksum"
28357
28358         set_checksums 1
28359         stack_trap "set_checksums $ORIG_CSUM" EXIT
28360         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28361
28362         local csum
28363         local before
28364         local after
28365         for csum in $CKSUM_TYPES; do
28366                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28367                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28368                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28369                         eval set -- $i
28370                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28371                         before=$(md5sum $DIR/$tfile)
28372                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28373                         after=$(md5sum $DIR/$tfile)
28374                         [ "$before" == "$after" ] ||
28375                                 error "$csum: $before != $after bs=$1 seek=$2"
28376                 done
28377         done
28378 }
28379 run_test 810 "partial page writes on ZFS (LU-11663)"
28380
28381 test_812a() {
28382         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28383                 skip "OST < 2.12.51 doesn't support this fail_loc"
28384
28385         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28386         # ensure ost1 is connected
28387         stat $DIR/$tfile >/dev/null || error "can't stat"
28388         wait_osc_import_state client ost1 FULL
28389         # no locks, no reqs to let the connection idle
28390         cancel_lru_locks osc
28391
28392         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28393 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28394         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28395         wait_osc_import_state client ost1 CONNECTING
28396         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28397
28398         stat $DIR/$tfile >/dev/null || error "can't stat file"
28399 }
28400 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28401
28402 test_812b() { # LU-12378
28403         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28404                 skip "OST < 2.12.51 doesn't support this fail_loc"
28405
28406         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28407         # ensure ost1 is connected
28408         stat $DIR/$tfile >/dev/null || error "can't stat"
28409         wait_osc_import_state client ost1 FULL
28410         # no locks, no reqs to let the connection idle
28411         cancel_lru_locks osc
28412
28413         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28414 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28415         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28416         wait_osc_import_state client ost1 CONNECTING
28417         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28418
28419         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28420         wait_osc_import_state client ost1 IDLE
28421 }
28422 run_test 812b "do not drop no resend request for idle connect"
28423
28424 test_812c() {
28425         local old
28426
28427         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28428
28429         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28430         $LFS getstripe $DIR/$tfile
28431         $LCTL set_param osc.*.idle_timeout=10
28432         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28433         # ensure ost1 is connected
28434         stat $DIR/$tfile >/dev/null || error "can't stat"
28435         wait_osc_import_state client ost1 FULL
28436         # no locks, no reqs to let the connection idle
28437         cancel_lru_locks osc
28438
28439 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28440         $LCTL set_param fail_loc=0x80000533
28441         sleep 15
28442         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28443 }
28444 run_test 812c "idle import vs lock enqueue race"
28445
28446 test_813() {
28447         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28448         [ -z "$file_heat_sav" ] && skip "no file heat support"
28449
28450         local readsample
28451         local writesample
28452         local readbyte
28453         local writebyte
28454         local readsample1
28455         local writesample1
28456         local readbyte1
28457         local writebyte1
28458
28459         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28460         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28461
28462         $LCTL set_param -n llite.*.file_heat=1
28463         echo "Turn on file heat"
28464         echo "Period second: $period_second, Decay percentage: $decay_pct"
28465
28466         echo "QQQQ" > $DIR/$tfile
28467         echo "QQQQ" > $DIR/$tfile
28468         echo "QQQQ" > $DIR/$tfile
28469         cat $DIR/$tfile > /dev/null
28470         cat $DIR/$tfile > /dev/null
28471         cat $DIR/$tfile > /dev/null
28472         cat $DIR/$tfile > /dev/null
28473
28474         local out=$($LFS heat_get $DIR/$tfile)
28475
28476         $LFS heat_get $DIR/$tfile
28477         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28478         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28479         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28480         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28481
28482         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28483         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28484         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28485         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28486
28487         sleep $((period_second + 3))
28488         echo "Sleep $((period_second + 3)) seconds..."
28489         # The recursion formula to calculate the heat of the file f is as
28490         # follow:
28491         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28492         # Where Hi is the heat value in the period between time points i*I and
28493         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28494         # to the weight of Ci.
28495         out=$($LFS heat_get $DIR/$tfile)
28496         $LFS heat_get $DIR/$tfile
28497         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28498         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28499         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28500         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28501
28502         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28503                 error "read sample ($readsample) is wrong"
28504         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28505                 error "write sample ($writesample) is wrong"
28506         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28507                 error "read bytes ($readbyte) is wrong"
28508         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28509                 error "write bytes ($writebyte) is wrong"
28510
28511         echo "QQQQ" > $DIR/$tfile
28512         echo "QQQQ" > $DIR/$tfile
28513         echo "QQQQ" > $DIR/$tfile
28514         cat $DIR/$tfile > /dev/null
28515         cat $DIR/$tfile > /dev/null
28516         cat $DIR/$tfile > /dev/null
28517         cat $DIR/$tfile > /dev/null
28518
28519         sleep $((period_second + 3))
28520         echo "Sleep $((period_second + 3)) seconds..."
28521
28522         out=$($LFS heat_get $DIR/$tfile)
28523         $LFS heat_get $DIR/$tfile
28524         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28525         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28526         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28527         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28528
28529         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28530                 4 * $decay_pct) / 100") -eq 1 ] ||
28531                 error "read sample ($readsample1) is wrong"
28532         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28533                 3 * $decay_pct) / 100") -eq 1 ] ||
28534                 error "write sample ($writesample1) is wrong"
28535         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28536                 20 * $decay_pct) / 100") -eq 1 ] ||
28537                 error "read bytes ($readbyte1) is wrong"
28538         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28539                 15 * $decay_pct) / 100") -eq 1 ] ||
28540                 error "write bytes ($writebyte1) is wrong"
28541
28542         echo "Turn off file heat for the file $DIR/$tfile"
28543         $LFS heat_set -o $DIR/$tfile
28544
28545         echo "QQQQ" > $DIR/$tfile
28546         echo "QQQQ" > $DIR/$tfile
28547         echo "QQQQ" > $DIR/$tfile
28548         cat $DIR/$tfile > /dev/null
28549         cat $DIR/$tfile > /dev/null
28550         cat $DIR/$tfile > /dev/null
28551         cat $DIR/$tfile > /dev/null
28552
28553         out=$($LFS heat_get $DIR/$tfile)
28554         $LFS heat_get $DIR/$tfile
28555         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28556         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28557         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28558         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28559
28560         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28561         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28562         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28563         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28564
28565         echo "Trun on file heat for the file $DIR/$tfile"
28566         $LFS heat_set -O $DIR/$tfile
28567
28568         echo "QQQQ" > $DIR/$tfile
28569         echo "QQQQ" > $DIR/$tfile
28570         echo "QQQQ" > $DIR/$tfile
28571         cat $DIR/$tfile > /dev/null
28572         cat $DIR/$tfile > /dev/null
28573         cat $DIR/$tfile > /dev/null
28574         cat $DIR/$tfile > /dev/null
28575
28576         out=$($LFS heat_get $DIR/$tfile)
28577         $LFS heat_get $DIR/$tfile
28578         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28579         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28580         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28581         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28582
28583         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28584         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28585         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28586         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28587
28588         $LFS heat_set -c $DIR/$tfile
28589         $LCTL set_param -n llite.*.file_heat=0
28590         echo "Turn off file heat support for the Lustre filesystem"
28591
28592         echo "QQQQ" > $DIR/$tfile
28593         echo "QQQQ" > $DIR/$tfile
28594         echo "QQQQ" > $DIR/$tfile
28595         cat $DIR/$tfile > /dev/null
28596         cat $DIR/$tfile > /dev/null
28597         cat $DIR/$tfile > /dev/null
28598         cat $DIR/$tfile > /dev/null
28599
28600         out=$($LFS heat_get $DIR/$tfile)
28601         $LFS heat_get $DIR/$tfile
28602         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28603         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28604         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28605         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28606
28607         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28608         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28609         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28610         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28611
28612         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28613         rm -f $DIR/$tfile
28614 }
28615 run_test 813 "File heat verfication"
28616
28617 test_814()
28618 {
28619         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28620         echo -n y >> $DIR/$tfile
28621         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28622         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28623 }
28624 run_test 814 "sparse cp works as expected (LU-12361)"
28625
28626 test_815()
28627 {
28628         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28629         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28630 }
28631 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28632
28633 test_816() {
28634         local ost1_imp=$(get_osc_import_name client ost1)
28635         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28636                          cut -d'.' -f2)
28637
28638         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28639         # ensure ost1 is connected
28640
28641         stat $DIR/$tfile >/dev/null || error "can't stat"
28642         wait_osc_import_state client ost1 FULL
28643         # no locks, no reqs to let the connection idle
28644         cancel_lru_locks osc
28645         lru_resize_disable osc
28646         local before
28647         local now
28648         before=$($LCTL get_param -n \
28649                  ldlm.namespaces.$imp_name.lru_size)
28650
28651         wait_osc_import_state client ost1 IDLE
28652         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28653         now=$($LCTL get_param -n \
28654               ldlm.namespaces.$imp_name.lru_size)
28655         [ $before == $now ] || error "lru_size changed $before != $now"
28656 }
28657 run_test 816 "do not reset lru_resize on idle reconnect"
28658
28659 cleanup_817() {
28660         umount $tmpdir
28661         exportfs -u localhost:$DIR/nfsexp
28662         rm -rf $DIR/nfsexp
28663 }
28664
28665 test_817() {
28666         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28667
28668         mkdir -p $DIR/nfsexp
28669         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28670                 error "failed to export nfs"
28671
28672         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28673         stack_trap cleanup_817 EXIT
28674
28675         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28676                 error "failed to mount nfs to $tmpdir"
28677
28678         cp /bin/true $tmpdir
28679         $DIR/nfsexp/true || error "failed to execute 'true' command"
28680 }
28681 run_test 817 "nfsd won't cache write lock for exec file"
28682
28683 test_818() {
28684         test_mkdir -i0 -c1 $DIR/$tdir
28685         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28686         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28687         stop $SINGLEMDS
28688
28689         # restore osp-syn threads
28690         stack_trap "fail $SINGLEMDS"
28691
28692         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28693         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28694         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28695                 error "start $SINGLEMDS failed"
28696         rm -rf $DIR/$tdir
28697
28698         local testid=$(echo $TESTNAME | tr '_' ' ')
28699
28700         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28701                 grep "run LFSCK" || error "run LFSCK is not suggested"
28702 }
28703 run_test 818 "unlink with failed llog"
28704
28705 test_819a() {
28706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28707         cancel_lru_locks osc
28708         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28709         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28710         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28711         rm -f $TDIR/$tfile
28712 }
28713 run_test 819a "too big niobuf in read"
28714
28715 test_819b() {
28716         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28717         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28718         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28719         cancel_lru_locks osc
28720         sleep 1
28721         rm -f $TDIR/$tfile
28722 }
28723 run_test 819b "too big niobuf in write"
28724
28725
28726 function test_820_start_ost() {
28727         sleep 5
28728
28729         for num in $(seq $OSTCOUNT); do
28730                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28731         done
28732 }
28733
28734 test_820() {
28735         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28736
28737         mkdir $DIR/$tdir
28738         umount_client $MOUNT || error "umount failed"
28739         for num in $(seq $OSTCOUNT); do
28740                 stop ost$num
28741         done
28742
28743         # mount client with no active OSTs
28744         # so that the client can't initialize max LOV EA size
28745         # from OSC notifications
28746         mount_client $MOUNT || error "mount failed"
28747         # delay OST starting to keep this 0 max EA size for a while
28748         test_820_start_ost &
28749
28750         # create a directory on MDS2
28751         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28752                 error "Failed to create directory"
28753         # open intent should update default EA size
28754         # see mdc_update_max_ea_from_body()
28755         # notice this is the very first RPC to MDS2
28756         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28757         ret=$?
28758         echo $out
28759         # With SSK, this situation can lead to -EPERM being returned.
28760         # In that case, simply retry.
28761         if [ $ret -ne 0 ] && $SHARED_KEY; then
28762                 if echo "$out" | grep -q "not permitted"; then
28763                         cp /etc/services $DIR/$tdir/mds2
28764                         ret=$?
28765                 fi
28766         fi
28767         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28768 }
28769 run_test 820 "update max EA from open intent"
28770
28771 test_823() {
28772         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28773         local OST_MAX_PRECREATE=20000
28774
28775         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28776                 skip "Need MDS version at least 2.14.56"
28777
28778         save_lustre_params mds1 \
28779                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28780         do_facet $SINGLEMDS "$LCTL set_param -n \
28781                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28782         do_facet $SINGLEMDS "$LCTL set_param -n \
28783                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28784
28785         stack_trap "restore_lustre_params < $p; rm $p"
28786
28787         do_facet $SINGLEMDS "$LCTL set_param -n \
28788                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28789
28790         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28791                       osp.$FSNAME-OST0000*MDT0000.create_count")
28792         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28793                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28794         local expect_count=$(((($max/2)/256) * 256))
28795
28796         log "setting create_count to 100200:"
28797         log " -result- count: $count with max: $max, expecting: $expect_count"
28798
28799         [[ $count -eq expect_count ]] ||
28800                 error "Create count not set to max precreate."
28801 }
28802 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28803
28804 test_831() {
28805         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28806                 skip "Need MDS version 2.14.56"
28807
28808         local sync_changes=$(do_facet $SINGLEMDS \
28809                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28810
28811         [ "$sync_changes" -gt 100 ] &&
28812                 skip "Sync changes $sync_changes > 100 already"
28813
28814         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28815
28816         $LFS mkdir -i 0 $DIR/$tdir
28817         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28818
28819         save_lustre_params mds1 \
28820                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28821         save_lustre_params mds1 \
28822                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28823
28824         do_facet mds1 "$LCTL set_param -n \
28825                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28826                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28827         stack_trap "restore_lustre_params < $p" EXIT
28828
28829         createmany -o $DIR/$tdir/f- 1000
28830         unlinkmany $DIR/$tdir/f- 1000 &
28831         local UNLINK_PID=$!
28832
28833         while sleep 1; do
28834                 sync_changes=$(do_facet mds1 \
28835                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28836                 # the check in the code is racy, fail the test
28837                 # if the value above the limit by 10.
28838                 [ $sync_changes -gt 110 ] && {
28839                         kill -2 $UNLINK_PID
28840                         wait
28841                         error "osp changes throttling failed, $sync_changes>110"
28842                 }
28843                 kill -0 $UNLINK_PID 2> /dev/null || break
28844         done
28845         wait
28846 }
28847 run_test 831 "throttling unlink/setattr queuing on OSP"
28848
28849 #
28850 # tests that do cleanup/setup should be run at the end
28851 #
28852
28853 test_900() {
28854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28855         local ls
28856
28857         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28858         $LCTL set_param fail_loc=0x903
28859
28860         cancel_lru_locks MGC
28861
28862         FAIL_ON_ERROR=true cleanup
28863         FAIL_ON_ERROR=true setup
28864 }
28865 run_test 900 "umount should not race with any mgc requeue thread"
28866
28867 # LUS-6253/LU-11185
28868 test_901() {
28869         local old
28870         local count
28871         local oldc
28872         local newc
28873         local olds
28874         local news
28875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28876
28877         # some get_param have a bug to handle dot in param name
28878         cancel_lru_locks MGC
28879         old=$(mount -t lustre | wc -l)
28880         # 1 config+sptlrpc
28881         # 2 params
28882         # 3 nodemap
28883         # 4 IR
28884         old=$((old * 4))
28885         oldc=0
28886         count=0
28887         while [ $old -ne $oldc ]; do
28888                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28889                 sleep 1
28890                 ((count++))
28891                 if [ $count -ge $TIMEOUT ]; then
28892                         error "too large timeout"
28893                 fi
28894         done
28895         umount_client $MOUNT || error "umount failed"
28896         mount_client $MOUNT || error "mount failed"
28897         cancel_lru_locks MGC
28898         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28899
28900         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28901
28902         return 0
28903 }
28904 run_test 901 "don't leak a mgc lock on client umount"
28905
28906 # LU-13377
28907 test_902() {
28908         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28909                 skip "client does not have LU-13377 fix"
28910         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28911         $LCTL set_param fail_loc=0x1415
28912         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28913         cancel_lru_locks osc
28914         rm -f $DIR/$tfile
28915 }
28916 run_test 902 "test short write doesn't hang lustre"
28917
28918 # LU-14711
28919 test_903() {
28920         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28921         echo "blah" > $DIR/${tfile}-2
28922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28923         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28924         $LCTL set_param fail_loc=0x417 fail_val=20
28925
28926         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28927         sleep 1 # To start the destroy
28928         wait_destroy_complete 150 || error "Destroy taking too long"
28929         cat $DIR/$tfile > /dev/null || error "Evicted"
28930 }
28931 run_test 903 "Test long page discard does not cause evictions"
28932
28933 test_904() {
28934         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28935         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28936                 grep -q project || skip "skip project quota not supported"
28937
28938         local testfile="$DIR/$tdir/$tfile"
28939         local xattr="trusted.projid"
28940         local projid
28941         local mdts=$(comma_list $(mdts_nodes))
28942         local saved=$(do_facet mds1 $LCTL get_param -n \
28943                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28944
28945         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28946         stack_trap "do_nodes $mdts $LCTL set_param \
28947                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28948
28949         mkdir -p $DIR/$tdir
28950         touch $testfile
28951         #hide projid xattr on server
28952         $LFS project -p 1 $testfile ||
28953                 error "set $testfile project id failed"
28954         getfattr -m - $testfile | grep $xattr &&
28955                 error "do not show trusted.projid when disabled on server"
28956         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28957         #should be hidden when projid is 0
28958         $LFS project -p 0 $testfile ||
28959                 error "set $testfile project id failed"
28960         getfattr -m - $testfile | grep $xattr &&
28961                 error "do not show trusted.projid with project ID 0"
28962
28963         #still can getxattr explicitly
28964         projid=$(getfattr -n $xattr $testfile |
28965                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28966         [ $projid == "0" ] ||
28967                 error "projid expected 0 not $projid"
28968
28969         #set the projid via setxattr
28970         setfattr -n $xattr -v "1000" $testfile ||
28971                 error "setattr failed with $?"
28972         projid=($($LFS project $testfile))
28973         [ ${projid[0]} == "1000" ] ||
28974                 error "projid expected 1000 not $projid"
28975
28976         #check the new projid via getxattr
28977         $LFS project -p 1001 $testfile ||
28978                 error "set $testfile project id failed"
28979         getfattr -m - $testfile | grep $xattr ||
28980                 error "should show trusted.projid when project ID != 0"
28981         projid=$(getfattr -n $xattr $testfile |
28982                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28983         [ $projid == "1001" ] ||
28984                 error "projid expected 1001 not $projid"
28985
28986         #try to set invalid projid
28987         setfattr -n $xattr -v "4294967295" $testfile &&
28988                 error "set invalid projid should fail"
28989
28990         #remove the xattr means setting projid to 0
28991         setfattr -x $xattr $testfile ||
28992                 error "setfattr failed with $?"
28993         projid=($($LFS project $testfile))
28994         [ ${projid[0]} == "0" ] ||
28995                 error "projid expected 0 not $projid"
28996
28997         #should be hidden when parent has inherit flag and same projid
28998         $LFS project -srp 1002 $DIR/$tdir ||
28999                 error "set $tdir project id failed"
29000         getfattr -m - $testfile | grep $xattr &&
29001                 error "do not show trusted.projid with inherit flag"
29002
29003         #still can getxattr explicitly
29004         projid=$(getfattr -n $xattr $testfile |
29005                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29006         [ $projid == "1002" ] ||
29007                 error "projid expected 1002 not $projid"
29008 }
29009 run_test 904 "virtual project ID xattr"
29010
29011 # LU-8582
29012 test_905() {
29013         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29014                 skip "lustre < 2.8.54 does not support ladvise"
29015
29016         remote_ost_nodsh && skip "remote OST with nodsh"
29017         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29018
29019         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29020
29021         #define OBD_FAIL_OST_OPCODE 0x253
29022         # OST_LADVISE = 21
29023         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29024         $LFS ladvise -a willread $DIR/$tfile &&
29025                 error "unexpected success of ladvise with fault injection"
29026         $LFS ladvise -a willread $DIR/$tfile |&
29027                 grep -q "Operation not supported"
29028         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29029 }
29030 run_test 905 "bad or new opcode should not stuck client"
29031
29032 test_906() {
29033         grep -q io_uring_setup /proc/kallsyms ||
29034                 skip "Client OS does not support io_uring I/O engine"
29035         io_uring_probe || skip "kernel does not support io_uring fully"
29036         which fio || skip_env "no fio installed"
29037         fio --enghelp | grep -q io_uring ||
29038                 skip_env "fio does not support io_uring I/O engine"
29039
29040         local file=$DIR/$tfile
29041         local ioengine="io_uring"
29042         local numjobs=2
29043         local size=50M
29044
29045         fio --name=seqwrite --ioengine=$ioengine        \
29046                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29047                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29048                 error "fio seqwrite $file failed"
29049
29050         fio --name=seqread --ioengine=$ioengine \
29051                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29052                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29053                 error "fio seqread $file failed"
29054
29055         rm -f $file || error "rm -f $file failed"
29056 }
29057 run_test 906 "Simple test for io_uring I/O engine via fio"
29058
29059 complete $SECONDS
29060 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29061 check_and_cleanup_lustre
29062 if [ "$I_MOUNTED" != "yes" ]; then
29063         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29064 fi
29065 exit_status