Whamcloud - gitweb
LU-16110 lprocfs: make job_stats and rename_stats valid YAML
[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_34_SIZE=${TEST_34_SIZE:-2000000000000}
4424 test_34a() {
4425         rm -f $DIR/f34
4426         $MCREATE $DIR/f34 || error "mcreate failed"
4427         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4428                 error "getstripe failed"
4429         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4430         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4431                 error "getstripe failed"
4432         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4433                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4434 }
4435 run_test 34a "truncate file that has not been opened ==========="
4436
4437 test_34b() {
4438         [ ! -f $DIR/f34 ] && test_34a
4439         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4440                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4441         $OPENFILE -f O_RDONLY $DIR/f34
4442         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4443                 error "getstripe failed"
4444         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4445                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4446 }
4447 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4448
4449 test_34c() {
4450         [ ! -f $DIR/f34 ] && test_34a
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453         $OPENFILE -f O_RDWR $DIR/f34
4454         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4455                 error "$LFS getstripe failed"
4456         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4457                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4458 }
4459 run_test 34c "O_RDWR opening file-with-size works =============="
4460
4461 test_34d() {
4462         [ ! -f $DIR/f34 ] && test_34a
4463         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4464                 error "dd failed"
4465         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4466                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4467         rm $DIR/f34
4468 }
4469 run_test 34d "write to sparse file ============================="
4470
4471 test_34e() {
4472         rm -f $DIR/f34e
4473         $MCREATE $DIR/f34e || error "mcreate failed"
4474         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4475         $CHECKSTAT -s 1000 $DIR/f34e ||
4476                 error "Size of $DIR/f34e not equal to 1000 bytes"
4477         $OPENFILE -f O_RDWR $DIR/f34e
4478         $CHECKSTAT -s 1000 $DIR/f34e ||
4479                 error "Size of $DIR/f34e not equal to 1000 bytes"
4480 }
4481 run_test 34e "create objects, some with size and some without =="
4482
4483 test_34f() { # bug 6242, 6243
4484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4485
4486         SIZE34F=48000
4487         rm -f $DIR/f34f
4488         $MCREATE $DIR/f34f || error "mcreate failed"
4489         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4490         dd if=$DIR/f34f of=$TMP/f34f
4491         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4492         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4493         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4494         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4495         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4496 }
4497 run_test 34f "read from a file with no objects until EOF ======="
4498
4499 test_34g() {
4500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4501
4502         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4503                 error "dd failed"
4504         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4505         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4506                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4507         cancel_lru_locks osc
4508         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4509                 error "wrong size after lock cancel"
4510
4511         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4512         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4513                 error "expanding truncate failed"
4514         cancel_lru_locks osc
4515         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4516                 error "wrong expanded size after lock cancel"
4517 }
4518 run_test 34g "truncate long file ==============================="
4519
4520 test_34h() {
4521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4522
4523         local gid=10
4524         local sz=1000
4525
4526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4527         sync # Flush the cache so that multiop below does not block on cache
4528              # flush when getting the group lock
4529         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4530         MULTIPID=$!
4531
4532         # Since just timed wait is not good enough, let's do a sync write
4533         # that way we are sure enough time for a roundtrip + processing
4534         # passed + 2 seconds of extra margin.
4535         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4536         rm $DIR/${tfile}-1
4537         sleep 2
4538
4539         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4540                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4541                 kill -9 $MULTIPID
4542         fi
4543         wait $MULTIPID
4544         local nsz=`stat -c %s $DIR/$tfile`
4545         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4546 }
4547 run_test 34h "ftruncate file under grouplock should not block"
4548
4549 test_35a() {
4550         cp /bin/sh $DIR/f35a
4551         chmod 444 $DIR/f35a
4552         chown $RUNAS_ID $DIR/f35a
4553         $RUNAS $DIR/f35a && error || true
4554         rm $DIR/f35a
4555 }
4556 run_test 35a "exec file with mode 444 (should return and not leak)"
4557
4558 test_36a() {
4559         rm -f $DIR/f36
4560         utime $DIR/f36 || error "utime failed for MDS"
4561 }
4562 run_test 36a "MDS utime check (mknod, utime)"
4563
4564 test_36b() {
4565         echo "" > $DIR/f36
4566         utime $DIR/f36 || error "utime failed for OST"
4567 }
4568 run_test 36b "OST utime check (open, utime)"
4569
4570 test_36c() {
4571         rm -f $DIR/d36/f36
4572         test_mkdir $DIR/d36
4573         chown $RUNAS_ID $DIR/d36
4574         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4575 }
4576 run_test 36c "non-root MDS utime check (mknod, utime)"
4577
4578 test_36d() {
4579         [ ! -d $DIR/d36 ] && test_36c
4580         echo "" > $DIR/d36/f36
4581         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4582 }
4583 run_test 36d "non-root OST utime check (open, utime)"
4584
4585 test_36e() {
4586         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4587
4588         test_mkdir $DIR/$tdir
4589         touch $DIR/$tdir/$tfile
4590         $RUNAS utime $DIR/$tdir/$tfile &&
4591                 error "utime worked, expected failure" || true
4592 }
4593 run_test 36e "utime on non-owned file (should return error)"
4594
4595 subr_36fh() {
4596         local fl="$1"
4597         local LANG_SAVE=$LANG
4598         local LC_LANG_SAVE=$LC_LANG
4599         export LANG=C LC_LANG=C # for date language
4600
4601         DATESTR="Dec 20  2000"
4602         test_mkdir $DIR/$tdir
4603         lctl set_param fail_loc=$fl
4604         date; date +%s
4605         cp /etc/hosts $DIR/$tdir/$tfile
4606         sync & # write RPC generated with "current" inode timestamp, but delayed
4607         sleep 1
4608         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4609         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4610         cancel_lru_locks $OSC
4611         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4612         date; date +%s
4613         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4614                 echo "BEFORE: $LS_BEFORE" && \
4615                 echo "AFTER : $LS_AFTER" && \
4616                 echo "WANT  : $DATESTR" && \
4617                 error "$DIR/$tdir/$tfile timestamps changed" || true
4618
4619         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4620 }
4621
4622 test_36f() {
4623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4624
4625         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4626         subr_36fh "0x80000214"
4627 }
4628 run_test 36f "utime on file racing with OST BRW write =========="
4629
4630 test_36g() {
4631         remote_ost_nodsh && skip "remote OST with nodsh"
4632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4633         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4634                 skip "Need MDS version at least 2.12.51"
4635
4636         local fmd_max_age
4637         local fmd
4638         local facet="ost1"
4639         local tgt="obdfilter"
4640
4641         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4642
4643         test_mkdir $DIR/$tdir
4644         fmd_max_age=$(do_facet $facet \
4645                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4646                 head -n 1")
4647
4648         echo "FMD max age: ${fmd_max_age}s"
4649         touch $DIR/$tdir/$tfile
4650         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4651                 gawk '{cnt=cnt+$1}  END{print cnt}')
4652         echo "FMD before: $fmd"
4653         [[ $fmd == 0 ]] &&
4654                 error "FMD wasn't create by touch"
4655         sleep $((fmd_max_age + 12))
4656         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4657                 gawk '{cnt=cnt+$1}  END{print cnt}')
4658         echo "FMD after: $fmd"
4659         [[ $fmd == 0 ]] ||
4660                 error "FMD wasn't expired by ping"
4661 }
4662 run_test 36g "FMD cache expiry ====================="
4663
4664 test_36h() {
4665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4666
4667         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4668         subr_36fh "0x80000227"
4669 }
4670 run_test 36h "utime on file racing with OST BRW write =========="
4671
4672 test_36i() {
4673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4674
4675         test_mkdir $DIR/$tdir
4676         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4677
4678         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4679         local new_mtime=$((mtime + 200))
4680
4681         #change Modify time of striped dir
4682         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4683                         error "change mtime failed"
4684
4685         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4686
4687         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4688 }
4689 run_test 36i "change mtime on striped directory"
4690
4691 # test_37 - duplicate with tests 32q 32r
4692
4693 test_38() {
4694         local file=$DIR/$tfile
4695         touch $file
4696         openfile -f O_DIRECTORY $file
4697         local RC=$?
4698         local ENOTDIR=20
4699         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4700         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4701 }
4702 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4703
4704 test_39a() { # was test_39
4705         touch $DIR/$tfile
4706         touch $DIR/${tfile}2
4707 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4708 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4709 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4710         sleep 2
4711         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4712         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4713                 echo "mtime"
4714                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4715                 echo "atime"
4716                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4717                 echo "ctime"
4718                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4719                 error "O_TRUNC didn't change timestamps"
4720         fi
4721 }
4722 run_test 39a "mtime changed on create"
4723
4724 test_39b() {
4725         test_mkdir -c1 $DIR/$tdir
4726         cp -p /etc/passwd $DIR/$tdir/fopen
4727         cp -p /etc/passwd $DIR/$tdir/flink
4728         cp -p /etc/passwd $DIR/$tdir/funlink
4729         cp -p /etc/passwd $DIR/$tdir/frename
4730         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4731
4732         sleep 1
4733         echo "aaaaaa" >> $DIR/$tdir/fopen
4734         echo "aaaaaa" >> $DIR/$tdir/flink
4735         echo "aaaaaa" >> $DIR/$tdir/funlink
4736         echo "aaaaaa" >> $DIR/$tdir/frename
4737
4738         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4739         local link_new=`stat -c %Y $DIR/$tdir/flink`
4740         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4741         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4742
4743         cat $DIR/$tdir/fopen > /dev/null
4744         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4745         rm -f $DIR/$tdir/funlink2
4746         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4750                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4751                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4752                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4753
4754                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4755                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4756                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4757                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39b "mtime change on open, link, unlink, rename  ======"
4764
4765 # this should be set to past
4766 TEST_39_MTIME=`date -d "1 year ago" +%s`
4767
4768 # bug 11063
4769 test_39c() {
4770         touch $DIR1/$tfile
4771         sleep 2
4772         local mtime0=`stat -c %Y $DIR1/$tfile`
4773
4774         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4775         local mtime1=`stat -c %Y $DIR1/$tfile`
4776         [ "$mtime1" = $TEST_39_MTIME ] || \
4777                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4778
4779         local d1=`date +%s`
4780         echo hello >> $DIR1/$tfile
4781         local d2=`date +%s`
4782         local mtime2=`stat -c %Y $DIR1/$tfile`
4783         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4784                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4785
4786         mv $DIR1/$tfile $DIR1/$tfile-1
4787
4788         for (( i=0; i < 2; i++ )) ; do
4789                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4790                 [ "$mtime2" = "$mtime3" ] || \
4791                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4792
4793                 cancel_lru_locks $OSC
4794                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4795         done
4796 }
4797 run_test 39c "mtime change on rename ==========================="
4798
4799 # bug 21114
4800 test_39d() {
4801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4802
4803         touch $DIR1/$tfile
4804         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4805
4806         for (( i=0; i < 2; i++ )) ; do
4807                 local mtime=`stat -c %Y $DIR1/$tfile`
4808                 [ $mtime = $TEST_39_MTIME ] || \
4809                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4810
4811                 cancel_lru_locks $OSC
4812                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4813         done
4814 }
4815 run_test 39d "create, utime, stat =============================="
4816
4817 # bug 21114
4818 test_39e() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         touch $DIR1/$tfile
4822         local mtime1=`stat -c %Y $DIR1/$tfile`
4823
4824         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4825
4826         for (( i=0; i < 2; i++ )) ; do
4827                 local mtime2=`stat -c %Y $DIR1/$tfile`
4828                 [ $mtime2 = $TEST_39_MTIME ] || \
4829                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4830
4831                 cancel_lru_locks $OSC
4832                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4833         done
4834 }
4835 run_test 39e "create, stat, utime, stat ========================"
4836
4837 # bug 21114
4838 test_39f() {
4839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4840
4841         touch $DIR1/$tfile
4842         mtime1=`stat -c %Y $DIR1/$tfile`
4843
4844         sleep 2
4845         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4846
4847         for (( i=0; i < 2; i++ )) ; do
4848                 local mtime2=`stat -c %Y $DIR1/$tfile`
4849                 [ $mtime2 = $TEST_39_MTIME ] || \
4850                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4851
4852                 cancel_lru_locks $OSC
4853                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4854         done
4855 }
4856 run_test 39f "create, stat, sleep, utime, stat ================="
4857
4858 # bug 11063
4859 test_39g() {
4860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4861
4862         echo hello >> $DIR1/$tfile
4863         local mtime1=`stat -c %Y $DIR1/$tfile`
4864
4865         sleep 2
4866         chmod o+r $DIR1/$tfile
4867
4868         for (( i=0; i < 2; i++ )) ; do
4869                 local mtime2=`stat -c %Y $DIR1/$tfile`
4870                 [ "$mtime1" = "$mtime2" ] || \
4871                         error "lost mtime: $mtime2, should be $mtime1"
4872
4873                 cancel_lru_locks $OSC
4874                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4875         done
4876 }
4877 run_test 39g "write, chmod, stat ==============================="
4878
4879 # bug 11063
4880 test_39h() {
4881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4882
4883         touch $DIR1/$tfile
4884         sleep 1
4885
4886         local d1=`date`
4887         echo hello >> $DIR1/$tfile
4888         local mtime1=`stat -c %Y $DIR1/$tfile`
4889
4890         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4891         local d2=`date`
4892         if [ "$d1" != "$d2" ]; then
4893                 echo "write and touch not within one second"
4894         else
4895                 for (( i=0; i < 2; i++ )) ; do
4896                         local mtime2=`stat -c %Y $DIR1/$tfile`
4897                         [ "$mtime2" = $TEST_39_MTIME ] || \
4898                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4899
4900                         cancel_lru_locks $OSC
4901                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902                 done
4903         fi
4904 }
4905 run_test 39h "write, utime within one second, stat ============="
4906
4907 test_39i() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         sleep 1
4912
4913         echo hello >> $DIR1/$tfile
4914         local mtime1=`stat -c %Y $DIR1/$tfile`
4915
4916         mv $DIR1/$tfile $DIR1/$tfile-1
4917
4918         for (( i=0; i < 2; i++ )) ; do
4919                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4920
4921                 [ "$mtime1" = "$mtime2" ] || \
4922                         error "lost mtime: $mtime2, should be $mtime1"
4923
4924                 cancel_lru_locks $OSC
4925                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4926         done
4927 }
4928 run_test 39i "write, rename, stat =============================="
4929
4930 test_39j() {
4931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4932
4933         start_full_debug_logging
4934         touch $DIR1/$tfile
4935         sleep 1
4936
4937         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4938         lctl set_param fail_loc=0x80000412
4939         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4940                 error "multiop failed"
4941         local multipid=$!
4942         local mtime1=`stat -c %Y $DIR1/$tfile`
4943
4944         mv $DIR1/$tfile $DIR1/$tfile-1
4945
4946         kill -USR1 $multipid
4947         wait $multipid || error "multiop close failed"
4948
4949         for (( i=0; i < 2; i++ )) ; do
4950                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4951                 [ "$mtime1" = "$mtime2" ] ||
4952                         error "mtime is lost on close: $mtime2, " \
4953                               "should be $mtime1"
4954
4955                 cancel_lru_locks
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958         lctl set_param fail_loc=0
4959         stop_full_debug_logging
4960 }
4961 run_test 39j "write, rename, close, stat ======================="
4962
4963 test_39k() {
4964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4965
4966         touch $DIR1/$tfile
4967         sleep 1
4968
4969         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4970         local multipid=$!
4971         local mtime1=`stat -c %Y $DIR1/$tfile`
4972
4973         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4974
4975         kill -USR1 $multipid
4976         wait $multipid || error "multiop close failed"
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile`
4980
4981                 [ "$mtime2" = $TEST_39_MTIME ] || \
4982                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4983
4984                 cancel_lru_locks
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39k "write, utime, close, stat ========================"
4989
4990 # this should be set to future
4991 TEST_39_ATIME=`date -d "1 year" +%s`
4992
4993 test_39l() {
4994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4995         remote_mds_nodsh && skip "remote MDS with nodsh"
4996
4997         local atime_diff=$(do_facet $SINGLEMDS \
4998                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4999         rm -rf $DIR/$tdir
5000         mkdir_on_mdt0 $DIR/$tdir
5001
5002         # test setting directory atime to future
5003         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5004         local atime=$(stat -c %X $DIR/$tdir)
5005         [ "$atime" = $TEST_39_ATIME ] ||
5006                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5007
5008         # test setting directory atime from future to now
5009         local now=$(date +%s)
5010         touch -a -d @$now $DIR/$tdir
5011
5012         atime=$(stat -c %X $DIR/$tdir)
5013         [ "$atime" -eq "$now"  ] ||
5014                 error "atime is not updated from future: $atime, $now"
5015
5016         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5017         sleep 3
5018
5019         # test setting directory atime when now > dir atime + atime_diff
5020         local d1=$(date +%s)
5021         ls $DIR/$tdir
5022         local d2=$(date +%s)
5023         cancel_lru_locks mdc
5024         atime=$(stat -c %X $DIR/$tdir)
5025         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5026                 error "atime is not updated  : $atime, should be $d2"
5027
5028         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5029         sleep 3
5030
5031         # test not setting directory atime when now < dir atime + atime_diff
5032         ls $DIR/$tdir
5033         cancel_lru_locks mdc
5034         atime=$(stat -c %X $DIR/$tdir)
5035         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5036                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5037
5038         do_facet $SINGLEMDS \
5039                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5040 }
5041 run_test 39l "directory atime update ==========================="
5042
5043 test_39m() {
5044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5045
5046         touch $DIR1/$tfile
5047         sleep 2
5048         local far_past_mtime=$(date -d "May 29 1953" +%s)
5049         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5050
5051         touch -m -d @$far_past_mtime $DIR1/$tfile
5052         touch -a -d @$far_past_atime $DIR1/$tfile
5053
5054         for (( i=0; i < 2; i++ )) ; do
5055                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5056                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5057                         error "atime or mtime set incorrectly"
5058
5059                 cancel_lru_locks $OSC
5060                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5061         done
5062 }
5063 run_test 39m "test atime and mtime before 1970"
5064
5065 test_39n() { # LU-3832
5066         remote_mds_nodsh && skip "remote MDS with nodsh"
5067
5068         local atime_diff=$(do_facet $SINGLEMDS \
5069                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5070         local atime0
5071         local atime1
5072         local atime2
5073
5074         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5075
5076         rm -rf $DIR/$tfile
5077         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5078         atime0=$(stat -c %X $DIR/$tfile)
5079
5080         sleep 5
5081         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5082         atime1=$(stat -c %X $DIR/$tfile)
5083
5084         sleep 5
5085         cancel_lru_locks mdc
5086         cancel_lru_locks osc
5087         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5088         atime2=$(stat -c %X $DIR/$tfile)
5089
5090         do_facet $SINGLEMDS \
5091                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5092
5093         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5094         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5095 }
5096 run_test 39n "check that O_NOATIME is honored"
5097
5098 test_39o() {
5099         TESTDIR=$DIR/$tdir/$tfile
5100         [ -e $TESTDIR ] && rm -rf $TESTDIR
5101         mkdir -p $TESTDIR
5102         cd $TESTDIR
5103         links1=2
5104         ls
5105         mkdir a b
5106         ls
5107         links2=$(stat -c %h .)
5108         [ $(($links1 + 2)) != $links2 ] &&
5109                 error "wrong links count $(($links1 + 2)) != $links2"
5110         rmdir b
5111         links3=$(stat -c %h .)
5112         [ $(($links1 + 1)) != $links3 ] &&
5113                 error "wrong links count $links1 != $links3"
5114         return 0
5115 }
5116 run_test 39o "directory cached attributes updated after create"
5117
5118 test_39p() {
5119         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5120
5121         local MDTIDX=1
5122         TESTDIR=$DIR/$tdir/$tdir
5123         [ -e $TESTDIR ] && rm -rf $TESTDIR
5124         test_mkdir -p $TESTDIR
5125         cd $TESTDIR
5126         links1=2
5127         ls
5128         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5129         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5130         ls
5131         links2=$(stat -c %h .)
5132         [ $(($links1 + 2)) != $links2 ] &&
5133                 error "wrong links count $(($links1 + 2)) != $links2"
5134         rmdir remote_dir2
5135         links3=$(stat -c %h .)
5136         [ $(($links1 + 1)) != $links3 ] &&
5137                 error "wrong links count $links1 != $links3"
5138         return 0
5139 }
5140 run_test 39p "remote directory cached attributes updated after create ========"
5141
5142 test_39r() {
5143         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5144                 skip "no atime update on old OST"
5145         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5146                 skip_env "ldiskfs only test"
5147         fi
5148
5149         local saved_adiff
5150         saved_adiff=$(do_facet ost1 \
5151                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5152         stack_trap "do_facet ost1 \
5153                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5154
5155         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5156
5157         $LFS setstripe -i 0 $DIR/$tfile
5158         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5159                 error "can't write initial file"
5160         cancel_lru_locks osc
5161
5162         # exceed atime_diff and access file
5163         sleep 10
5164         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5165                 error "can't udpate atime"
5166
5167         local atime_cli=$(stat -c %X $DIR/$tfile)
5168         echo "client atime: $atime_cli"
5169         # allow atime update to be written to device
5170         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5171         sleep 5
5172
5173         local ostdev=$(ostdevname 1)
5174         local fid=($(lfs getstripe -y $DIR/$tfile |
5175                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5176         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5177         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5178
5179         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5180         local atime_ost=$(do_facet ost1 "$cmd" |&
5181                           awk -F'[: ]' '/atime:/ { print $4 }')
5182         (( atime_cli == atime_ost )) ||
5183                 error "atime on client $atime_cli != ost $atime_ost"
5184 }
5185 run_test 39r "lazy atime update on OST"
5186
5187 test_39q() { # LU-8041
5188         local testdir=$DIR/$tdir
5189         mkdir -p $testdir
5190         multiop_bg_pause $testdir D_c || error "multiop failed"
5191         local multipid=$!
5192         cancel_lru_locks mdc
5193         kill -USR1 $multipid
5194         local atime=$(stat -c %X $testdir)
5195         [ "$atime" -ne 0 ] || error "atime is zero"
5196 }
5197 run_test 39q "close won't zero out atime"
5198
5199 test_40() {
5200         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5201         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5202                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5203         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5204                 error "$tfile is not 4096 bytes in size"
5205 }
5206 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5207
5208 test_41() {
5209         # bug 1553
5210         small_write $DIR/f41 18
5211 }
5212 run_test 41 "test small file write + fstat ====================="
5213
5214 count_ost_writes() {
5215         lctl get_param -n ${OSC}.*.stats |
5216                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5217                         END { printf("%0.0f", writes) }'
5218 }
5219
5220 # decent default
5221 WRITEBACK_SAVE=500
5222 DIRTY_RATIO_SAVE=40
5223 MAX_DIRTY_RATIO=50
5224 BG_DIRTY_RATIO_SAVE=10
5225 MAX_BG_DIRTY_RATIO=25
5226
5227 start_writeback() {
5228         trap 0
5229         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5230         # dirty_ratio, dirty_background_ratio
5231         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5232                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5233                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5234                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5235         else
5236                 # if file not here, we are a 2.4 kernel
5237                 kill -CONT `pidof kupdated`
5238         fi
5239 }
5240
5241 stop_writeback() {
5242         # setup the trap first, so someone cannot exit the test at the
5243         # exact wrong time and mess up a machine
5244         trap start_writeback EXIT
5245         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5246         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5247                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5248                 sysctl -w vm.dirty_writeback_centisecs=0
5249                 sysctl -w vm.dirty_writeback_centisecs=0
5250                 # save and increase /proc/sys/vm/dirty_ratio
5251                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5252                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5253                 # save and increase /proc/sys/vm/dirty_background_ratio
5254                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5255                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5256         else
5257                 # if file not here, we are a 2.4 kernel
5258                 kill -STOP `pidof kupdated`
5259         fi
5260 }
5261
5262 # ensure that all stripes have some grant before we test client-side cache
5263 setup_test42() {
5264         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5265                 dd if=/dev/zero of=$i bs=4k count=1
5266                 rm $i
5267         done
5268 }
5269
5270 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5271 # file truncation, and file removal.
5272 test_42a() {
5273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5274
5275         setup_test42
5276         cancel_lru_locks $OSC
5277         stop_writeback
5278         sync; sleep 1; sync # just to be safe
5279         BEFOREWRITES=`count_ost_writes`
5280         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5281         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5282         AFTERWRITES=`count_ost_writes`
5283         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5284                 error "$BEFOREWRITES < $AFTERWRITES"
5285         start_writeback
5286 }
5287 run_test 42a "ensure that we don't flush on close"
5288
5289 test_42b() {
5290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5291
5292         setup_test42
5293         cancel_lru_locks $OSC
5294         stop_writeback
5295         sync
5296         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5297         BEFOREWRITES=$(count_ost_writes)
5298         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5299         AFTERWRITES=$(count_ost_writes)
5300         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5301                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5302         fi
5303         BEFOREWRITES=$(count_ost_writes)
5304         sync || error "sync: $?"
5305         AFTERWRITES=$(count_ost_writes)
5306         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5307                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5308         fi
5309         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5310         start_writeback
5311         return 0
5312 }
5313 run_test 42b "test destroy of file with cached dirty data ======"
5314
5315 # if these tests just want to test the effect of truncation,
5316 # they have to be very careful.  consider:
5317 # - the first open gets a {0,EOF}PR lock
5318 # - the first write conflicts and gets a {0, count-1}PW
5319 # - the rest of the writes are under {count,EOF}PW
5320 # - the open for truncate tries to match a {0,EOF}PR
5321 #   for the filesize and cancels the PWs.
5322 # any number of fixes (don't get {0,EOF} on open, match
5323 # composite locks, do smarter file size management) fix
5324 # this, but for now we want these tests to verify that
5325 # the cancellation with truncate intent works, so we
5326 # start the file with a full-file pw lock to match against
5327 # until the truncate.
5328 trunc_test() {
5329         test=$1
5330         file=$DIR/$test
5331         offset=$2
5332         cancel_lru_locks $OSC
5333         stop_writeback
5334         # prime the file with 0,EOF PW to match
5335         touch $file
5336         $TRUNCATE $file 0
5337         sync; sync
5338         # now the real test..
5339         dd if=/dev/zero of=$file bs=1024 count=100
5340         BEFOREWRITES=`count_ost_writes`
5341         $TRUNCATE $file $offset
5342         cancel_lru_locks $OSC
5343         AFTERWRITES=`count_ost_writes`
5344         start_writeback
5345 }
5346
5347 test_42c() {
5348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5349
5350         trunc_test 42c 1024
5351         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5352                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5353         rm $file
5354 }
5355 run_test 42c "test partial truncate of file with cached dirty data"
5356
5357 test_42d() {
5358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5359
5360         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5361         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5362         $LCTL set_param debug=+cache
5363
5364         trunc_test 42d 0
5365         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5366                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5367         rm $file
5368 }
5369 run_test 42d "test complete truncate of file with cached dirty data"
5370
5371 test_42e() { # bug22074
5372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5373
5374         local TDIR=$DIR/${tdir}e
5375         local pages=16 # hardcoded 16 pages, don't change it.
5376         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5377         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5378         local max_dirty_mb
5379         local warmup_files
5380
5381         test_mkdir $DIR/${tdir}e
5382         $LFS setstripe -c 1 $TDIR
5383         createmany -o $TDIR/f $files
5384
5385         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5386
5387         # we assume that with $OSTCOUNT files, at least one of them will
5388         # be allocated on OST0.
5389         warmup_files=$((OSTCOUNT * max_dirty_mb))
5390         createmany -o $TDIR/w $warmup_files
5391
5392         # write a large amount of data into one file and sync, to get good
5393         # avail_grant number from OST.
5394         for ((i=0; i<$warmup_files; i++)); do
5395                 idx=$($LFS getstripe -i $TDIR/w$i)
5396                 [ $idx -ne 0 ] && continue
5397                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5398                 break
5399         done
5400         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5401         sync
5402         $LCTL get_param $proc_osc0/cur_dirty_bytes
5403         $LCTL get_param $proc_osc0/cur_grant_bytes
5404
5405         # create as much dirty pages as we can while not to trigger the actual
5406         # RPCs directly. but depends on the env, VFS may trigger flush during this
5407         # period, hopefully we are good.
5408         for ((i=0; i<$warmup_files; i++)); do
5409                 idx=$($LFS getstripe -i $TDIR/w$i)
5410                 [ $idx -ne 0 ] && continue
5411                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5412         done
5413         $LCTL get_param $proc_osc0/cur_dirty_bytes
5414         $LCTL get_param $proc_osc0/cur_grant_bytes
5415
5416         # perform the real test
5417         $LCTL set_param $proc_osc0/rpc_stats 0
5418         for ((;i<$files; i++)); do
5419                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5420                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5421         done
5422         sync
5423         $LCTL get_param $proc_osc0/rpc_stats
5424
5425         local percent=0
5426         local have_ppr=false
5427         $LCTL get_param $proc_osc0/rpc_stats |
5428                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5429                         # skip lines until we are at the RPC histogram data
5430                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5431                         $have_ppr || continue
5432
5433                         # we only want the percent stat for < 16 pages
5434                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5435
5436                         percent=$((percent + WPCT))
5437                         if [[ $percent -gt 15 ]]; then
5438                                 error "less than 16-pages write RPCs" \
5439                                       "$percent% > 15%"
5440                                 break
5441                         fi
5442                 done
5443         rm -rf $TDIR
5444 }
5445 run_test 42e "verify sub-RPC writes are not done synchronously"
5446
5447 test_43A() { # was test_43
5448         test_mkdir $DIR/$tdir
5449         cp -p /bin/ls $DIR/$tdir/$tfile
5450         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5451         pid=$!
5452         # give multiop a chance to open
5453         sleep 1
5454
5455         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5456         kill -USR1 $pid
5457         # Wait for multiop to exit
5458         wait $pid
5459 }
5460 run_test 43A "execution of file opened for write should return -ETXTBSY"
5461
5462 test_43a() {
5463         test_mkdir $DIR/$tdir
5464         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5465         $DIR/$tdir/sleep 60 &
5466         SLEEP_PID=$!
5467         # Make sure exec of $tdir/sleep wins race with truncate
5468         sleep 1
5469         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5470         kill $SLEEP_PID
5471 }
5472 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5473
5474 test_43b() {
5475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5476
5477         test_mkdir $DIR/$tdir
5478         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5479         $DIR/$tdir/sleep 60 &
5480         SLEEP_PID=$!
5481         # Make sure exec of $tdir/sleep wins race with truncate
5482         sleep 1
5483         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5484         kill $SLEEP_PID
5485 }
5486 run_test 43b "truncate of file being executed should return -ETXTBSY"
5487
5488 test_43c() {
5489         local testdir="$DIR/$tdir"
5490         test_mkdir $testdir
5491         cp $SHELL $testdir/
5492         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5493                 ( cd $testdir && md5sum -c )
5494 }
5495 run_test 43c "md5sum of copy into lustre"
5496
5497 test_44A() { # was test_44
5498         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5499
5500         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5501         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5502 }
5503 run_test 44A "zero length read from a sparse stripe"
5504
5505 test_44a() {
5506         local nstripe=$($LFS getstripe -c -d $DIR)
5507         [ -z "$nstripe" ] && skip "can't get stripe info"
5508         [[ $nstripe -gt $OSTCOUNT ]] &&
5509                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5510
5511         local stride=$($LFS getstripe -S -d $DIR)
5512         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5513                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5514         fi
5515
5516         OFFSETS="0 $((stride/2)) $((stride-1))"
5517         for offset in $OFFSETS; do
5518                 for i in $(seq 0 $((nstripe-1))); do
5519                         local GLOBALOFFSETS=""
5520                         # size in Bytes
5521                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5522                         local myfn=$DIR/d44a-$size
5523                         echo "--------writing $myfn at $size"
5524                         ll_sparseness_write $myfn $size ||
5525                                 error "ll_sparseness_write"
5526                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5527                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5528                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5529
5530                         for j in $(seq 0 $((nstripe-1))); do
5531                                 # size in Bytes
5532                                 size=$((((j + $nstripe )*$stride + $offset)))
5533                                 ll_sparseness_write $myfn $size ||
5534                                         error "ll_sparseness_write"
5535                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5536                         done
5537                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5538                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5539                         rm -f $myfn
5540                 done
5541         done
5542 }
5543 run_test 44a "test sparse pwrite ==============================="
5544
5545 dirty_osc_total() {
5546         tot=0
5547         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5548                 tot=$(($tot + $d))
5549         done
5550         echo $tot
5551 }
5552 do_dirty_record() {
5553         before=`dirty_osc_total`
5554         echo executing "\"$*\""
5555         eval $*
5556         after=`dirty_osc_total`
5557         echo before $before, after $after
5558 }
5559 test_45() {
5560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5561
5562         f="$DIR/f45"
5563         # Obtain grants from OST if it supports it
5564         echo blah > ${f}_grant
5565         stop_writeback
5566         sync
5567         do_dirty_record "echo blah > $f"
5568         [[ $before -eq $after ]] && error "write wasn't cached"
5569         do_dirty_record "> $f"
5570         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5571         do_dirty_record "echo blah > $f"
5572         [[ $before -eq $after ]] && error "write wasn't cached"
5573         do_dirty_record "sync"
5574         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5575         do_dirty_record "echo blah > $f"
5576         [[ $before -eq $after ]] && error "write wasn't cached"
5577         do_dirty_record "cancel_lru_locks osc"
5578         [[ $before -gt $after ]] ||
5579                 error "lock cancellation didn't lower dirty count"
5580         start_writeback
5581 }
5582 run_test 45 "osc io page accounting ============================"
5583
5584 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5585 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5586 # objects offset and an assert hit when an rpc was built with 1023's mapped
5587 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5588 test_46() {
5589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5590
5591         f="$DIR/f46"
5592         stop_writeback
5593         sync
5594         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5595         sync
5596         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5597         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5598         sync
5599         start_writeback
5600 }
5601 run_test 46 "dirtying a previously written page ================"
5602
5603 # test_47 is removed "Device nodes check" is moved to test_28
5604
5605 test_48a() { # bug 2399
5606         [ "$mds1_FSTYPE" = "zfs" ] &&
5607         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5608                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5609
5610         test_mkdir $DIR/$tdir
5611         cd $DIR/$tdir
5612         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5613         test_mkdir $DIR/$tdir
5614         touch foo || error "'touch foo' failed after recreating cwd"
5615         test_mkdir bar
5616         touch .foo || error "'touch .foo' failed after recreating cwd"
5617         test_mkdir .bar
5618         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5619         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5620         cd . || error "'cd .' failed after recreating cwd"
5621         mkdir . && error "'mkdir .' worked after recreating cwd"
5622         rmdir . && error "'rmdir .' worked after recreating cwd"
5623         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5624         cd .. || error "'cd ..' failed after recreating cwd"
5625 }
5626 run_test 48a "Access renamed working dir (should return errors)="
5627
5628 test_48b() { # bug 2399
5629         rm -rf $DIR/$tdir
5630         test_mkdir $DIR/$tdir
5631         cd $DIR/$tdir
5632         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5633         touch foo && error "'touch foo' worked after removing cwd"
5634         mkdir foo && error "'mkdir foo' worked after removing cwd"
5635         touch .foo && error "'touch .foo' worked after removing cwd"
5636         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5637         ls . > /dev/null && error "'ls .' worked after removing cwd"
5638         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5639         mkdir . && error "'mkdir .' worked after removing cwd"
5640         rmdir . && error "'rmdir .' worked after removing cwd"
5641         ln -s . foo && error "'ln -s .' worked after removing cwd"
5642         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5643 }
5644 run_test 48b "Access removed working dir (should return errors)="
5645
5646 test_48c() { # bug 2350
5647         #lctl set_param debug=-1
5648         #set -vx
5649         rm -rf $DIR/$tdir
5650         test_mkdir -p $DIR/$tdir/dir
5651         cd $DIR/$tdir/dir
5652         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5653         $TRACE touch foo && error "touch foo worked after removing cwd"
5654         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5655         touch .foo && error "touch .foo worked after removing cwd"
5656         mkdir .foo && error "mkdir .foo worked after removing cwd"
5657         $TRACE ls . && error "'ls .' worked after removing cwd"
5658         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5659         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5660         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5661         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5662         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5663 }
5664 run_test 48c "Access removed working subdir (should return errors)"
5665
5666 test_48d() { # bug 2350
5667         #lctl set_param debug=-1
5668         #set -vx
5669         rm -rf $DIR/$tdir
5670         test_mkdir -p $DIR/$tdir/dir
5671         cd $DIR/$tdir/dir
5672         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5673         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5674         $TRACE touch foo && error "'touch foo' worked after removing parent"
5675         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5676         touch .foo && error "'touch .foo' worked after removing parent"
5677         mkdir .foo && error "mkdir .foo worked after removing parent"
5678         $TRACE ls . && error "'ls .' worked after removing parent"
5679         $TRACE ls .. && error "'ls ..' worked after removing parent"
5680         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5681         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5682         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5683         true
5684 }
5685 run_test 48d "Access removed parent subdir (should return errors)"
5686
5687 test_48e() { # bug 4134
5688         #lctl set_param debug=-1
5689         #set -vx
5690         rm -rf $DIR/$tdir
5691         test_mkdir -p $DIR/$tdir/dir
5692         cd $DIR/$tdir/dir
5693         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5694         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5695         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5696         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5697         # On a buggy kernel addition of "touch foo" after cd .. will
5698         # produce kernel oops in lookup_hash_it
5699         touch ../foo && error "'cd ..' worked after recreate parent"
5700         cd $DIR
5701         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5702 }
5703 run_test 48e "Access to recreated parent subdir (should return errors)"
5704
5705 test_48f() {
5706         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5707                 skip "need MDS >= 2.13.55"
5708         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5709         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5710                 skip "needs different host for mdt1 mdt2"
5711         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5712
5713         $LFS mkdir -i0 $DIR/$tdir
5714         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5715
5716         for d in sub1 sub2 sub3; do
5717                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5718                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5719                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5720         done
5721
5722         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5723 }
5724 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5725
5726 test_49() { # LU-1030
5727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5728         remote_ost_nodsh && skip "remote OST with nodsh"
5729
5730         # get ost1 size - $FSNAME-OST0000
5731         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5732                 awk '{ print $4 }')
5733         # write 800M at maximum
5734         [[ $ost1_size -lt 2 ]] && ost1_size=2
5735         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5736
5737         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5738         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5739         local dd_pid=$!
5740
5741         # change max_pages_per_rpc while writing the file
5742         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5743         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5744         # loop until dd process exits
5745         while ps ax -opid | grep -wq $dd_pid; do
5746                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5747                 sleep $((RANDOM % 5 + 1))
5748         done
5749         # restore original max_pages_per_rpc
5750         $LCTL set_param $osc1_mppc=$orig_mppc
5751         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5752 }
5753 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5754
5755 test_50() {
5756         # bug 1485
5757         test_mkdir $DIR/$tdir
5758         cd $DIR/$tdir
5759         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5760 }
5761 run_test 50 "special situations: /proc symlinks  ==============="
5762
5763 test_51a() {    # was test_51
5764         # bug 1516 - create an empty entry right after ".." then split dir
5765         test_mkdir -c1 $DIR/$tdir
5766         touch $DIR/$tdir/foo
5767         $MCREATE $DIR/$tdir/bar
5768         rm $DIR/$tdir/foo
5769         createmany -m $DIR/$tdir/longfile 201
5770         FNUM=202
5771         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5772                 $MCREATE $DIR/$tdir/longfile$FNUM
5773                 FNUM=$(($FNUM + 1))
5774                 echo -n "+"
5775         done
5776         echo
5777         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5778 }
5779 run_test 51a "special situations: split htree with empty entry =="
5780
5781 cleanup_print_lfs_df () {
5782         trap 0
5783         $LFS df
5784         $LFS df -i
5785 }
5786
5787 test_51b() {
5788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5789
5790         local dir=$DIR/$tdir
5791         local nrdirs=$((65536 + 100))
5792
5793         # cleanup the directory
5794         rm -fr $dir
5795
5796         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5797
5798         $LFS df
5799         $LFS df -i
5800         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5801         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5802         [[ $numfree -lt $nrdirs ]] &&
5803                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5804
5805         # need to check free space for the directories as well
5806         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5807         numfree=$(( blkfree / $(fs_inode_ksize) ))
5808         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5809
5810         trap cleanup_print_lfs_df EXIT
5811
5812         # create files
5813         createmany -d $dir/d $nrdirs || {
5814                 unlinkmany $dir/d $nrdirs
5815                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5816         }
5817
5818         # really created :
5819         nrdirs=$(ls -U $dir | wc -l)
5820
5821         # unlink all but 100 subdirectories, then check it still works
5822         local left=100
5823         local delete=$((nrdirs - left))
5824
5825         $LFS df
5826         $LFS df -i
5827
5828         # for ldiskfs the nlink count should be 1, but this is OSD specific
5829         # and so this is listed for informational purposes only
5830         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5831         unlinkmany -d $dir/d $delete ||
5832                 error "unlink of first $delete subdirs failed"
5833
5834         echo "nlink between: $(stat -c %h $dir)"
5835         local found=$(ls -U $dir | wc -l)
5836         [ $found -ne $left ] &&
5837                 error "can't find subdirs: found only $found, expected $left"
5838
5839         unlinkmany -d $dir/d $delete $left ||
5840                 error "unlink of second $left subdirs failed"
5841         # regardless of whether the backing filesystem tracks nlink accurately
5842         # or not, the nlink count shouldn't be more than "." and ".." here
5843         local after=$(stat -c %h $dir)
5844         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5845                 echo "nlink after: $after"
5846
5847         cleanup_print_lfs_df
5848 }
5849 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5850
5851 test_51d_sub() {
5852         local stripecount=$1
5853         local nfiles=$2
5854
5855         log "create files with stripecount=$stripecount"
5856         $LFS setstripe -C $stripecount $DIR/$tdir
5857         createmany -o $DIR/$tdir/t- $nfiles
5858         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5859         for ((n = 0; n < $OSTCOUNT; n++)); do
5860                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5861                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5862                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5863                             '($1 == '$n') { objs += 1 } \
5864                             END { printf("%0.0f", objs) }')
5865                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5866         done
5867         unlinkmany $DIR/$tdir/t- $nfiles
5868         rm  -f $TMP/$tfile
5869
5870         local nlast
5871         local min=4
5872         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5873
5874         # For some combinations of stripecount and OSTCOUNT current code
5875         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5876         # than others. Rather than skipping this test entirely, check that
5877         # and keep testing to ensure imbalance does not get worse. LU-15282
5878         (( (OSTCOUNT == 6 && stripecount == 4) ||
5879            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5880            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5881         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5882                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5883                         { $LFS df && $LFS df -i &&
5884                         error "stripecount=$stripecount: " \
5885                               "OST $n has fewer objects vs. OST $nlast " \
5886                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5887                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5888                         { $LFS df && $LFS df -i &&
5889                         error "stripecount=$stripecount: " \
5890                               "OST $n has more objects vs. OST $nlast " \
5891                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5892
5893                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5894                         { $LFS df && $LFS df -i &&
5895                         error "stripecount=$stripecount: " \
5896                               "OST $n has fewer #0 objects vs. OST $nlast " \
5897                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5898                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5899                         { $LFS df && $LFS df -i &&
5900                         error "stripecount=$stripecount: " \
5901                               "OST $n has more #0 objects vs. OST $nlast " \
5902                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5903         done
5904 }
5905
5906 test_51d() {
5907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5908         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5909
5910         local stripecount
5911         local per_ost=100
5912         local nfiles=$((per_ost * OSTCOUNT))
5913         local mdts=$(comma_list $(mdts_nodes))
5914         local param="osp.*.create_count"
5915         local qos_old=$(do_facet mds1 \
5916                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5917
5918         do_nodes $mdts \
5919                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5920         stack_trap "do_nodes $mdts \
5921                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5922
5923         test_mkdir $DIR/$tdir
5924         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5925         (( dirstripes > 0 )) || dirstripes=1
5926
5927         # Ensure enough OST objects precreated for tests to pass without
5928         # running out of objects.  This is an LOV r-r OST algorithm test,
5929         # not an OST object precreation test.
5930         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5931         (( old >= nfiles )) ||
5932         {
5933                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5934
5935                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5936                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5937
5938                 # trigger precreation from all MDTs for all OSTs
5939                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5940                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5941                 done
5942         }
5943
5944         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5945                 sleep 8  # allow object precreation to catch up
5946                 test_51d_sub $stripecount $nfiles
5947         done
5948 }
5949 run_test 51d "check LOV round-robin OST object distribution"
5950
5951 test_51e() {
5952         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5953                 skip_env "ldiskfs only test"
5954         fi
5955
5956         test_mkdir -c1 $DIR/$tdir
5957         test_mkdir -c1 $DIR/$tdir/d0
5958
5959         touch $DIR/$tdir/d0/foo
5960         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5961                 error "file exceed 65000 nlink limit!"
5962         unlinkmany $DIR/$tdir/d0/f- 65001
5963         return 0
5964 }
5965 run_test 51e "check file nlink limit"
5966
5967 test_51f() {
5968         test_mkdir $DIR/$tdir
5969
5970         local max=100000
5971         local ulimit_old=$(ulimit -n)
5972         local spare=20 # number of spare fd's for scripts/libraries, etc.
5973         local mdt=$($LFS getstripe -m $DIR/$tdir)
5974         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5975
5976         echo "MDT$mdt numfree=$numfree, max=$max"
5977         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5978         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5979                 while ! ulimit -n $((numfree + spare)); do
5980                         numfree=$((numfree * 3 / 4))
5981                 done
5982                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5983         else
5984                 echo "left ulimit at $ulimit_old"
5985         fi
5986
5987         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5988                 unlinkmany $DIR/$tdir/f $numfree
5989                 error "create+open $numfree files in $DIR/$tdir failed"
5990         }
5991         ulimit -n $ulimit_old
5992
5993         # if createmany exits at 120s there will be fewer than $numfree files
5994         unlinkmany $DIR/$tdir/f $numfree || true
5995 }
5996 run_test 51f "check many open files limit"
5997
5998 test_52a() {
5999         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6000         test_mkdir $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6003         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6004         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6005         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6006         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6007                                         error "link worked"
6008         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6009         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6010         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6011                                                      error "lsattr"
6012         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6013         cp -r $DIR/$tdir $TMP/
6014         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6015 }
6016 run_test 52a "append-only flag test (should return errors)"
6017
6018 test_52b() {
6019         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6020         test_mkdir $DIR/$tdir
6021         touch $DIR/$tdir/foo
6022         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6023         cat test > $DIR/$tdir/foo && error "cat test worked"
6024         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6025         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6026         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6027                                         error "link worked"
6028         echo foo >> $DIR/$tdir/foo && error "echo worked"
6029         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6030         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6031         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6032         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6033                                                         error "lsattr"
6034         chattr -i $DIR/$tdir/foo || error "chattr failed"
6035
6036         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6037 }
6038 run_test 52b "immutable flag test (should return errors) ======="
6039
6040 test_53() {
6041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6042         remote_mds_nodsh && skip "remote MDS with nodsh"
6043         remote_ost_nodsh && skip "remote OST with nodsh"
6044
6045         local param
6046         local param_seq
6047         local ostname
6048         local mds_last
6049         local mds_last_seq
6050         local ost_last
6051         local ost_last_seq
6052         local ost_last_id
6053         local ostnum
6054         local node
6055         local found=false
6056         local support_last_seq=true
6057
6058         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6059                 support_last_seq=false
6060
6061         # only test MDT0000
6062         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6063         local value
6064         for value in $(do_facet $SINGLEMDS \
6065                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6066                 param=$(echo ${value[0]} | cut -d "=" -f1)
6067                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6068
6069                 if $support_last_seq; then
6070                         param_seq=$(echo $param |
6071                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6072                         mds_last_seq=$(do_facet $SINGLEMDS \
6073                                        $LCTL get_param -n $param_seq)
6074                 fi
6075                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6076
6077                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6078                 node=$(facet_active_host ost$((ostnum+1)))
6079                 param="obdfilter.$ostname.last_id"
6080                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6081                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6082                         ost_last_id=$ost_last
6083
6084                         if $support_last_seq; then
6085                                 ost_last_id=$(echo $ost_last |
6086                                               awk -F':' '{print $2}' |
6087                                               sed -e "s/^0x//g")
6088                                 ost_last_seq=$(echo $ost_last |
6089                                                awk -F':' '{print $1}')
6090                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6091                         fi
6092
6093                         if [[ $ost_last_id != $mds_last ]]; then
6094                                 error "$ost_last_id != $mds_last"
6095                         else
6096                                 found=true
6097                                 break
6098                         fi
6099                 done
6100         done
6101         $found || error "can not match last_seq/last_id for $mdtosc"
6102         return 0
6103 }
6104 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6105
6106 test_54a() {
6107         perl -MSocket -e ';' || skip "no Socket perl module installed"
6108
6109         $SOCKETSERVER $DIR/socket ||
6110                 error "$SOCKETSERVER $DIR/socket failed: $?"
6111         $SOCKETCLIENT $DIR/socket ||
6112                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6113         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6114 }
6115 run_test 54a "unix domain socket test =========================="
6116
6117 test_54b() {
6118         f="$DIR/f54b"
6119         mknod $f c 1 3
6120         chmod 0666 $f
6121         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6122 }
6123 run_test 54b "char device works in lustre ======================"
6124
6125 find_loop_dev() {
6126         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6127         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6128         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6129
6130         for i in $(seq 3 7); do
6131                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6132                 LOOPDEV=$LOOPBASE$i
6133                 LOOPNUM=$i
6134                 break
6135         done
6136 }
6137
6138 cleanup_54c() {
6139         local rc=0
6140         loopdev="$DIR/loop54c"
6141
6142         trap 0
6143         $UMOUNT $DIR/$tdir || rc=$?
6144         losetup -d $loopdev || true
6145         losetup -d $LOOPDEV || true
6146         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6147         return $rc
6148 }
6149
6150 test_54c() {
6151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6152
6153         loopdev="$DIR/loop54c"
6154
6155         find_loop_dev
6156         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6157         trap cleanup_54c EXIT
6158         mknod $loopdev b 7 $LOOPNUM
6159         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6160         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6161         losetup $loopdev $DIR/$tfile ||
6162                 error "can't set up $loopdev for $DIR/$tfile"
6163         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6164         test_mkdir $DIR/$tdir
6165         mount -t ext2 $loopdev $DIR/$tdir ||
6166                 error "error mounting $loopdev on $DIR/$tdir"
6167         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6168                 error "dd write"
6169         df $DIR/$tdir
6170         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6171                 error "dd read"
6172         cleanup_54c
6173 }
6174 run_test 54c "block device works in lustre ====================="
6175
6176 test_54d() {
6177         local pipe="$DIR/$tfile.pipe"
6178         local string="aaaaaa"
6179
6180         mknod $pipe p
6181         echo -n "$string" > $pipe &
6182         local result=$(cat $pipe)
6183         [[ "$result" == "$string" ]] || error "$result != $string"
6184 }
6185 run_test 54d "fifo device works in lustre ======================"
6186
6187 test_54e() {
6188         f="$DIR/f54e"
6189         string="aaaaaa"
6190         cp -aL /dev/console $f
6191         echo $string > $f || error "echo $string to $f failed"
6192 }
6193 run_test 54e "console/tty device works in lustre ======================"
6194
6195 test_56a() {
6196         local numfiles=3
6197         local numdirs=2
6198         local dir=$DIR/$tdir
6199
6200         rm -rf $dir
6201         test_mkdir -p $dir/dir
6202         for i in $(seq $numfiles); do
6203                 touch $dir/file$i
6204                 touch $dir/dir/file$i
6205         done
6206
6207         local numcomp=$($LFS getstripe --component-count $dir)
6208
6209         [[ $numcomp == 0 ]] && numcomp=1
6210
6211         # test lfs getstripe with --recursive
6212         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6213
6214         [[ $filenum -eq $((numfiles * 2)) ]] ||
6215                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6216         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6217         [[ $filenum -eq $numfiles ]] ||
6218                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6219         echo "$LFS getstripe showed obdidx or l_ost_idx"
6220
6221         # test lfs getstripe with file instead of dir
6222         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6223         [[ $filenum -eq 1 ]] ||
6224                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6225         echo "$LFS getstripe file1 passed"
6226
6227         #test lfs getstripe with --verbose
6228         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6229         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6230                 error "$LFS getstripe --verbose $dir: "\
6231                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6232         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6233                 error "$LFS getstripe $dir: showed lmm_magic"
6234
6235         #test lfs getstripe with -v prints lmm_fid
6236         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6237         local countfids=$((numdirs + numfiles * numcomp))
6238         [[ $filenum -eq $countfids ]] ||
6239                 error "$LFS getstripe -v $dir: "\
6240                       "got $filenum want $countfids lmm_fid"
6241         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6242                 error "$LFS getstripe $dir: showed lmm_fid by default"
6243         echo "$LFS getstripe --verbose passed"
6244
6245         #check for FID information
6246         local fid1=$($LFS getstripe --fid $dir/file1)
6247         local fid2=$($LFS getstripe --verbose $dir/file1 |
6248                      awk '/lmm_fid: / { print $2; exit; }')
6249         local fid3=$($LFS path2fid $dir/file1)
6250
6251         [ "$fid1" != "$fid2" ] &&
6252                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6253         [ "$fid1" != "$fid3" ] &&
6254                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6255         echo "$LFS getstripe --fid passed"
6256
6257         #test lfs getstripe with --obd
6258         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6259                 error "$LFS getstripe --obd wrong_uuid: should return error"
6260
6261         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6262
6263         local ostidx=1
6264         local obduuid=$(ostuuid_from_index $ostidx)
6265         local found=$($LFS getstripe -r --obd $obduuid $dir |
6266                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6267
6268         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6269         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6270                 ((filenum--))
6271         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6272                 ((filenum--))
6273
6274         [[ $found -eq $filenum ]] ||
6275                 error "$LFS getstripe --obd: found $found expect $filenum"
6276         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6277                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6278                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6279                 error "$LFS getstripe --obd: should not show file on other obd"
6280         echo "$LFS getstripe --obd passed"
6281 }
6282 run_test 56a "check $LFS getstripe"
6283
6284 test_56b() {
6285         local dir=$DIR/$tdir
6286         local numdirs=3
6287
6288         test_mkdir $dir
6289         for i in $(seq $numdirs); do
6290                 test_mkdir $dir/dir$i
6291         done
6292
6293         # test lfs getdirstripe default mode is non-recursion, which is
6294         # different from lfs getstripe
6295         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6296
6297         [[ $dircnt -eq 1 ]] ||
6298                 error "$LFS getdirstripe: found $dircnt, not 1"
6299         dircnt=$($LFS getdirstripe --recursive $dir |
6300                 grep -c lmv_stripe_count)
6301         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6302                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6303 }
6304 run_test 56b "check $LFS getdirstripe"
6305
6306 test_56c() {
6307         remote_ost_nodsh && skip "remote OST with nodsh"
6308
6309         local ost_idx=0
6310         local ost_name=$(ostname_from_index $ost_idx)
6311         local old_status=$(ost_dev_status $ost_idx)
6312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6313
6314         [[ -z "$old_status" ]] ||
6315                 skip_env "OST $ost_name is in $old_status status"
6316
6317         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6318         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6319                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6320         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6321                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6322                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6323         fi
6324
6325         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6326                 error "$LFS df -v showing inactive devices"
6327         sleep_maxage
6328
6329         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6330
6331         [[ "$new_status" =~ "D" ]] ||
6332                 error "$ost_name status is '$new_status', missing 'D'"
6333         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6334                 [[ "$new_status" =~ "N" ]] ||
6335                         error "$ost_name status is '$new_status', missing 'N'"
6336         fi
6337         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6338                 [[ "$new_status" =~ "f" ]] ||
6339                         error "$ost_name status is '$new_status', missing 'f'"
6340         fi
6341
6342         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6343         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6344                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6345         [[ -z "$p" ]] && restore_lustre_params < $p || true
6346         sleep_maxage
6347
6348         new_status=$(ost_dev_status $ost_idx)
6349         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6350                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6351         # can't check 'f' as devices may actually be on flash
6352 }
6353 run_test 56c "check 'lfs df' showing device status"
6354
6355 test_56d() {
6356         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6357         local osts=$($LFS df -v $MOUNT | grep -c OST)
6358
6359         $LFS df $MOUNT
6360
6361         (( mdts == MDSCOUNT )) ||
6362                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6363         (( osts == OSTCOUNT )) ||
6364                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6365 }
6366 run_test 56d "'lfs df -v' prints only configured devices"
6367
6368 test_56e() {
6369         err_enoent=2 # No such file or directory
6370         err_eopnotsupp=95 # Operation not supported
6371
6372         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6373         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6374
6375         # Check for handling of path not exists
6376         output=$($LFS df $enoent_mnt 2>&1)
6377         ret=$?
6378
6379         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6380         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6381                 error "expect failure $err_enoent, not $ret"
6382
6383         # Check for handling of non-Lustre FS
6384         output=$($LFS df $notsup_mnt)
6385         ret=$?
6386
6387         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6388         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6389                 error "expect success $err_eopnotsupp, not $ret"
6390
6391         # Check for multiple LustreFS argument
6392         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6393         ret=$?
6394
6395         [[ $output -eq 3 && $ret -eq 0 ]] ||
6396                 error "expect success 3, not $output, rc = $ret"
6397
6398         # Check for correct non-Lustre FS handling among multiple
6399         # LustreFS argument
6400         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6401                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6402         ret=$?
6403
6404         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6405                 error "expect success 2, not $output, rc = $ret"
6406 }
6407 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6408
6409 NUMFILES=3
6410 NUMDIRS=3
6411 setup_56() {
6412         local local_tdir="$1"
6413         local local_numfiles="$2"
6414         local local_numdirs="$3"
6415         local dir_params="$4"
6416         local dir_stripe_params="$5"
6417
6418         if [ ! -d "$local_tdir" ] ; then
6419                 test_mkdir -p $dir_stripe_params $local_tdir
6420                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6421                 for i in $(seq $local_numfiles) ; do
6422                         touch $local_tdir/file$i
6423                 done
6424                 for i in $(seq $local_numdirs) ; do
6425                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6426                         for j in $(seq $local_numfiles) ; do
6427                                 touch $local_tdir/dir$i/file$j
6428                         done
6429                 done
6430         fi
6431 }
6432
6433 setup_56_special() {
6434         local local_tdir=$1
6435         local local_numfiles=$2
6436         local local_numdirs=$3
6437
6438         setup_56 $local_tdir $local_numfiles $local_numdirs
6439
6440         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6441                 for i in $(seq $local_numfiles) ; do
6442                         mknod $local_tdir/loop${i}b b 7 $i
6443                         mknod $local_tdir/null${i}c c 1 3
6444                         ln -s $local_tdir/file1 $local_tdir/link${i}
6445                 done
6446                 for i in $(seq $local_numdirs) ; do
6447                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6448                         mknod $local_tdir/dir$i/null${i}c c 1 3
6449                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6450                 done
6451         fi
6452 }
6453
6454 test_56g() {
6455         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6456         local expected=$(($NUMDIRS + 2))
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         # test lfs find with -name
6461         for i in $(seq $NUMFILES) ; do
6462                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6463
6464                 [ $nums -eq $expected ] ||
6465                         error "lfs find -name '*$i' $dir wrong: "\
6466                               "found $nums, expected $expected"
6467         done
6468 }
6469 run_test 56g "check lfs find -name"
6470
6471 test_56h() {
6472         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6473         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6474
6475         setup_56 $dir $NUMFILES $NUMDIRS
6476
6477         # test lfs find with ! -name
6478         for i in $(seq $NUMFILES) ; do
6479                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6480
6481                 [ $nums -eq $expected ] ||
6482                         error "lfs find ! -name '*$i' $dir wrong: "\
6483                               "found $nums, expected $expected"
6484         done
6485 }
6486 run_test 56h "check lfs find ! -name"
6487
6488 test_56i() {
6489         local dir=$DIR/$tdir
6490
6491         test_mkdir $dir
6492
6493         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6494         local out=$($cmd)
6495
6496         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6497 }
6498 run_test 56i "check 'lfs find -ost UUID' skips directories"
6499
6500 test_56j() {
6501         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6502
6503         setup_56_special $dir $NUMFILES $NUMDIRS
6504
6505         local expected=$((NUMDIRS + 1))
6506         local cmd="$LFS find -type d $dir"
6507         local nums=$($cmd | wc -l)
6508
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511 }
6512 run_test 56j "check lfs find -type d"
6513
6514 test_56k() {
6515         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6516
6517         setup_56_special $dir $NUMFILES $NUMDIRS
6518
6519         local expected=$(((NUMDIRS + 1) * NUMFILES))
6520         local cmd="$LFS find -type f $dir"
6521         local nums=$($cmd | wc -l)
6522
6523         [ $nums -eq $expected ] ||
6524                 error "'$cmd' wrong: found $nums, expected $expected"
6525 }
6526 run_test 56k "check lfs find -type f"
6527
6528 test_56l() {
6529         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6530
6531         setup_56_special $dir $NUMFILES $NUMDIRS
6532
6533         local expected=$((NUMDIRS + NUMFILES))
6534         local cmd="$LFS find -type b $dir"
6535         local nums=$($cmd | wc -l)
6536
6537         [ $nums -eq $expected ] ||
6538                 error "'$cmd' wrong: found $nums, expected $expected"
6539 }
6540 run_test 56l "check lfs find -type b"
6541
6542 test_56m() {
6543         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6544
6545         setup_56_special $dir $NUMFILES $NUMDIRS
6546
6547         local expected=$((NUMDIRS + NUMFILES))
6548         local cmd="$LFS find -type c $dir"
6549         local nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552 }
6553 run_test 56m "check lfs find -type c"
6554
6555 test_56n() {
6556         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6557         setup_56_special $dir $NUMFILES $NUMDIRS
6558
6559         local expected=$((NUMDIRS + NUMFILES))
6560         local cmd="$LFS find -type l $dir"
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565 }
6566 run_test 56n "check lfs find -type l"
6567
6568 test_56o() {
6569         local dir=$DIR/$tdir
6570
6571         setup_56 $dir $NUMFILES $NUMDIRS
6572         utime $dir/file1 > /dev/null || error "utime (1)"
6573         utime $dir/file2 > /dev/null || error "utime (2)"
6574         utime $dir/dir1 > /dev/null || error "utime (3)"
6575         utime $dir/dir2 > /dev/null || error "utime (4)"
6576         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6577         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6578
6579         local expected=4
6580         local nums=$($LFS find -mtime +0 $dir | wc -l)
6581
6582         [ $nums -eq $expected ] ||
6583                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6584
6585         expected=12
6586         cmd="$LFS find -mtime 0 $dir"
6587         nums=$($cmd | wc -l)
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590 }
6591 run_test 56o "check lfs find -mtime for old files"
6592
6593 test_56ob() {
6594         local dir=$DIR/$tdir
6595         local expected=1
6596         local count=0
6597
6598         # just to make sure there is something that won't be found
6599         test_mkdir $dir
6600         touch $dir/$tfile.now
6601
6602         for age in year week day hour min; do
6603                 count=$((count + 1))
6604
6605                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6606                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6607                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6608
6609                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6610                 local nums=$($cmd | wc -l)
6611                 [ $nums -eq $expected ] ||
6612                         error "'$cmd' wrong: found $nums, expected $expected"
6613
6614                 cmd="$LFS find $dir -atime $count${age:0:1}"
6615                 nums=$($cmd | wc -l)
6616                 [ $nums -eq $expected ] ||
6617                         error "'$cmd' wrong: found $nums, expected $expected"
6618         done
6619
6620         sleep 2
6621         cmd="$LFS find $dir -ctime +1s -type f"
6622         nums=$($cmd | wc -l)
6623         (( $nums == $count * 2 + 1)) ||
6624                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6625 }
6626 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6627
6628 test_newerXY_base() {
6629         local x=$1
6630         local y=$2
6631         local dir=$DIR/$tdir
6632         local ref
6633         local negref
6634
6635         if [ $y == "t" ]; then
6636                 if [ $x == "b" ]; then
6637                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6638                 else
6639                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6640                 fi
6641         else
6642                 ref=$DIR/$tfile.newer.$x$y
6643                 touch $ref || error "touch $ref failed"
6644         fi
6645
6646         echo "before = $ref"
6647         sleep 2
6648         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6649         sleep 2
6650         if [ $y == "t" ]; then
6651                 if [ $x == "b" ]; then
6652                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6653                 else
6654                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6655                 fi
6656         else
6657                 negref=$DIR/$tfile.negnewer.$x$y
6658                 touch $negref || error "touch $negref failed"
6659         fi
6660
6661         echo "after = $negref"
6662         local cmd="$LFS find $dir -newer$x$y $ref"
6663         local nums=$(eval $cmd | wc -l)
6664         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6665
6666         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6667                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6668
6669         cmd="$LFS find $dir ! -newer$x$y $negref"
6670         nums=$(eval $cmd | wc -l)
6671         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6672                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6673
6674         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6675         nums=$(eval $cmd | wc -l)
6676         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6677                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6678
6679         rm -rf $DIR/*
6680 }
6681
6682 test_56oc() {
6683         test_newerXY_base "a" "a"
6684         test_newerXY_base "a" "m"
6685         test_newerXY_base "a" "c"
6686         test_newerXY_base "m" "a"
6687         test_newerXY_base "m" "m"
6688         test_newerXY_base "m" "c"
6689         test_newerXY_base "c" "a"
6690         test_newerXY_base "c" "m"
6691         test_newerXY_base "c" "c"
6692
6693         test_newerXY_base "a" "t"
6694         test_newerXY_base "m" "t"
6695         test_newerXY_base "c" "t"
6696
6697         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6698            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6699                 ! btime_supported && echo "btime unsupported" && return 0
6700
6701         test_newerXY_base "b" "b"
6702         test_newerXY_base "b" "t"
6703 }
6704 run_test 56oc "check lfs find -newerXY work"
6705
6706 btime_supported() {
6707         local dir=$DIR/$tdir
6708         local rc
6709
6710         mkdir -p $dir
6711         touch $dir/$tfile
6712         $LFS find $dir -btime -1d -type f
6713         rc=$?
6714         rm -rf $dir
6715         return $rc
6716 }
6717
6718 test_56od() {
6719         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6720                 ! btime_supported && skip "btime unsupported on MDS"
6721
6722         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6723                 ! btime_supported && skip "btime unsupported on clients"
6724
6725         local dir=$DIR/$tdir
6726         local ref=$DIR/$tfile.ref
6727         local negref=$DIR/$tfile.negref
6728
6729         mkdir $dir || error "mkdir $dir failed"
6730         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6731         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6732         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6733         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6734         touch $ref || error "touch $ref failed"
6735         # sleep 3 seconds at least
6736         sleep 3
6737
6738         local before=$(do_facet mds1 date +%s)
6739         local skew=$(($(date +%s) - before + 1))
6740
6741         if (( skew < 0 && skew > -5 )); then
6742                 sleep $((0 - skew + 1))
6743                 skew=0
6744         fi
6745
6746         # Set the dir stripe params to limit files all on MDT0,
6747         # otherwise we need to calc the max clock skew between
6748         # the client and MDTs.
6749         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6750         sleep 2
6751         touch $negref || error "touch $negref failed"
6752
6753         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6754         local nums=$($cmd | wc -l)
6755         local expected=$(((NUMFILES + 1) * NUMDIRS))
6756
6757         [ $nums -eq $expected ] ||
6758                 error "'$cmd' wrong: found $nums, expected $expected"
6759
6760         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6761         nums=$($cmd | wc -l)
6762         expected=$((NUMFILES + 1))
6763         [ $nums -eq $expected ] ||
6764                 error "'$cmd' wrong: found $nums, expected $expected"
6765
6766         [ $skew -lt 0 ] && return
6767
6768         local after=$(do_facet mds1 date +%s)
6769         local age=$((after - before + 1 + skew))
6770
6771         cmd="$LFS find $dir -btime -${age}s -type f"
6772         nums=$($cmd | wc -l)
6773         expected=$(((NUMFILES + 1) * NUMDIRS))
6774
6775         echo "Clock skew between client and server: $skew, age:$age"
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778
6779         expected=$(($NUMDIRS + 1))
6780         cmd="$LFS find $dir -btime -${age}s -type d"
6781         nums=$($cmd | wc -l)
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784         rm -f $ref $negref || error "Failed to remove $ref $negref"
6785 }
6786 run_test 56od "check lfs find -btime with units"
6787
6788 test_56p() {
6789         [ $RUNAS_ID -eq $UID ] &&
6790                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6791
6792         local dir=$DIR/$tdir
6793
6794         setup_56 $dir $NUMFILES $NUMDIRS
6795         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6796
6797         local expected=$NUMFILES
6798         local cmd="$LFS find -uid $RUNAS_ID $dir"
6799         local nums=$($cmd | wc -l)
6800
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803
6804         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6805         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6806         nums=$($cmd | wc -l)
6807         [ $nums -eq $expected ] ||
6808                 error "'$cmd' wrong: found $nums, expected $expected"
6809 }
6810 run_test 56p "check lfs find -uid and ! -uid"
6811
6812 test_56q() {
6813         [ $RUNAS_ID -eq $UID ] &&
6814                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6815
6816         local dir=$DIR/$tdir
6817
6818         setup_56 $dir $NUMFILES $NUMDIRS
6819         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6820
6821         local expected=$NUMFILES
6822         local cmd="$LFS find -gid $RUNAS_GID $dir"
6823         local nums=$($cmd | wc -l)
6824
6825         [ $nums -eq $expected ] ||
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827
6828         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6829         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833 }
6834 run_test 56q "check lfs find -gid and ! -gid"
6835
6836 test_56r() {
6837         local dir=$DIR/$tdir
6838
6839         setup_56 $dir $NUMFILES $NUMDIRS
6840
6841         local expected=12
6842         local cmd="$LFS find -size 0 -type f -lazy $dir"
6843         local nums=$($cmd | wc -l)
6844
6845         [ $nums -eq $expected ] ||
6846                 error "'$cmd' wrong: found $nums, expected $expected"
6847         cmd="$LFS find -size 0 -type f $dir"
6848         nums=$($cmd | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851
6852         expected=0
6853         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6854         nums=$($cmd | wc -l)
6855         [ $nums -eq $expected ] ||
6856                 error "'$cmd' wrong: found $nums, expected $expected"
6857         cmd="$LFS find ! -size 0 -type f $dir"
6858         nums=$($cmd | wc -l)
6859         [ $nums -eq $expected ] ||
6860                 error "'$cmd' wrong: found $nums, expected $expected"
6861
6862         echo "test" > $dir/$tfile
6863         echo "test2" > $dir/$tfile.2 && sync
6864         expected=1
6865         cmd="$LFS find -size 5 -type f -lazy $dir"
6866         nums=$($cmd | wc -l)
6867         [ $nums -eq $expected ] ||
6868                 error "'$cmd' wrong: found $nums, expected $expected"
6869         cmd="$LFS find -size 5 -type f $dir"
6870         nums=$($cmd | wc -l)
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873
6874         expected=1
6875         cmd="$LFS find -size +5 -type f -lazy $dir"
6876         nums=$($cmd | wc -l)
6877         [ $nums -eq $expected ] ||
6878                 error "'$cmd' wrong: found $nums, expected $expected"
6879         cmd="$LFS find -size +5 -type f $dir"
6880         nums=$($cmd | wc -l)
6881         [ $nums -eq $expected ] ||
6882                 error "'$cmd' wrong: found $nums, expected $expected"
6883
6884         expected=2
6885         cmd="$LFS find -size +0 -type f -lazy $dir"
6886         nums=$($cmd | wc -l)
6887         [ $nums -eq $expected ] ||
6888                 error "'$cmd' wrong: found $nums, expected $expected"
6889         cmd="$LFS find -size +0 -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         expected=2
6895         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] ||
6898                 error "'$cmd' wrong: found $nums, expected $expected"
6899         cmd="$LFS find ! -size -5 -type f $dir"
6900         nums=$($cmd | wc -l)
6901         [ $nums -eq $expected ] ||
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903
6904         expected=12
6905         cmd="$LFS find -size -5 -type f -lazy $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         cmd="$LFS find -size -5 -type f $dir"
6910         nums=$($cmd | wc -l)
6911         [ $nums -eq $expected ] ||
6912                 error "'$cmd' wrong: found $nums, expected $expected"
6913 }
6914 run_test 56r "check lfs find -size works"
6915
6916 test_56ra_sub() {
6917         local expected=$1
6918         local glimpses=$2
6919         local cmd="$3"
6920
6921         cancel_lru_locks $OSC
6922
6923         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6924         local nums=$($cmd | wc -l)
6925
6926         [ $nums -eq $expected ] ||
6927                 error "'$cmd' wrong: found $nums, expected $expected"
6928
6929         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6930
6931         if (( rpcs_before + glimpses != rpcs_after )); then
6932                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6933                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6934
6935                 if [[ $glimpses == 0 ]]; then
6936                         error "'$cmd' should not send glimpse RPCs to OST"
6937                 else
6938                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6939                 fi
6940         fi
6941 }
6942
6943 test_56ra() {
6944         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6945                 skip "MDS < 2.12.58 doesn't return LSOM data"
6946         local dir=$DIR/$tdir
6947         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6948
6949         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6950
6951         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6952         $LCTL set_param -n llite.*.statahead_agl=0
6953         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6954
6955         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6956         # open and close all files to ensure LSOM is updated
6957         cancel_lru_locks $OSC
6958         find $dir -type f | xargs cat > /dev/null
6959
6960         #   expect_found  glimpse_rpcs  command_to_run
6961         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6962         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6963         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6964         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6965
6966         echo "test" > $dir/$tfile
6967         echo "test2" > $dir/$tfile.2 && sync
6968         cancel_lru_locks $OSC
6969         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6970
6971         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6972         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6973         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6974         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6975
6976         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6977         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6978         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6979         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6980         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6981         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6982 }
6983 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6984
6985 test_56rb() {
6986         local dir=$DIR/$tdir
6987         local tmp=$TMP/$tfile.log
6988         local mdt_idx;
6989
6990         test_mkdir -p $dir || error "failed to mkdir $dir"
6991         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6992                 error "failed to setstripe $dir/$tfile"
6993         mdt_idx=$($LFS getdirstripe -i $dir)
6994         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6995
6996         stack_trap "rm -f $tmp" EXIT
6997         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6998         ! grep -q obd_uuid $tmp ||
6999                 error "failed to find --size +100K --ost 0 $dir"
7000         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7001         ! grep -q obd_uuid $tmp ||
7002                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7003 }
7004 run_test 56rb "check lfs find --size --ost/--mdt works"
7005
7006 test_56rc() {
7007         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7008         local dir=$DIR/$tdir
7009         local found
7010
7011         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7012         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7013         (( $MDSCOUNT > 2 )) &&
7014                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7015         mkdir $dir/$tdir-{1..10}
7016         touch $dir/$tfile-{1..10}
7017
7018         found=$($LFS find $dir --mdt-count 2 | wc -l)
7019         expect=11
7020         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7021
7022         found=$($LFS find $dir -T +1 | wc -l)
7023         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7024         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7025
7026         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7027         expect=11
7028         (( $found == $expect )) || error "found $found all_char, expect $expect"
7029
7030         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7031         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7032         (( $found == $expect )) || error "found $found all_char, expect $expect"
7033 }
7034 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7035
7036 test_56s() { # LU-611 #LU-9369
7037         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7038
7039         local dir=$DIR/$tdir
7040         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7041
7042         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7043         for i in $(seq $NUMDIRS); do
7044                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7045         done
7046
7047         local expected=$NUMDIRS
7048         local cmd="$LFS find -c $OSTCOUNT $dir"
7049         local nums=$($cmd | wc -l)
7050
7051         [ $nums -eq $expected ] || {
7052                 $LFS getstripe -R $dir
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054         }
7055
7056         expected=$((NUMDIRS + onestripe))
7057         cmd="$LFS find -stripe-count +0 -type f $dir"
7058         nums=$($cmd | wc -l)
7059         [ $nums -eq $expected ] || {
7060                 $LFS getstripe -R $dir
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062         }
7063
7064         expected=$onestripe
7065         cmd="$LFS find -stripe-count 1 -type f $dir"
7066         nums=$($cmd | wc -l)
7067         [ $nums -eq $expected ] || {
7068                 $LFS getstripe -R $dir
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070         }
7071
7072         cmd="$LFS find -stripe-count -2 -type f $dir"
7073         nums=$($cmd | wc -l)
7074         [ $nums -eq $expected ] || {
7075                 $LFS getstripe -R $dir
7076                 error "'$cmd' wrong: found $nums, expected $expected"
7077         }
7078
7079         expected=0
7080         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7081         nums=$($cmd | wc -l)
7082         [ $nums -eq $expected ] || {
7083                 $LFS getstripe -R $dir
7084                 error "'$cmd' wrong: found $nums, expected $expected"
7085         }
7086 }
7087 run_test 56s "check lfs find -stripe-count works"
7088
7089 test_56t() { # LU-611 #LU-9369
7090         local dir=$DIR/$tdir
7091
7092         setup_56 $dir 0 $NUMDIRS
7093         for i in $(seq $NUMDIRS); do
7094                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7095         done
7096
7097         local expected=$NUMDIRS
7098         local cmd="$LFS find -S 8M $dir"
7099         local nums=$($cmd | wc -l)
7100
7101         [ $nums -eq $expected ] || {
7102                 $LFS getstripe -R $dir
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104         }
7105         rm -rf $dir
7106
7107         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7108
7109         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7110
7111         expected=$(((NUMDIRS + 1) * NUMFILES))
7112         cmd="$LFS find -stripe-size 512k -type f $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116
7117         cmd="$LFS find -stripe-size +320k -type f $dir"
7118         nums=$($cmd | wc -l)
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121
7122         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7123         cmd="$LFS find -stripe-size +200k -type f $dir"
7124         nums=$($cmd | wc -l)
7125         [ $nums -eq $expected ] ||
7126                 error "'$cmd' wrong: found $nums, expected $expected"
7127
7128         cmd="$LFS find -stripe-size -640k -type f $dir"
7129         nums=$($cmd | wc -l)
7130         [ $nums -eq $expected ] ||
7131                 error "'$cmd' wrong: found $nums, expected $expected"
7132
7133         expected=4
7134         cmd="$LFS find -stripe-size 256k -type f $dir"
7135         nums=$($cmd | wc -l)
7136         [ $nums -eq $expected ] ||
7137                 error "'$cmd' wrong: found $nums, expected $expected"
7138
7139         cmd="$LFS find -stripe-size -320k -type f $dir"
7140         nums=$($cmd | wc -l)
7141         [ $nums -eq $expected ] ||
7142                 error "'$cmd' wrong: found $nums, expected $expected"
7143
7144         expected=0
7145         cmd="$LFS find -stripe-size 1024k -type f $dir"
7146         nums=$($cmd | wc -l)
7147         [ $nums -eq $expected ] ||
7148                 error "'$cmd' wrong: found $nums, expected $expected"
7149 }
7150 run_test 56t "check lfs find -stripe-size works"
7151
7152 test_56u() { # LU-611
7153         local dir=$DIR/$tdir
7154
7155         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7156
7157         if [[ $OSTCOUNT -gt 1 ]]; then
7158                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7159                 onestripe=4
7160         else
7161                 onestripe=0
7162         fi
7163
7164         local expected=$(((NUMDIRS + 1) * NUMFILES))
7165         local cmd="$LFS find -stripe-index 0 -type f $dir"
7166         local nums=$($cmd | wc -l)
7167
7168         [ $nums -eq $expected ] ||
7169                 error "'$cmd' wrong: found $nums, expected $expected"
7170
7171         expected=$onestripe
7172         cmd="$LFS find -stripe-index 1 -type f $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176
7177         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7178         nums=$($cmd | wc -l)
7179         [ $nums -eq $expected ] ||
7180                 error "'$cmd' wrong: found $nums, expected $expected"
7181
7182         expected=0
7183         # This should produce an error and not return any files
7184         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7185         nums=$($cmd 2>/dev/null | wc -l)
7186         [ $nums -eq $expected ] ||
7187                 error "'$cmd' wrong: found $nums, expected $expected"
7188
7189         if [[ $OSTCOUNT -gt 1 ]]; then
7190                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7191                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7192                 nums=$($cmd | wc -l)
7193                 [ $nums -eq $expected ] ||
7194                         error "'$cmd' wrong: found $nums, expected $expected"
7195         fi
7196 }
7197 run_test 56u "check lfs find -stripe-index works"
7198
7199 test_56v() {
7200         local mdt_idx=0
7201         local dir=$DIR/$tdir
7202
7203         setup_56 $dir $NUMFILES $NUMDIRS
7204
7205         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7206         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7207
7208         for file in $($LFS find -m $UUID $dir); do
7209                 file_midx=$($LFS getstripe -m $file)
7210                 [ $file_midx -eq $mdt_idx ] ||
7211                         error "lfs find -m $UUID != getstripe -m $file_midx"
7212         done
7213 }
7214 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7215
7216 test_56w() {
7217         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7219
7220         local dir=$DIR/$tdir
7221
7222         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7223
7224         local stripe_size=$($LFS getstripe -S -d $dir) ||
7225                 error "$LFS getstripe -S -d $dir failed"
7226         stripe_size=${stripe_size%% *}
7227
7228         local file_size=$((stripe_size * OSTCOUNT))
7229         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7230         local required_space=$((file_num * file_size))
7231         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7232                            head -n1)
7233         [[ $free_space -le $((required_space / 1024)) ]] &&
7234                 skip_env "need $required_space, have $free_space kbytes"
7235
7236         local dd_bs=65536
7237         local dd_count=$((file_size / dd_bs))
7238
7239         # write data into the files
7240         local i
7241         local j
7242         local file
7243
7244         for i in $(seq $NUMFILES); do
7245                 file=$dir/file$i
7246                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7247                         error "write data into $file failed"
7248         done
7249         for i in $(seq $NUMDIRS); do
7250                 for j in $(seq $NUMFILES); do
7251                         file=$dir/dir$i/file$j
7252                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7253                                 error "write data into $file failed"
7254                 done
7255         done
7256
7257         # $LFS_MIGRATE will fail if hard link migration is unsupported
7258         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7259                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7260                         error "creating links to $dir/dir1/file1 failed"
7261         fi
7262
7263         local expected=-1
7264
7265         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7266
7267         # lfs_migrate file
7268         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7269
7270         echo "$cmd"
7271         eval $cmd || error "$cmd failed"
7272
7273         check_stripe_count $dir/file1 $expected
7274
7275         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7276         then
7277                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7278                 # OST 1 if it is on OST 0. This file is small enough to
7279                 # be on only one stripe.
7280                 file=$dir/migr_1_ost
7281                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7282                         error "write data into $file failed"
7283                 local obdidx=$($LFS getstripe -i $file)
7284                 local oldmd5=$(md5sum $file)
7285                 local newobdidx=0
7286
7287                 [[ $obdidx -eq 0 ]] && newobdidx=1
7288                 cmd="$LFS migrate -i $newobdidx $file"
7289                 echo $cmd
7290                 eval $cmd || error "$cmd failed"
7291
7292                 local realobdix=$($LFS getstripe -i $file)
7293                 local newmd5=$(md5sum $file)
7294
7295                 [[ $newobdidx -ne $realobdix ]] &&
7296                         error "new OST is different (was=$obdidx, "\
7297                               "wanted=$newobdidx, got=$realobdix)"
7298                 [[ "$oldmd5" != "$newmd5" ]] &&
7299                         error "md5sum differ: $oldmd5, $newmd5"
7300         fi
7301
7302         # lfs_migrate dir
7303         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7304         echo "$cmd"
7305         eval $cmd || error "$cmd failed"
7306
7307         for j in $(seq $NUMFILES); do
7308                 check_stripe_count $dir/dir1/file$j $expected
7309         done
7310
7311         # lfs_migrate works with lfs find
7312         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7313              $LFS_MIGRATE -y -c $expected"
7314         echo "$cmd"
7315         eval $cmd || error "$cmd failed"
7316
7317         for i in $(seq 2 $NUMFILES); do
7318                 check_stripe_count $dir/file$i $expected
7319         done
7320         for i in $(seq 2 $NUMDIRS); do
7321                 for j in $(seq $NUMFILES); do
7322                 check_stripe_count $dir/dir$i/file$j $expected
7323                 done
7324         done
7325 }
7326 run_test 56w "check lfs_migrate -c stripe_count works"
7327
7328 test_56wb() {
7329         local file1=$DIR/$tdir/file1
7330         local create_pool=false
7331         local initial_pool=$($LFS getstripe -p $DIR)
7332         local pool_list=()
7333         local pool=""
7334
7335         echo -n "Creating test dir..."
7336         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7337         echo "done."
7338
7339         echo -n "Creating test file..."
7340         touch $file1 || error "cannot create file"
7341         echo "done."
7342
7343         echo -n "Detecting existing pools..."
7344         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7345
7346         if [ ${#pool_list[@]} -gt 0 ]; then
7347                 echo "${pool_list[@]}"
7348                 for thispool in "${pool_list[@]}"; do
7349                         if [[ -z "$initial_pool" ||
7350                               "$initial_pool" != "$thispool" ]]; then
7351                                 pool="$thispool"
7352                                 echo "Using existing pool '$pool'"
7353                                 break
7354                         fi
7355                 done
7356         else
7357                 echo "none detected."
7358         fi
7359         if [ -z "$pool" ]; then
7360                 pool=${POOL:-testpool}
7361                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7362                 echo -n "Creating pool '$pool'..."
7363                 create_pool=true
7364                 pool_add $pool &> /dev/null ||
7365                         error "pool_add failed"
7366                 echo "done."
7367
7368                 echo -n "Adding target to pool..."
7369                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7370                         error "pool_add_targets failed"
7371                 echo "done."
7372         fi
7373
7374         echo -n "Setting pool using -p option..."
7375         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7376                 error "migrate failed rc = $?"
7377         echo "done."
7378
7379         echo -n "Verifying test file is in pool after migrating..."
7380         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7381                 error "file was not migrated to pool $pool"
7382         echo "done."
7383
7384         echo -n "Removing test file from pool '$pool'..."
7385         # "lfs migrate $file" won't remove the file from the pool
7386         # until some striping information is changed.
7387         $LFS migrate -c 1 $file1 &> /dev/null ||
7388                 error "cannot remove from pool"
7389         [ "$($LFS getstripe -p $file1)" ] &&
7390                 error "pool still set"
7391         echo "done."
7392
7393         echo -n "Setting pool using --pool option..."
7394         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7395                 error "migrate failed rc = $?"
7396         echo "done."
7397
7398         # Clean up
7399         rm -f $file1
7400         if $create_pool; then
7401                 destroy_test_pools 2> /dev/null ||
7402                         error "destroy test pools failed"
7403         fi
7404 }
7405 run_test 56wb "check lfs_migrate pool support"
7406
7407 test_56wc() {
7408         local file1="$DIR/$tdir/file1"
7409         local parent_ssize
7410         local parent_scount
7411         local cur_ssize
7412         local cur_scount
7413         local orig_ssize
7414
7415         echo -n "Creating test dir..."
7416         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7417         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7418                 error "cannot set stripe by '-S 1M -c 1'"
7419         echo "done"
7420
7421         echo -n "Setting initial stripe for test file..."
7422         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7423                 error "cannot set stripe"
7424         cur_ssize=$($LFS getstripe -S "$file1")
7425         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7426         echo "done."
7427
7428         # File currently set to -S 512K -c 1
7429
7430         # Ensure -c and -S options are rejected when -R is set
7431         echo -n "Verifying incompatible options are detected..."
7432         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7433                 error "incompatible -c and -R options not detected"
7434         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7435                 error "incompatible -S and -R options not detected"
7436         echo "done."
7437
7438         # Ensure unrecognized options are passed through to 'lfs migrate'
7439         echo -n "Verifying -S option is passed through to lfs migrate..."
7440         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7441                 error "migration failed"
7442         cur_ssize=$($LFS getstripe -S "$file1")
7443         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7444         echo "done."
7445
7446         # File currently set to -S 1M -c 1
7447
7448         # Ensure long options are supported
7449         echo -n "Verifying long options supported..."
7450         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7451                 error "long option without argument not supported"
7452         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7453                 error "long option with argument not supported"
7454         cur_ssize=$($LFS getstripe -S "$file1")
7455         [ $cur_ssize -eq 524288 ] ||
7456                 error "migrate --stripe-size $cur_ssize != 524288"
7457         echo "done."
7458
7459         # File currently set to -S 512K -c 1
7460
7461         if [ "$OSTCOUNT" -gt 1 ]; then
7462                 echo -n "Verifying explicit stripe count can be set..."
7463                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7464                         error "migrate failed"
7465                 cur_scount=$($LFS getstripe -c "$file1")
7466                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7467                 echo "done."
7468         fi
7469
7470         # File currently set to -S 512K -c 1 or -S 512K -c 2
7471
7472         # Ensure parent striping is used if -R is set, and no stripe
7473         # count or size is specified
7474         echo -n "Setting stripe for parent directory..."
7475         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7476                 error "cannot set stripe '-S 2M -c 1'"
7477         echo "done."
7478
7479         echo -n "Verifying restripe option uses parent stripe settings..."
7480         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7481         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7482         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7483                 error "migrate failed"
7484         cur_ssize=$($LFS getstripe -S "$file1")
7485         [ $cur_ssize -eq $parent_ssize ] ||
7486                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7487         cur_scount=$($LFS getstripe -c "$file1")
7488         [ $cur_scount -eq $parent_scount ] ||
7489                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7490         echo "done."
7491
7492         # File currently set to -S 1M -c 1
7493
7494         # Ensure striping is preserved if -R is not set, and no stripe
7495         # count or size is specified
7496         echo -n "Verifying striping size preserved when not specified..."
7497         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7498         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7499                 error "cannot set stripe on parent directory"
7500         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7501                 error "migrate failed"
7502         cur_ssize=$($LFS getstripe -S "$file1")
7503         [ $cur_ssize -eq $orig_ssize ] ||
7504                 error "migrate by default $cur_ssize != $orig_ssize"
7505         echo "done."
7506
7507         # Ensure file name properly detected when final option has no argument
7508         echo -n "Verifying file name properly detected..."
7509         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7510                 error "file name interpreted as option argument"
7511         echo "done."
7512
7513         # Clean up
7514         rm -f "$file1"
7515 }
7516 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7517
7518 test_56wd() {
7519         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7520
7521         local file1=$DIR/$tdir/file1
7522
7523         echo -n "Creating test dir..."
7524         test_mkdir $DIR/$tdir || error "cannot create dir"
7525         echo "done."
7526
7527         echo -n "Creating test file..."
7528         touch $file1
7529         echo "done."
7530
7531         # Ensure 'lfs migrate' will fail by using a non-existent option,
7532         # and make sure rsync is not called to recover
7533         echo -n "Make sure --no-rsync option works..."
7534         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7535                 grep -q 'refusing to fall back to rsync' ||
7536                 error "rsync was called with --no-rsync set"
7537         echo "done."
7538
7539         # Ensure rsync is called without trying 'lfs migrate' first
7540         echo -n "Make sure --rsync option works..."
7541         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7542                 grep -q 'falling back to rsync' &&
7543                 error "lfs migrate was called with --rsync set"
7544         echo "done."
7545
7546         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7547         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7548                 grep -q 'at the same time' ||
7549                 error "--rsync and --no-rsync accepted concurrently"
7550         echo "done."
7551
7552         # Clean up
7553         rm -f $file1
7554 }
7555 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7556
7557 test_56we() {
7558         local td=$DIR/$tdir
7559         local tf=$td/$tfile
7560
7561         test_mkdir $td || error "cannot create $td"
7562         touch $tf || error "cannot touch $tf"
7563
7564         echo -n "Make sure --non-direct|-D works..."
7565         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7566                 grep -q "lfs migrate --non-direct" ||
7567                 error "--non-direct option cannot work correctly"
7568         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7569                 grep -q "lfs migrate -D" ||
7570                 error "-D option cannot work correctly"
7571         echo "done."
7572 }
7573 run_test 56we "check lfs_migrate --non-direct|-D support"
7574
7575 test_56x() {
7576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7577         check_swap_layouts_support
7578
7579         local dir=$DIR/$tdir
7580         local ref1=/etc/passwd
7581         local file1=$dir/file1
7582
7583         test_mkdir $dir || error "creating dir $dir"
7584         $LFS setstripe -c 2 $file1
7585         cp $ref1 $file1
7586         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7587         stripe=$($LFS getstripe -c $file1)
7588         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7589         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7590
7591         # clean up
7592         rm -f $file1
7593 }
7594 run_test 56x "lfs migration support"
7595
7596 test_56xa() {
7597         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7598         check_swap_layouts_support
7599
7600         local dir=$DIR/$tdir/$testnum
7601
7602         test_mkdir -p $dir
7603
7604         local ref1=/etc/passwd
7605         local file1=$dir/file1
7606
7607         $LFS setstripe -c 2 $file1
7608         cp $ref1 $file1
7609         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7610
7611         local stripe=$($LFS getstripe -c $file1)
7612
7613         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7614         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7615
7616         # clean up
7617         rm -f $file1
7618 }
7619 run_test 56xa "lfs migration --block support"
7620
7621 check_migrate_links() {
7622         local dir="$1"
7623         local file1="$dir/file1"
7624         local begin="$2"
7625         local count="$3"
7626         local runas="$4"
7627         local total_count=$(($begin + $count - 1))
7628         local symlink_count=10
7629         local uniq_count=10
7630
7631         if [ ! -f "$file1" ]; then
7632                 echo -n "creating initial file..."
7633                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7634                         error "cannot setstripe initial file"
7635                 echo "done"
7636
7637                 echo -n "creating symlinks..."
7638                 for s in $(seq 1 $symlink_count); do
7639                         ln -s "$file1" "$dir/slink$s" ||
7640                                 error "cannot create symlinks"
7641                 done
7642                 echo "done"
7643
7644                 echo -n "creating nonlinked files..."
7645                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7646                         error "cannot create nonlinked files"
7647                 echo "done"
7648         fi
7649
7650         # create hard links
7651         if [ ! -f "$dir/file$total_count" ]; then
7652                 echo -n "creating hard links $begin:$total_count..."
7653                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7654                         /dev/null || error "cannot create hard links"
7655                 echo "done"
7656         fi
7657
7658         echo -n "checking number of hard links listed in xattrs..."
7659         local fid=$($LFS getstripe -F "$file1")
7660         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7661
7662         echo "${#paths[*]}"
7663         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7664                         skip "hard link list has unexpected size, skipping test"
7665         fi
7666         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7667                         error "link names should exceed xattrs size"
7668         fi
7669
7670         echo -n "migrating files..."
7671         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7672         local rc=$?
7673         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7674         echo "done"
7675
7676         # make sure all links have been properly migrated
7677         echo -n "verifying files..."
7678         fid=$($LFS getstripe -F "$file1") ||
7679                 error "cannot get fid for file $file1"
7680         for i in $(seq 2 $total_count); do
7681                 local fid2=$($LFS getstripe -F $dir/file$i)
7682
7683                 [ "$fid2" == "$fid" ] ||
7684                         error "migrated hard link has mismatched FID"
7685         done
7686
7687         # make sure hard links were properly detected, and migration was
7688         # performed only once for the entire link set; nonlinked files should
7689         # also be migrated
7690         local actual=$(grep -c 'done' <<< "$migrate_out")
7691         local expected=$(($uniq_count + 1))
7692
7693         [ "$actual" -eq  "$expected" ] ||
7694                 error "hard links individually migrated ($actual != $expected)"
7695
7696         # make sure the correct number of hard links are present
7697         local hardlinks=$(stat -c '%h' "$file1")
7698
7699         [ $hardlinks -eq $total_count ] ||
7700                 error "num hard links $hardlinks != $total_count"
7701         echo "done"
7702
7703         return 0
7704 }
7705
7706 test_56xb() {
7707         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7708                 skip "Need MDS version at least 2.10.55"
7709
7710         local dir="$DIR/$tdir"
7711
7712         test_mkdir "$dir" || error "cannot create dir $dir"
7713
7714         echo "testing lfs migrate mode when all links fit within xattrs"
7715         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7716
7717         echo "testing rsync mode when all links fit within xattrs"
7718         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7719
7720         echo "testing lfs migrate mode when all links do not fit within xattrs"
7721         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7722
7723         echo "testing rsync mode when all links do not fit within xattrs"
7724         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7725
7726         chown -R $RUNAS_ID $dir
7727         echo "testing non-root lfs migrate mode when not all links are in xattr"
7728         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7729
7730         # clean up
7731         rm -rf $dir
7732 }
7733 run_test 56xb "lfs migration hard link support"
7734
7735 test_56xc() {
7736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7737
7738         local dir="$DIR/$tdir"
7739
7740         test_mkdir "$dir" || error "cannot create dir $dir"
7741
7742         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7743         echo -n "Setting initial stripe for 20MB test file..."
7744         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7745                 error "cannot setstripe 20MB file"
7746         echo "done"
7747         echo -n "Sizing 20MB test file..."
7748         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7749         echo "done"
7750         echo -n "Verifying small file autostripe count is 1..."
7751         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7752                 error "cannot migrate 20MB file"
7753         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7754                 error "cannot get stripe for $dir/20mb"
7755         [ $stripe_count -eq 1 ] ||
7756                 error "unexpected stripe count $stripe_count for 20MB file"
7757         rm -f "$dir/20mb"
7758         echo "done"
7759
7760         # Test 2: File is small enough to fit within the available space on
7761         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7762         # have at least an additional 1KB for each desired stripe for test 3
7763         echo -n "Setting stripe for 1GB test file..."
7764         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7765         echo "done"
7766         echo -n "Sizing 1GB test file..."
7767         # File size is 1GB + 3KB
7768         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7769         echo "done"
7770
7771         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7772         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7773         if (( avail > 524288 * OSTCOUNT )); then
7774                 echo -n "Migrating 1GB file..."
7775                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7776                         error "cannot migrate 1GB file"
7777                 echo "done"
7778                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7779                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7780                         error "cannot getstripe for 1GB file"
7781                 [ $stripe_count -eq 2 ] ||
7782                         error "unexpected stripe count $stripe_count != 2"
7783                 echo "done"
7784         fi
7785
7786         # Test 3: File is too large to fit within the available space on
7787         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7788         if [ $OSTCOUNT -ge 3 ]; then
7789                 # The required available space is calculated as
7790                 # file size (1GB + 3KB) / OST count (3).
7791                 local kb_per_ost=349526
7792
7793                 echo -n "Migrating 1GB file with limit..."
7794                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7795                         error "cannot migrate 1GB file with limit"
7796                 echo "done"
7797
7798                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7799                 echo -n "Verifying 1GB autostripe count with limited space..."
7800                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7801                         error "unexpected stripe count $stripe_count (min 3)"
7802                 echo "done"
7803         fi
7804
7805         # clean up
7806         rm -rf $dir
7807 }
7808 run_test 56xc "lfs migration autostripe"
7809
7810 test_56xd() {
7811         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7812
7813         local dir=$DIR/$tdir
7814         local f_mgrt=$dir/$tfile.mgrt
7815         local f_yaml=$dir/$tfile.yaml
7816         local f_copy=$dir/$tfile.copy
7817         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7818         local layout_copy="-c 2 -S 2M -i 1"
7819         local yamlfile=$dir/yamlfile
7820         local layout_before;
7821         local layout_after;
7822
7823         test_mkdir "$dir" || error "cannot create dir $dir"
7824         $LFS setstripe $layout_yaml $f_yaml ||
7825                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7826         $LFS getstripe --yaml $f_yaml > $yamlfile
7827         $LFS setstripe $layout_copy $f_copy ||
7828                 error "cannot setstripe $f_copy with layout $layout_copy"
7829         touch $f_mgrt
7830         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7831
7832         # 1. test option --yaml
7833         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7834                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7835         layout_before=$(get_layout_param $f_yaml)
7836         layout_after=$(get_layout_param $f_mgrt)
7837         [ "$layout_after" == "$layout_before" ] ||
7838                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7839
7840         # 2. test option --copy
7841         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7842                 error "cannot migrate $f_mgrt with --copy $f_copy"
7843         layout_before=$(get_layout_param $f_copy)
7844         layout_after=$(get_layout_param $f_mgrt)
7845         [ "$layout_after" == "$layout_before" ] ||
7846                 error "lfs_migrate --copy: $layout_after != $layout_before"
7847 }
7848 run_test 56xd "check lfs_migrate --yaml and --copy support"
7849
7850 test_56xe() {
7851         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7852
7853         local dir=$DIR/$tdir
7854         local f_comp=$dir/$tfile
7855         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7856         local layout_before=""
7857         local layout_after=""
7858
7859         test_mkdir "$dir" || error "cannot create dir $dir"
7860         $LFS setstripe $layout $f_comp ||
7861                 error "cannot setstripe $f_comp with layout $layout"
7862         layout_before=$(get_layout_param $f_comp)
7863         dd if=/dev/zero of=$f_comp bs=1M count=4
7864
7865         # 1. migrate a comp layout file by lfs_migrate
7866         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7867         layout_after=$(get_layout_param $f_comp)
7868         [ "$layout_before" == "$layout_after" ] ||
7869                 error "lfs_migrate: $layout_before != $layout_after"
7870
7871         # 2. migrate a comp layout file by lfs migrate
7872         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7873         layout_after=$(get_layout_param $f_comp)
7874         [ "$layout_before" == "$layout_after" ] ||
7875                 error "lfs migrate: $layout_before != $layout_after"
7876 }
7877 run_test 56xe "migrate a composite layout file"
7878
7879 test_56xf() {
7880         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7881
7882         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7883                 skip "Need server version at least 2.13.53"
7884
7885         local dir=$DIR/$tdir
7886         local f_comp=$dir/$tfile
7887         local layout="-E 1M -c1 -E -1 -c2"
7888         local fid_before=""
7889         local fid_after=""
7890
7891         test_mkdir "$dir" || error "cannot create dir $dir"
7892         $LFS setstripe $layout $f_comp ||
7893                 error "cannot setstripe $f_comp with layout $layout"
7894         fid_before=$($LFS getstripe --fid $f_comp)
7895         dd if=/dev/zero of=$f_comp bs=1M count=4
7896
7897         # 1. migrate a comp layout file to a comp layout
7898         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7899         fid_after=$($LFS getstripe --fid $f_comp)
7900         [ "$fid_before" == "$fid_after" ] ||
7901                 error "comp-to-comp migrate: $fid_before != $fid_after"
7902
7903         # 2. migrate a comp layout file to a plain layout
7904         $LFS migrate -c2 $f_comp ||
7905                 error "cannot migrate $f_comp by lfs migrate"
7906         fid_after=$($LFS getstripe --fid $f_comp)
7907         [ "$fid_before" == "$fid_after" ] ||
7908                 error "comp-to-plain migrate: $fid_before != $fid_after"
7909
7910         # 3. migrate a plain layout file to a comp layout
7911         $LFS migrate $layout $f_comp ||
7912                 error "cannot migrate $f_comp by lfs migrate"
7913         fid_after=$($LFS getstripe --fid $f_comp)
7914         [ "$fid_before" == "$fid_after" ] ||
7915                 error "plain-to-comp migrate: $fid_before != $fid_after"
7916 }
7917 run_test 56xf "FID is not lost during migration of a composite layout file"
7918
7919 check_file_ost_range() {
7920         local file="$1"
7921         shift
7922         local range="$*"
7923         local -a file_range
7924         local idx
7925
7926         file_range=($($LFS getstripe -y "$file" |
7927                 awk '/l_ost_idx:/ { print $NF }'))
7928
7929         if [[ "${#file_range[@]}" = 0 ]]; then
7930                 echo "No osts found for $file"
7931                 return 1
7932         fi
7933
7934         for idx in "${file_range[@]}"; do
7935                 [[ " $range " =~ " $idx " ]] ||
7936                         return 1
7937         done
7938
7939         return 0
7940 }
7941
7942 sub_test_56xg() {
7943         local stripe_opt="$1"
7944         local pool="$2"
7945         shift 2
7946         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7947
7948         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7949                 error "Fail to migrate $tfile on $pool"
7950         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7951                 error "$tfile is not in pool $pool"
7952         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7953                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7954 }
7955
7956 test_56xg() {
7957         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7958         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7959         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7960                 skip "Need MDS version newer than 2.14.52"
7961
7962         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7963         local -a pool_ranges=("0 0" "1 1" "0 1")
7964
7965         # init pools
7966         for i in "${!pool_names[@]}"; do
7967                 pool_add ${pool_names[$i]} ||
7968                         error "pool_add failed (pool: ${pool_names[$i]})"
7969                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7970                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7971         done
7972
7973         # init the file to migrate
7974         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7975                 error "Unable to create $tfile on OST1"
7976         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7977                 error "Unable to write on $tfile"
7978
7979         echo "1. migrate $tfile on pool ${pool_names[0]}"
7980         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7981
7982         echo "2. migrate $tfile on pool ${pool_names[2]}"
7983         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7984
7985         echo "3. migrate $tfile on pool ${pool_names[1]}"
7986         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7987
7988         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7989         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7990         echo
7991
7992         # Clean pools
7993         destroy_test_pools ||
7994                 error "pool_destroy failed"
7995 }
7996 run_test 56xg "lfs migrate pool support"
7997
7998 test_56y() {
7999         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8000                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8001
8002         local res=""
8003         local dir=$DIR/$tdir
8004         local f1=$dir/file1
8005         local f2=$dir/file2
8006
8007         test_mkdir -p $dir || error "creating dir $dir"
8008         touch $f1 || error "creating std file $f1"
8009         $MULTIOP $f2 H2c || error "creating released file $f2"
8010
8011         # a directory can be raid0, so ask only for files
8012         res=$($LFS find $dir -L raid0 -type f | wc -l)
8013         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8014
8015         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8016         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8017
8018         # only files can be released, so no need to force file search
8019         res=$($LFS find $dir -L released)
8020         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8021
8022         res=$($LFS find $dir -type f \! -L released)
8023         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8024 }
8025 run_test 56y "lfs find -L raid0|released"
8026
8027 test_56z() { # LU-4824
8028         # This checks to make sure 'lfs find' continues after errors
8029         # There are two classes of errors that should be caught:
8030         # - If multiple paths are provided, all should be searched even if one
8031         #   errors out
8032         # - If errors are encountered during the search, it should not terminate
8033         #   early
8034         local dir=$DIR/$tdir
8035         local i
8036
8037         test_mkdir $dir
8038         for i in d{0..9}; do
8039                 test_mkdir $dir/$i
8040                 touch $dir/$i/$tfile
8041         done
8042         $LFS find $DIR/non_existent_dir $dir &&
8043                 error "$LFS find did not return an error"
8044         # Make a directory unsearchable. This should NOT be the last entry in
8045         # directory order.  Arbitrarily pick the 6th entry
8046         chmod 700 $($LFS find $dir -type d | sed '6!d')
8047
8048         $RUNAS $LFS find $DIR/non_existent $dir
8049         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8050
8051         # The user should be able to see 10 directories and 9 files
8052         (( count == 19 )) ||
8053                 error "$LFS find found $count != 19 entries after error"
8054 }
8055 run_test 56z "lfs find should continue after an error"
8056
8057 test_56aa() { # LU-5937
8058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8059
8060         local dir=$DIR/$tdir
8061
8062         mkdir $dir
8063         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8064
8065         createmany -o $dir/striped_dir/${tfile}- 1024
8066         local dirs=$($LFS find --size +8k $dir/)
8067
8068         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8069 }
8070 run_test 56aa "lfs find --size under striped dir"
8071
8072 test_56ab() { # LU-10705
8073         test_mkdir $DIR/$tdir
8074         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8075         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8076         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8077         # Flush writes to ensure valid blocks.  Need to be more thorough for
8078         # ZFS, since blocks are not allocated/returned to client immediately.
8079         sync_all_data
8080         wait_zfs_commit ost1 2
8081         cancel_lru_locks osc
8082         ls -ls $DIR/$tdir
8083
8084         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8085
8086         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8087
8088         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8089         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8090
8091         rm -f $DIR/$tdir/$tfile.[123]
8092 }
8093 run_test 56ab "lfs find --blocks"
8094
8095 # LU-11188
8096 test_56aca() {
8097         local dir="$DIR/$tdir"
8098         local perms=(001 002 003 004 005 006 007
8099                      010 020 030 040 050 060 070
8100                      100 200 300 400 500 600 700
8101                      111 222 333 444 555 666 777)
8102         local perm_minus=(8 8 4 8 4 4 2
8103                           8 8 4 8 4 4 2
8104                           8 8 4 8 4 4 2
8105                           4 4 2 4 2 2 1)
8106         local perm_slash=(8  8 12  8 12 12 14
8107                           8  8 12  8 12 12 14
8108                           8  8 12  8 12 12 14
8109                          16 16 24 16 24 24 28)
8110
8111         test_mkdir "$dir"
8112         for perm in ${perms[*]}; do
8113                 touch "$dir/$tfile.$perm"
8114                 chmod $perm "$dir/$tfile.$perm"
8115         done
8116
8117         for ((i = 0; i < ${#perms[*]}; i++)); do
8118                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8119                 (( $num == 1 )) ||
8120                         error "lfs find -perm ${perms[i]}:"\
8121                               "$num != 1"
8122
8123                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8124                 (( $num == ${perm_minus[i]} )) ||
8125                         error "lfs find -perm -${perms[i]}:"\
8126                               "$num != ${perm_minus[i]}"
8127
8128                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8129                 (( $num == ${perm_slash[i]} )) ||
8130                         error "lfs find -perm /${perms[i]}:"\
8131                               "$num != ${perm_slash[i]}"
8132         done
8133 }
8134 run_test 56aca "check lfs find -perm with octal representation"
8135
8136 test_56acb() {
8137         local dir=$DIR/$tdir
8138         # p is the permission of write and execute for user, group and other
8139         # without the umask. It is used to test +wx.
8140         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8141         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8142         local symbolic=(+t  a+t u+t g+t o+t
8143                         g+s u+s o+s +s o+sr
8144                         o=r,ug+o,u+w
8145                         u+ g+ o+ a+ ugo+
8146                         u- g- o- a- ugo-
8147                         u= g= o= a= ugo=
8148                         o=r,ug+o,u+w u=r,a+u,u+w
8149                         g=r,ugo=g,u+w u+x,+X +X
8150                         u+x,u+X u+X u+x,g+X o+r,+X
8151                         u+x,go+X +wx +rwx)
8152
8153         test_mkdir $dir
8154         for perm in ${perms[*]}; do
8155                 touch "$dir/$tfile.$perm"
8156                 chmod $perm "$dir/$tfile.$perm"
8157         done
8158
8159         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8160                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8161
8162                 (( $num == 1 )) ||
8163                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8164         done
8165 }
8166 run_test 56acb "check lfs find -perm with symbolic representation"
8167
8168 test_56acc() {
8169         local dir=$DIR/$tdir
8170         local tests="17777 787 789 abcd
8171                 ug=uu ug=a ug=gu uo=ou urw
8172                 u+xg+x a=r,u+x,"
8173
8174         test_mkdir $dir
8175         for err in $tests; do
8176                 if $LFS find $dir -perm $err 2>/dev/null; then
8177                         error "lfs find -perm $err: parsing should have failed"
8178                 fi
8179         done
8180 }
8181 run_test 56acc "check parsing error for lfs find -perm"
8182
8183 test_56ba() {
8184         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8185                 skip "Need MDS version at least 2.10.50"
8186
8187         # Create composite files with one component
8188         local dir=$DIR/$tdir
8189
8190         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8191         # Create composite files with three components
8192         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8193         # Create non-composite files
8194         createmany -o $dir/${tfile}- 10
8195
8196         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8197
8198         [[ $nfiles == 10 ]] ||
8199                 error "lfs find -E 1M found $nfiles != 10 files"
8200
8201         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8202         [[ $nfiles == 25 ]] ||
8203                 error "lfs find ! -E 1M found $nfiles != 25 files"
8204
8205         # All files have a component that starts at 0
8206         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8207         [[ $nfiles == 35 ]] ||
8208                 error "lfs find --component-start 0 - $nfiles != 35 files"
8209
8210         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8211         [[ $nfiles == 15 ]] ||
8212                 error "lfs find --component-start 2M - $nfiles != 15 files"
8213
8214         # All files created here have a componenet that does not starts at 2M
8215         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8216         [[ $nfiles == 35 ]] ||
8217                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8218
8219         # Find files with a specified number of components
8220         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8221         [[ $nfiles == 15 ]] ||
8222                 error "lfs find --component-count 3 - $nfiles != 15 files"
8223
8224         # Remember non-composite files have a component count of zero
8225         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8226         [[ $nfiles == 10 ]] ||
8227                 error "lfs find --component-count 0 - $nfiles != 10 files"
8228
8229         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8230         [[ $nfiles == 20 ]] ||
8231                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8232
8233         # All files have a flag called "init"
8234         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8235         [[ $nfiles == 35 ]] ||
8236                 error "lfs find --component-flags init - $nfiles != 35 files"
8237
8238         # Multi-component files will have a component not initialized
8239         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8240         [[ $nfiles == 15 ]] ||
8241                 error "lfs find !--component-flags init - $nfiles != 15 files"
8242
8243         rm -rf $dir
8244
8245 }
8246 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8247
8248 test_56ca() {
8249         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8250                 skip "Need MDS version at least 2.10.57"
8251
8252         local td=$DIR/$tdir
8253         local tf=$td/$tfile
8254         local dir
8255         local nfiles
8256         local cmd
8257         local i
8258         local j
8259
8260         # create mirrored directories and mirrored files
8261         mkdir $td || error "mkdir $td failed"
8262         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8263         createmany -o $tf- 10 || error "create $tf- failed"
8264
8265         for i in $(seq 2); do
8266                 dir=$td/dir$i
8267                 mkdir $dir || error "mkdir $dir failed"
8268                 $LFS mirror create -N$((3 + i)) $dir ||
8269                         error "create mirrored dir $dir failed"
8270                 createmany -o $dir/$tfile- 10 ||
8271                         error "create $dir/$tfile- failed"
8272         done
8273
8274         # change the states of some mirrored files
8275         echo foo > $tf-6
8276         for i in $(seq 2); do
8277                 dir=$td/dir$i
8278                 for j in $(seq 4 9); do
8279                         echo foo > $dir/$tfile-$j
8280                 done
8281         done
8282
8283         # find mirrored files with specific mirror count
8284         cmd="$LFS find --mirror-count 3 --type f $td"
8285         nfiles=$($cmd | wc -l)
8286         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8287
8288         cmd="$LFS find ! --mirror-count 3 --type f $td"
8289         nfiles=$($cmd | wc -l)
8290         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8291
8292         cmd="$LFS find --mirror-count +2 --type f $td"
8293         nfiles=$($cmd | wc -l)
8294         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8295
8296         cmd="$LFS find --mirror-count -6 --type f $td"
8297         nfiles=$($cmd | wc -l)
8298         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8299
8300         # find mirrored files with specific file state
8301         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8302         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8303
8304         cmd="$LFS find --mirror-state=ro --type f $td"
8305         nfiles=$($cmd | wc -l)
8306         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8307
8308         cmd="$LFS find ! --mirror-state=ro --type f $td"
8309         nfiles=$($cmd | wc -l)
8310         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8311
8312         cmd="$LFS find --mirror-state=wp --type f $td"
8313         nfiles=$($cmd | wc -l)
8314         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8315
8316         cmd="$LFS find ! --mirror-state=sp --type f $td"
8317         nfiles=$($cmd | wc -l)
8318         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8319 }
8320 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8321
8322 test_56da() { # LU-14179
8323         local path=$DIR/$tdir
8324
8325         test_mkdir $path
8326         cd $path
8327
8328         local longdir=$(str_repeat 'a' 255)
8329
8330         for i in {1..15}; do
8331                 path=$path/$longdir
8332                 test_mkdir $longdir
8333                 cd $longdir
8334         done
8335
8336         local len=${#path}
8337         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8338
8339         test_mkdir $lastdir
8340         cd $lastdir
8341         # PATH_MAX-1
8342         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8343
8344         # NAME_MAX
8345         touch $(str_repeat 'f' 255)
8346
8347         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8348                 error "lfs find reported an error"
8349
8350         rm -rf $DIR/$tdir
8351 }
8352 run_test 56da "test lfs find with long paths"
8353
8354 test_56ea() { #LU-10378
8355         local path=$DIR/$tdir
8356         local pool=$TESTNAME
8357
8358         # Create ost pool
8359         pool_add $pool || error "pool_add $pool failed"
8360         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8361                 error "adding targets to $pool failed"
8362
8363         # Set default pool on directory before creating file
8364         mkdir $path || error "mkdir $path failed"
8365         $LFS setstripe -p $pool $path ||
8366                 error "set OST pool on $pool failed"
8367         touch $path/$tfile || error "touch $path/$tfile failed"
8368
8369         # Compare basic file attributes from -printf and stat
8370         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8371         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8372
8373         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8374                 error "Attrs from lfs find and stat don't match"
8375
8376         # Compare Lustre attributes from lfs find and lfs getstripe
8377         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8378         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8379         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8380         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8381         local fpool=$($LFS getstripe --pool $path/$tfile)
8382         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8383
8384         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8385                 error "Attrs from lfs find and lfs getstripe don't match"
8386
8387         # Verify behavior for unknown escape/format sequences
8388         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8389
8390         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8391                 error "Escape/format codes don't match"
8392 }
8393 run_test 56ea "test lfs find -printf option"
8394
8395 test_57a() {
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397         # note test will not do anything if MDS is not local
8398         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8399                 skip_env "ldiskfs only test"
8400         fi
8401         remote_mds_nodsh && skip "remote MDS with nodsh"
8402
8403         local MNTDEV="osd*.*MDT*.mntdev"
8404         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8405         [ -z "$DEV" ] && error "can't access $MNTDEV"
8406         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8407                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8408                         error "can't access $DEV"
8409                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8410                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8411                 rm $TMP/t57a.dump
8412         done
8413 }
8414 run_test 57a "verify MDS filesystem created with large inodes =="
8415
8416 test_57b() {
8417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8418         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8419                 skip_env "ldiskfs only test"
8420         fi
8421         remote_mds_nodsh && skip "remote MDS with nodsh"
8422
8423         local dir=$DIR/$tdir
8424         local filecount=100
8425         local file1=$dir/f1
8426         local fileN=$dir/f$filecount
8427
8428         rm -rf $dir || error "removing $dir"
8429         test_mkdir -c1 $dir
8430         local mdtidx=$($LFS getstripe -m $dir)
8431         local mdtname=MDT$(printf %04x $mdtidx)
8432         local facet=mds$((mdtidx + 1))
8433
8434         echo "mcreating $filecount files"
8435         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8436
8437         # verify that files do not have EAs yet
8438         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8439                 error "$file1 has an EA"
8440         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8441                 error "$fileN has an EA"
8442
8443         sync
8444         sleep 1
8445         df $dir  #make sure we get new statfs data
8446         local mdsfree=$(do_facet $facet \
8447                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8448         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8449         local file
8450
8451         echo "opening files to create objects/EAs"
8452         for file in $(seq -f $dir/f%g 1 $filecount); do
8453                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8454                         error "opening $file"
8455         done
8456
8457         # verify that files have EAs now
8458         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8459         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8460
8461         sleep 1  #make sure we get new statfs data
8462         df $dir
8463         local mdsfree2=$(do_facet $facet \
8464                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8465         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8466
8467         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8468                 if [ "$mdsfree" != "$mdsfree2" ]; then
8469                         error "MDC before $mdcfree != after $mdcfree2"
8470                 else
8471                         echo "MDC before $mdcfree != after $mdcfree2"
8472                         echo "unable to confirm if MDS has large inodes"
8473                 fi
8474         fi
8475         rm -rf $dir
8476 }
8477 run_test 57b "default LOV EAs are stored inside large inodes ==="
8478
8479 test_58() {
8480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8481         [ -z "$(which wiretest 2>/dev/null)" ] &&
8482                         skip_env "could not find wiretest"
8483
8484         wiretest
8485 }
8486 run_test 58 "verify cross-platform wire constants =============="
8487
8488 test_59() {
8489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8490
8491         echo "touch 130 files"
8492         createmany -o $DIR/f59- 130
8493         echo "rm 130 files"
8494         unlinkmany $DIR/f59- 130
8495         sync
8496         # wait for commitment of removal
8497         wait_delete_completed
8498 }
8499 run_test 59 "verify cancellation of llog records async ========="
8500
8501 TEST60_HEAD="test_60 run $RANDOM"
8502 test_60a() {
8503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8504         remote_mgs_nodsh && skip "remote MGS with nodsh"
8505         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8506                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8507                         skip_env "missing subtest run-llog.sh"
8508
8509         log "$TEST60_HEAD - from kernel mode"
8510         do_facet mgs "$LCTL dk > /dev/null"
8511         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8512         do_facet mgs $LCTL dk > $TMP/$tfile
8513
8514         # LU-6388: test llog_reader
8515         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8516         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8517         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8518                         skip_env "missing llog_reader"
8519         local fstype=$(facet_fstype mgs)
8520         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8521                 skip_env "Only for ldiskfs or zfs type mgs"
8522
8523         local mntpt=$(facet_mntpt mgs)
8524         local mgsdev=$(mgsdevname 1)
8525         local fid_list
8526         local fid
8527         local rec_list
8528         local rec
8529         local rec_type
8530         local obj_file
8531         local path
8532         local seq
8533         local oid
8534         local pass=true
8535
8536         #get fid and record list
8537         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8538                 tail -n 4))
8539         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8540                 tail -n 4))
8541         #remount mgs as ldiskfs or zfs type
8542         stop mgs || error "stop mgs failed"
8543         mount_fstype mgs || error "remount mgs failed"
8544         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8545                 fid=${fid_list[i]}
8546                 rec=${rec_list[i]}
8547                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8548                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8549                 oid=$((16#$oid))
8550
8551                 case $fstype in
8552                         ldiskfs )
8553                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8554                         zfs )
8555                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8556                 esac
8557                 echo "obj_file is $obj_file"
8558                 do_facet mgs $llog_reader $obj_file
8559
8560                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8561                         awk '{ print $3 }' | sed -e "s/^type=//g")
8562                 if [ $rec_type != $rec ]; then
8563                         echo "FAILED test_60a wrong record type $rec_type," \
8564                               "should be $rec"
8565                         pass=false
8566                         break
8567                 fi
8568
8569                 #check obj path if record type is LLOG_LOGID_MAGIC
8570                 if [ "$rec" == "1064553b" ]; then
8571                         path=$(do_facet mgs $llog_reader $obj_file |
8572                                 grep "path=" | awk '{ print $NF }' |
8573                                 sed -e "s/^path=//g")
8574                         if [ $obj_file != $mntpt/$path ]; then
8575                                 echo "FAILED test_60a wrong obj path" \
8576                                       "$montpt/$path, should be $obj_file"
8577                                 pass=false
8578                                 break
8579                         fi
8580                 fi
8581         done
8582         rm -f $TMP/$tfile
8583         #restart mgs before "error", otherwise it will block the next test
8584         stop mgs || error "stop mgs failed"
8585         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8586         $pass || error "test failed, see FAILED test_60a messages for specifics"
8587 }
8588 run_test 60a "llog_test run from kernel module and test llog_reader"
8589
8590 test_60b() { # bug 6411
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592
8593         dmesg > $DIR/$tfile
8594         LLOG_COUNT=$(do_facet mgs dmesg |
8595                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8596                           /llog_[a-z]*.c:[0-9]/ {
8597                                 if (marker)
8598                                         from_marker++
8599                                 from_begin++
8600                           }
8601                           END {
8602                                 if (marker)
8603                                         print from_marker
8604                                 else
8605                                         print from_begin
8606                           }")
8607
8608         [[ $LLOG_COUNT -gt 120 ]] &&
8609                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8610 }
8611 run_test 60b "limit repeated messages from CERROR/CWARN"
8612
8613 test_60c() {
8614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8615
8616         echo "create 5000 files"
8617         createmany -o $DIR/f60c- 5000
8618 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8619         lctl set_param fail_loc=0x80000137
8620         unlinkmany $DIR/f60c- 5000
8621         lctl set_param fail_loc=0
8622 }
8623 run_test 60c "unlink file when mds full"
8624
8625 test_60d() {
8626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8627
8628         SAVEPRINTK=$(lctl get_param -n printk)
8629         # verify "lctl mark" is even working"
8630         MESSAGE="test message ID $RANDOM $$"
8631         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8632         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8633
8634         lctl set_param printk=0 || error "set lnet.printk failed"
8635         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8636         MESSAGE="new test message ID $RANDOM $$"
8637         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8638         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8639         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8640
8641         lctl set_param -n printk="$SAVEPRINTK"
8642 }
8643 run_test 60d "test printk console message masking"
8644
8645 test_60e() {
8646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8647         remote_mds_nodsh && skip "remote MDS with nodsh"
8648
8649         touch $DIR/$tfile
8650 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8651         do_facet mds1 lctl set_param fail_loc=0x15b
8652         rm $DIR/$tfile
8653 }
8654 run_test 60e "no space while new llog is being created"
8655
8656 test_60f() {
8657         local old_path=$($LCTL get_param -n debug_path)
8658
8659         stack_trap "$LCTL set_param debug_path=$old_path"
8660         stack_trap "rm -f $TMP/$tfile*"
8661         rm -f $TMP/$tfile* 2> /dev/null
8662         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8663         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8664         test_mkdir $DIR/$tdir
8665         # retry in case the open is cached and not released
8666         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8667                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8668                 sleep 0.1
8669         done
8670         ls $TMP/$tfile*
8671         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8672 }
8673 run_test 60f "change debug_path works"
8674
8675 test_60g() {
8676         local pid
8677         local i
8678
8679         test_mkdir -c $MDSCOUNT $DIR/$tdir
8680
8681         (
8682                 local index=0
8683                 while true; do
8684                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8685                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8686                                 2>/dev/null
8687                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8688                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8689                         index=$((index + 1))
8690                 done
8691         ) &
8692
8693         pid=$!
8694
8695         for i in {0..100}; do
8696                 # define OBD_FAIL_OSD_TXN_START    0x19a
8697                 local index=$((i % MDSCOUNT + 1))
8698
8699                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8700                         > /dev/null
8701                 sleep 0.01
8702         done
8703
8704         kill -9 $pid
8705
8706         for i in $(seq $MDSCOUNT); do
8707                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8708         done
8709
8710         mkdir $DIR/$tdir/new || error "mkdir failed"
8711         rmdir $DIR/$tdir/new || error "rmdir failed"
8712
8713         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8714                 -t namespace
8715         for i in $(seq $MDSCOUNT); do
8716                 wait_update_facet mds$i "$LCTL get_param -n \
8717                         mdd.$(facet_svc mds$i).lfsck_namespace |
8718                         awk '/^status/ { print \\\$2 }'" "completed"
8719         done
8720
8721         ls -R $DIR/$tdir
8722         rm -rf $DIR/$tdir || error "rmdir failed"
8723 }
8724 run_test 60g "transaction abort won't cause MDT hung"
8725
8726 test_60h() {
8727         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8728                 skip "Need MDS version at least 2.12.52"
8729         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8730
8731         local f
8732
8733         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8734         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8735         for fail_loc in 0x80000188 0x80000189; do
8736                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8737                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8738                         error "mkdir $dir-$fail_loc failed"
8739                 for i in {0..10}; do
8740                         # create may fail on missing stripe
8741                         echo $i > $DIR/$tdir-$fail_loc/$i
8742                 done
8743                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8744                         error "getdirstripe $tdir-$fail_loc failed"
8745                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8746                         error "migrate $tdir-$fail_loc failed"
8747                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8748                         error "getdirstripe $tdir-$fail_loc failed"
8749                 pushd $DIR/$tdir-$fail_loc
8750                 for f in *; do
8751                         echo $f | cmp $f - || error "$f data mismatch"
8752                 done
8753                 popd
8754                 rm -rf $DIR/$tdir-$fail_loc
8755         done
8756 }
8757 run_test 60h "striped directory with missing stripes can be accessed"
8758
8759 function t60i_load() {
8760         mkdir $DIR/$tdir
8761         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8762         $LCTL set_param fail_loc=0x131c fail_val=1
8763         for ((i=0; i<5000; i++)); do
8764                 touch $DIR/$tdir/f$i
8765         done
8766 }
8767
8768 test_60i() {
8769         changelog_register || error "changelog_register failed"
8770         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8771         changelog_users $SINGLEMDS | grep -q $cl_user ||
8772                 error "User $cl_user not found in changelog_users"
8773         changelog_chmask "ALL"
8774         t60i_load &
8775         local PID=$!
8776         for((i=0; i<100; i++)); do
8777                 changelog_dump >/dev/null ||
8778                         error "can't read changelog"
8779         done
8780         kill $PID
8781         wait $PID
8782         changelog_deregister || error "changelog_deregister failed"
8783         $LCTL set_param fail_loc=0
8784 }
8785 run_test 60i "llog: new record vs reader race"
8786
8787 test_60j() {
8788         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8789                 skip "need MDS version at least 2.15.50"
8790         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8791         remote_mds_nodsh && skip "remote MDS with nodsh"
8792         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8793
8794         changelog_users $SINGLEMDS | grep "^cl" &&
8795                 skip "active changelog user"
8796
8797         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8798
8799         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8800                 skip_env "missing llog_reader"
8801
8802         mkdir_on_mdt0 $DIR/$tdir
8803
8804         local f=$DIR/$tdir/$tfile
8805         local mdt_dev
8806         local tmpfile
8807         local plain
8808
8809         changelog_register || error "cannot register changelog user"
8810
8811         # set changelog_mask to ALL
8812         changelog_chmask "ALL"
8813         changelog_clear
8814
8815         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8816         unlinkmany ${f}- 100 || error "unlinkmany failed"
8817
8818         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8819         mdt_dev=$(facet_device $SINGLEMDS)
8820
8821         do_facet $SINGLEMDS sync
8822         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8823                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8824                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8825
8826         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8827
8828         # if $tmpfile is not on EXT3 filesystem for some reason
8829         [[ ${plain:0:1} == 'O' ]] ||
8830                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8831
8832         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8833                 $mdt_dev; stat -c %s $tmpfile")
8834         echo "Truncate llog from $size to $((size - size % 8192))"
8835         size=$((size - size % 8192))
8836         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8837         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8838                 grep -c 'in bitmap only')
8839         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8840
8841         size=$((size - 9000))
8842         echo "Corrupt llog in the middle at $size"
8843         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8844                 count=333 conv=notrunc
8845         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8846                 grep -c 'next chunk')
8847         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
8848 }
8849 run_test 60j "llog_reader reports corruptions"
8850
8851 test_61a() {
8852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8853
8854         f="$DIR/f61"
8855         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8856         cancel_lru_locks osc
8857         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8858         sync
8859 }
8860 run_test 61a "mmap() writes don't make sync hang ================"
8861
8862 test_61b() {
8863         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8864 }
8865 run_test 61b "mmap() of unstriped file is successful"
8866
8867 # bug 2330 - insufficient obd_match error checking causes LBUG
8868 test_62() {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870
8871         f="$DIR/f62"
8872         echo foo > $f
8873         cancel_lru_locks osc
8874         lctl set_param fail_loc=0x405
8875         cat $f && error "cat succeeded, expect -EIO"
8876         lctl set_param fail_loc=0
8877 }
8878 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8879 # match every page all of the time.
8880 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8881
8882 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8883 # Though this test is irrelevant anymore, it helped to reveal some
8884 # other grant bugs (LU-4482), let's keep it.
8885 test_63a() {   # was test_63
8886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8887
8888         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8889
8890         for i in `seq 10` ; do
8891                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8892                 sleep 5
8893                 kill $!
8894                 sleep 1
8895         done
8896
8897         rm -f $DIR/f63 || true
8898 }
8899 run_test 63a "Verify oig_wait interruption does not crash ======="
8900
8901 # bug 2248 - async write errors didn't return to application on sync
8902 # bug 3677 - async write errors left page locked
8903 test_63b() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905
8906         debugsave
8907         lctl set_param debug=-1
8908
8909         # ensure we have a grant to do async writes
8910         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8911         rm $DIR/$tfile
8912
8913         sync    # sync lest earlier test intercept the fail_loc
8914
8915         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8916         lctl set_param fail_loc=0x80000406
8917         $MULTIOP $DIR/$tfile Owy && \
8918                 error "sync didn't return ENOMEM"
8919         sync; sleep 2; sync     # do a real sync this time to flush page
8920         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8921                 error "locked page left in cache after async error" || true
8922         debugrestore
8923 }
8924 run_test 63b "async write errors should be returned to fsync ==="
8925
8926 test_64a () {
8927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8928
8929         lfs df $DIR
8930         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8931 }
8932 run_test 64a "verify filter grant calculations (in kernel) ====="
8933
8934 test_64b () {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8938 }
8939 run_test 64b "check out-of-space detection on client"
8940
8941 test_64c() {
8942         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8943 }
8944 run_test 64c "verify grant shrink"
8945
8946 import_param() {
8947         local tgt=$1
8948         local param=$2
8949
8950         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8951 }
8952
8953 # this does exactly what osc_request.c:osc_announce_cached() does in
8954 # order to calculate max amount of grants to ask from server
8955 want_grant() {
8956         local tgt=$1
8957
8958         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8959         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8960
8961         ((rpc_in_flight++));
8962         nrpages=$((nrpages * rpc_in_flight))
8963
8964         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8965
8966         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8967
8968         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8969         local undirty=$((nrpages * PAGE_SIZE))
8970
8971         local max_extent_pages
8972         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8973         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8974         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8975         local grant_extent_tax
8976         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8977
8978         undirty=$((undirty + nrextents * grant_extent_tax))
8979
8980         echo $undirty
8981 }
8982
8983 # this is size of unit for grant allocation. It should be equal to
8984 # what tgt_grant.c:tgt_grant_chunk() calculates
8985 grant_chunk() {
8986         local tgt=$1
8987         local max_brw_size
8988         local grant_extent_tax
8989
8990         max_brw_size=$(import_param $tgt max_brw_size)
8991
8992         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8993
8994         echo $(((max_brw_size + grant_extent_tax) * 2))
8995 }
8996
8997 test_64d() {
8998         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8999                 skip "OST < 2.10.55 doesn't limit grants enough"
9000
9001         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9002
9003         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9004                 skip "no grant_param connect flag"
9005
9006         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9007
9008         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9009         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9010
9011
9012         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9013         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9014
9015         $LFS setstripe $DIR/$tfile -i 0 -c 1
9016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9017         ddpid=$!
9018
9019         while kill -0 $ddpid; do
9020                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9021
9022                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9023                         kill $ddpid
9024                         error "cur_grant $cur_grant > $max_cur_granted"
9025                 fi
9026
9027                 sleep 1
9028         done
9029 }
9030 run_test 64d "check grant limit exceed"
9031
9032 check_grants() {
9033         local tgt=$1
9034         local expected=$2
9035         local msg=$3
9036         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9037
9038         ((cur_grants == expected)) ||
9039                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9040 }
9041
9042 round_up_p2() {
9043         echo $((($1 + $2 - 1) & ~($2 - 1)))
9044 }
9045
9046 test_64e() {
9047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9048         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9049                 skip "Need OSS version at least 2.11.56"
9050
9051         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9052         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9053         $LCTL set_param debug=+cache
9054
9055         # Remount client to reset grant
9056         remount_client $MOUNT || error "failed to remount client"
9057         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9058
9059         local init_grants=$(import_param $osc_tgt initial_grant)
9060
9061         check_grants $osc_tgt $init_grants "init grants"
9062
9063         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9064         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9065         local gbs=$(import_param $osc_tgt grant_block_size)
9066
9067         # write random number of bytes from max_brw_size / 4 to max_brw_size
9068         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9069         # align for direct io
9070         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9071         # round to grant consumption unit
9072         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9073
9074         local grants=$((wb_round_up + extent_tax))
9075
9076         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9077
9078         # define OBD_FAIL_TGT_NO_GRANT 0x725
9079         # make the server not grant more back
9080         do_facet ost1 $LCTL set_param fail_loc=0x725
9081         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9082
9083         do_facet ost1 $LCTL set_param fail_loc=0
9084
9085         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9086
9087         rm -f $DIR/$tfile || error "rm failed"
9088
9089         # Remount client to reset grant
9090         remount_client $MOUNT || error "failed to remount client"
9091         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9092
9093         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9094
9095         # define OBD_FAIL_TGT_NO_GRANT 0x725
9096         # make the server not grant more back
9097         do_facet ost1 $LCTL set_param fail_loc=0x725
9098         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9099         do_facet ost1 $LCTL set_param fail_loc=0
9100
9101         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9102 }
9103 run_test 64e "check grant consumption (no grant allocation)"
9104
9105 test_64f() {
9106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9107
9108         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9109         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9110         $LCTL set_param debug=+cache
9111
9112         # Remount client to reset grant
9113         remount_client $MOUNT || error "failed to remount client"
9114         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9115
9116         local init_grants=$(import_param $osc_tgt initial_grant)
9117         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9118         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9119         local gbs=$(import_param $osc_tgt grant_block_size)
9120         local chunk=$(grant_chunk $osc_tgt)
9121
9122         # write random number of bytes from max_brw_size / 4 to max_brw_size
9123         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9124         # align for direct io
9125         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9126         # round to grant consumption unit
9127         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9128
9129         local grants=$((wb_round_up + extent_tax))
9130
9131         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9132         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9133                 error "error writing to $DIR/$tfile"
9134
9135         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9136                 "direct io with grant allocation"
9137
9138         rm -f $DIR/$tfile || error "rm failed"
9139
9140         # Remount client to reset grant
9141         remount_client $MOUNT || error "failed to remount client"
9142         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9143
9144         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9145
9146         local cmd="oO_WRONLY:w${write_bytes}_yc"
9147
9148         $MULTIOP $DIR/$tfile $cmd &
9149         MULTIPID=$!
9150         sleep 1
9151
9152         check_grants $osc_tgt $((init_grants - grants)) \
9153                 "buffered io, not write rpc"
9154
9155         kill -USR1 $MULTIPID
9156         wait
9157
9158         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9159                 "buffered io, one RPC"
9160 }
9161 run_test 64f "check grant consumption (with grant allocation)"
9162
9163 test_64g() {
9164         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9165                 skip "Need MDS version at least 2.14.56"
9166
9167         local mdts=$(comma_list $(mdts_nodes))
9168
9169         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9170                         tr '\n' ' ')
9171         stack_trap "$LCTL set_param $old"
9172
9173         # generate dirty pages and increase dirty granted on MDT
9174         stack_trap "rm -f $DIR/$tfile-*"
9175         for (( i = 0; i < 10; i++)); do
9176                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9177                         error "can't set stripe"
9178                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9179                         error "can't dd"
9180                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9181                         $LFS getstripe $DIR/$tfile-$i
9182                         error "not DoM file"
9183                 }
9184         done
9185
9186         # flush dirty pages
9187         sync
9188
9189         # wait until grant shrink reset grant dirty on MDTs
9190         for ((i = 0; i < 120; i++)); do
9191                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9192                         awk '{sum=sum+$1} END {print sum}')
9193                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9194                 echo "$grant_dirty grants, $vm_dirty pages"
9195                 (( grant_dirty + vm_dirty == 0 )) && break
9196                 (( i == 3 )) && sync &&
9197                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9198                 sleep 1
9199         done
9200
9201         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9202                 awk '{sum=sum+$1} END {print sum}')
9203         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9204 }
9205 run_test 64g "grant shrink on MDT"
9206
9207 test_64h() {
9208         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9209                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9210
9211         local instance=$($LFS getname -i $DIR)
9212         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9213         local num_exps=$(do_facet ost1 \
9214             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9215         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9216         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9217         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9218
9219         # 10MiB is for file to be written, max_brw_size * 16 *
9220         # num_exps is space reserve so that tgt_grant_shrink() decided
9221         # to not shrink
9222         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9223         (( avail * 1024 < expect )) &&
9224                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9225
9226         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9227         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9228         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9229         $LCTL set_param osc.*OST0000*.grant_shrink=1
9230         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9231
9232         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9233         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9234
9235         # drop cache so that coming read would do rpc
9236         cancel_lru_locks osc
9237
9238         # shrink interval is set to 10, pause for 7 seconds so that
9239         # grant thread did not wake up yet but coming read entered
9240         # shrink mode for rpc (osc_should_shrink_grant())
9241         sleep 7
9242
9243         declare -a cur_grant_bytes
9244         declare -a tot_granted
9245         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9246         tot_granted[0]=$(do_facet ost1 \
9247             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9248
9249         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9250
9251         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9252         tot_granted[1]=$(do_facet ost1 \
9253             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9254
9255         # grant change should be equal on both sides
9256         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9257                 tot_granted[0] - tot_granted[1])) ||
9258                 error "grant change mismatch, "                                \
9259                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9260                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9261 }
9262 run_test 64h "grant shrink on read"
9263
9264 test_64i() {
9265         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9266                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9267
9268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9269         remote_ost_nodsh && skip "remote OSTs with nodsh"
9270
9271         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9272
9273         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9274
9275         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9276         local instance=$($LFS getname -i $DIR)
9277
9278         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9279         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9280
9281         # shrink grants and simulate rpc loss
9282         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9283         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9284         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9285
9286         fail ost1
9287
9288         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9289
9290         local testid=$(echo $TESTNAME | tr '_' ' ')
9291
9292         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9293                 grep "GRANT, real grant" &&
9294                 error "client has more grants then it owns" || true
9295 }
9296 run_test 64i "shrink on reconnect"
9297
9298 # bug 1414 - set/get directories' stripe info
9299 test_65a() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301
9302         test_mkdir $DIR/$tdir
9303         touch $DIR/$tdir/f1
9304         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9305 }
9306 run_test 65a "directory with no stripe info"
9307
9308 test_65b() {
9309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9310
9311         test_mkdir $DIR/$tdir
9312         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9313
9314         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9315                                                 error "setstripe"
9316         touch $DIR/$tdir/f2
9317         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9318 }
9319 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9320
9321 test_65c() {
9322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9323         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9324
9325         test_mkdir $DIR/$tdir
9326         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9327
9328         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9329                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9330         touch $DIR/$tdir/f3
9331         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9332 }
9333 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9334
9335 test_65d() {
9336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9337
9338         test_mkdir $DIR/$tdir
9339         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9340         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9341
9342         if [[ $STRIPECOUNT -le 0 ]]; then
9343                 sc=1
9344         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9345                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9346                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9347         else
9348                 sc=$(($STRIPECOUNT - 1))
9349         fi
9350         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9351         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9352         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9353                 error "lverify failed"
9354 }
9355 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9356
9357 test_65e() {
9358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9359
9360         test_mkdir $DIR/$tdir
9361
9362         $LFS setstripe $DIR/$tdir || error "setstripe"
9363         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9364                                         error "no stripe info failed"
9365         touch $DIR/$tdir/f6
9366         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9367 }
9368 run_test 65e "directory setstripe defaults"
9369
9370 test_65f() {
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372
9373         test_mkdir $DIR/${tdir}f
9374         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9375                 error "setstripe succeeded" || true
9376 }
9377 run_test 65f "dir setstripe permission (should return error) ==="
9378
9379 test_65g() {
9380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9381
9382         test_mkdir $DIR/$tdir
9383         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9384
9385         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9386                 error "setstripe -S failed"
9387         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9388         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9389                 error "delete default stripe failed"
9390 }
9391 run_test 65g "directory setstripe -d"
9392
9393 test_65h() {
9394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9395
9396         test_mkdir $DIR/$tdir
9397         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9398
9399         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9400                 error "setstripe -S failed"
9401         test_mkdir $DIR/$tdir/dd1
9402         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9403                 error "stripe info inherit failed"
9404 }
9405 run_test 65h "directory stripe info inherit ===================="
9406
9407 test_65i() {
9408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9409
9410         save_layout_restore_at_exit $MOUNT
9411
9412         # bug6367: set non-default striping on root directory
9413         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9414
9415         # bug12836: getstripe on -1 default directory striping
9416         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9417
9418         # bug12836: getstripe -v on -1 default directory striping
9419         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9420
9421         # bug12836: new find on -1 default directory striping
9422         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9423 }
9424 run_test 65i "various tests to set root directory striping"
9425
9426 test_65j() { # bug6367
9427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9428
9429         sync; sleep 1
9430
9431         # if we aren't already remounting for each test, do so for this test
9432         if [ "$I_MOUNTED" = "yes" ]; then
9433                 cleanup || error "failed to unmount"
9434                 setup
9435         fi
9436
9437         save_layout_restore_at_exit $MOUNT
9438
9439         $LFS setstripe -d $MOUNT || error "setstripe failed"
9440 }
9441 run_test 65j "set default striping on root directory (bug 6367)="
9442
9443 cleanup_65k() {
9444         rm -rf $DIR/$tdir
9445         wait_delete_completed
9446         do_facet $SINGLEMDS "lctl set_param -n \
9447                 osp.$ost*MDT0000.max_create_count=$max_count"
9448         do_facet $SINGLEMDS "lctl set_param -n \
9449                 osp.$ost*MDT0000.create_count=$count"
9450         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9451         echo $INACTIVE_OSC "is Activate"
9452
9453         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9454 }
9455
9456 test_65k() { # bug11679
9457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9459         remote_mds_nodsh && skip "remote MDS with nodsh"
9460
9461         local disable_precreate=true
9462         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9463                 disable_precreate=false
9464
9465         echo "Check OST status: "
9466         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9467                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9468
9469         for OSC in $MDS_OSCS; do
9470                 echo $OSC "is active"
9471                 do_facet $SINGLEMDS lctl --device %$OSC activate
9472         done
9473
9474         for INACTIVE_OSC in $MDS_OSCS; do
9475                 local ost=$(osc_to_ost $INACTIVE_OSC)
9476                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9477                                lov.*md*.target_obd |
9478                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9479
9480                 mkdir -p $DIR/$tdir
9481                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9482                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9483
9484                 echo "Deactivate: " $INACTIVE_OSC
9485                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9486
9487                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9488                               osp.$ost*MDT0000.create_count")
9489                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9490                                   osp.$ost*MDT0000.max_create_count")
9491                 $disable_precreate &&
9492                         do_facet $SINGLEMDS "lctl set_param -n \
9493                                 osp.$ost*MDT0000.max_create_count=0"
9494
9495                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9496                         [ -f $DIR/$tdir/$idx ] && continue
9497                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9498                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9499                                 { cleanup_65k;
9500                                   error "setstripe $idx should succeed"; }
9501                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9502                 done
9503                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9504                 rmdir $DIR/$tdir
9505
9506                 do_facet $SINGLEMDS "lctl set_param -n \
9507                         osp.$ost*MDT0000.max_create_count=$max_count"
9508                 do_facet $SINGLEMDS "lctl set_param -n \
9509                         osp.$ost*MDT0000.create_count=$count"
9510                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9511                 echo $INACTIVE_OSC "is Activate"
9512
9513                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9514         done
9515 }
9516 run_test 65k "validate manual striping works properly with deactivated OSCs"
9517
9518 test_65l() { # bug 12836
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520
9521         test_mkdir -p $DIR/$tdir/test_dir
9522         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9523         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9524 }
9525 run_test 65l "lfs find on -1 stripe dir ========================"
9526
9527 test_65m() {
9528         local layout=$(save_layout $MOUNT)
9529         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9530                 restore_layout $MOUNT $layout
9531                 error "setstripe should fail by non-root users"
9532         }
9533         true
9534 }
9535 run_test 65m "normal user can't set filesystem default stripe"
9536
9537 test_65n() {
9538         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9539         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9540                 skip "Need MDS version at least 2.12.50"
9541         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9542
9543         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9544         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9545         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9546
9547         save_layout_restore_at_exit $MOUNT
9548
9549         # new subdirectory under root directory should not inherit
9550         # the default layout from root
9551         local dir1=$MOUNT/$tdir-1
9552         mkdir $dir1 || error "mkdir $dir1 failed"
9553         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9554                 error "$dir1 shouldn't have LOV EA"
9555
9556         # delete the default layout on root directory
9557         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9558
9559         local dir2=$MOUNT/$tdir-2
9560         mkdir $dir2 || error "mkdir $dir2 failed"
9561         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9562                 error "$dir2 shouldn't have LOV EA"
9563
9564         # set a new striping pattern on root directory
9565         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9566         local new_def_stripe_size=$((def_stripe_size * 2))
9567         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9568                 error "set stripe size on $MOUNT failed"
9569
9570         # new file created in $dir2 should inherit the new stripe size from
9571         # the filesystem default
9572         local file2=$dir2/$tfile-2
9573         touch $file2 || error "touch $file2 failed"
9574
9575         local file2_stripe_size=$($LFS getstripe -S $file2)
9576         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9577         {
9578                 echo "file2_stripe_size: '$file2_stripe_size'"
9579                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9580                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9581         }
9582
9583         local dir3=$MOUNT/$tdir-3
9584         mkdir $dir3 || error "mkdir $dir3 failed"
9585         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9586         # the root layout, which is the actual default layout that will be used
9587         # when new files are created in $dir3.
9588         local dir3_layout=$(get_layout_param $dir3)
9589         local root_dir_layout=$(get_layout_param $MOUNT)
9590         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9591         {
9592                 echo "dir3_layout: '$dir3_layout'"
9593                 echo "root_dir_layout: '$root_dir_layout'"
9594                 error "$dir3 should show the default layout from $MOUNT"
9595         }
9596
9597         # set OST pool on root directory
9598         local pool=$TESTNAME
9599         pool_add $pool || error "add $pool failed"
9600         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9601                 error "add targets to $pool failed"
9602
9603         $LFS setstripe -p $pool $MOUNT ||
9604                 error "set OST pool on $MOUNT failed"
9605
9606         # new file created in $dir3 should inherit the pool from
9607         # the filesystem default
9608         local file3=$dir3/$tfile-3
9609         touch $file3 || error "touch $file3 failed"
9610
9611         local file3_pool=$($LFS getstripe -p $file3)
9612         [[ "$file3_pool" = "$pool" ]] ||
9613                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9614
9615         local dir4=$MOUNT/$tdir-4
9616         mkdir $dir4 || error "mkdir $dir4 failed"
9617         local dir4_layout=$(get_layout_param $dir4)
9618         root_dir_layout=$(get_layout_param $MOUNT)
9619         echo "$LFS getstripe -d $dir4"
9620         $LFS getstripe -d $dir4
9621         echo "$LFS getstripe -d $MOUNT"
9622         $LFS getstripe -d $MOUNT
9623         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9624         {
9625                 echo "dir4_layout: '$dir4_layout'"
9626                 echo "root_dir_layout: '$root_dir_layout'"
9627                 error "$dir4 should show the default layout from $MOUNT"
9628         }
9629
9630         # new file created in $dir4 should inherit the pool from
9631         # the filesystem default
9632         local file4=$dir4/$tfile-4
9633         touch $file4 || error "touch $file4 failed"
9634
9635         local file4_pool=$($LFS getstripe -p $file4)
9636         [[ "$file4_pool" = "$pool" ]] ||
9637                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9638
9639         # new subdirectory under non-root directory should inherit
9640         # the default layout from its parent directory
9641         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9642                 error "set directory layout on $dir4 failed"
9643
9644         local dir5=$dir4/$tdir-5
9645         mkdir $dir5 || error "mkdir $dir5 failed"
9646
9647         dir4_layout=$(get_layout_param $dir4)
9648         local dir5_layout=$(get_layout_param $dir5)
9649         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9650         {
9651                 echo "dir4_layout: '$dir4_layout'"
9652                 echo "dir5_layout: '$dir5_layout'"
9653                 error "$dir5 should inherit the default layout from $dir4"
9654         }
9655
9656         # though subdir under ROOT doesn't inherit default layout, but
9657         # its sub dir/file should be created with default layout.
9658         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9659         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9660                 skip "Need MDS version at least 2.12.59"
9661
9662         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9663         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9664         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9665
9666         if [ $default_lmv_hash == "none" ]; then
9667                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9668         else
9669                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9670                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9671         fi
9672
9673         $LFS setdirstripe -D -c 2 $MOUNT ||
9674                 error "setdirstripe -D -c 2 failed"
9675         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9676         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9677         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9678
9679         # $dir4 layout includes pool
9680         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9681         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9682                 error "pool lost on setstripe"
9683         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9684         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9685                 error "pool lost on compound layout setstripe"
9686 }
9687 run_test 65n "don't inherit default layout from root for new subdirectories"
9688
9689 test_65o() {
9690         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9691                 skip "need MDS version at least 2.14.57"
9692
9693         # set OST pool on root directory
9694         local pool=$TESTNAME
9695
9696         pool_add $pool || error "add $pool failed"
9697         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9698                 error "add targets to $pool failed"
9699
9700         local dir1=$MOUNT/$tdir
9701
9702         mkdir $dir1 || error "mkdir $dir1 failed"
9703
9704         # set a new striping pattern on root directory
9705         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9706
9707         $LFS setstripe -p $pool $dir1 ||
9708                 error "set directory layout on $dir1 failed"
9709
9710         # $dir1 layout includes pool
9711         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9712         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9713                 error "pool lost on setstripe"
9714         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9715         $LFS getstripe $dir1
9716         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9717                 error "pool lost on compound layout setstripe"
9718
9719         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9720                 error "setdirstripe failed on sub-dir with inherited pool"
9721         $LFS getstripe $dir1/dir2
9722         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9723                 error "pool lost on compound layout setdirstripe"
9724
9725         $LFS setstripe -E -1 -c 1 $dir1
9726         $LFS getstripe -d $dir1
9727         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9728                 error "pool lost on setstripe"
9729 }
9730 run_test 65o "pool inheritance for mdt component"
9731
9732 test_65p () { # LU-16152
9733         local src_dir=$DIR/$tdir/src_dir
9734         local dst_dir=$DIR/$tdir/dst_dir
9735         local yaml_file=$DIR/$tdir/layout.yaml
9736         local border
9737
9738         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9739                 skip "Need at least version 2.15.51"
9740
9741         test_mkdir -p $src_dir
9742         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9743                 error "failed to setstripe"
9744         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9745                 error "failed to getstripe"
9746
9747         test_mkdir -p $dst_dir
9748         $LFS setstripe --yaml $yaml_file $dst_dir ||
9749                 error "failed to setstripe with yaml file"
9750         border=$($LFS getstripe -d $dst_dir |
9751                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9752                 error "failed to getstripe"
9753
9754         # 2048M is 0x80000000, or 2147483648
9755         (( $border == 2147483648 )) ||
9756                 error "failed to handle huge number in yaml layout"
9757 }
9758 run_test 65p "setstripe with yaml file and huge number"
9759
9760 # bug 2543 - update blocks count on client
9761 test_66() {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         local COUNT=${COUNT:-8}
9765         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9766         sync; sync_all_data; sync; sync_all_data
9767         cancel_lru_locks osc
9768         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9769         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9770 }
9771 run_test 66 "update inode blocks count on client ==============="
9772
9773 meminfo() {
9774         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9775 }
9776
9777 swap_used() {
9778         swapon -s | awk '($1 == "'$1'") { print $4 }'
9779 }
9780
9781 # bug5265, obdfilter oa2dentry return -ENOENT
9782 # #define OBD_FAIL_SRV_ENOENT 0x217
9783 test_69() {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         remote_ost_nodsh && skip "remote OST with nodsh"
9786
9787         f="$DIR/$tfile"
9788         $LFS setstripe -c 1 -i 0 $f
9789
9790         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9791
9792         do_facet ost1 lctl set_param fail_loc=0x217
9793         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9794         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9795
9796         do_facet ost1 lctl set_param fail_loc=0
9797         $DIRECTIO write $f 0 2 || error "write error"
9798
9799         cancel_lru_locks osc
9800         $DIRECTIO read $f 0 1 || error "read error"
9801
9802         do_facet ost1 lctl set_param fail_loc=0x217
9803         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9804
9805         do_facet ost1 lctl set_param fail_loc=0
9806         rm -f $f
9807 }
9808 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9809
9810 test_71() {
9811         test_mkdir $DIR/$tdir
9812         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9813         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9814 }
9815 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9816
9817 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9819         [ "$RUNAS_ID" = "$UID" ] &&
9820                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9821         # Check that testing environment is properly set up. Skip if not
9822         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9823                 skip_env "User $RUNAS_ID does not exist - skipping"
9824
9825         touch $DIR/$tfile
9826         chmod 777 $DIR/$tfile
9827         chmod ug+s $DIR/$tfile
9828         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9829                 error "$RUNAS dd $DIR/$tfile failed"
9830         # See if we are still setuid/sgid
9831         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9832                 error "S/gid is not dropped on write"
9833         # Now test that MDS is updated too
9834         cancel_lru_locks mdc
9835         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9836                 error "S/gid is not dropped on MDS"
9837         rm -f $DIR/$tfile
9838 }
9839 run_test 72a "Test that remove suid works properly (bug5695) ===="
9840
9841 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9842         local perm
9843
9844         [ "$RUNAS_ID" = "$UID" ] &&
9845                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9846         [ "$RUNAS_ID" -eq 0 ] &&
9847                 skip_env "RUNAS_ID = 0 -- skipping"
9848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9849         # Check that testing environment is properly set up. Skip if not
9850         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9851                 skip_env "User $RUNAS_ID does not exist - skipping"
9852
9853         touch $DIR/${tfile}-f{g,u}
9854         test_mkdir $DIR/${tfile}-dg
9855         test_mkdir $DIR/${tfile}-du
9856         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9857         chmod g+s $DIR/${tfile}-{f,d}g
9858         chmod u+s $DIR/${tfile}-{f,d}u
9859         for perm in 777 2777 4777; do
9860                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9861                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9862                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9863                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9864         done
9865         true
9866 }
9867 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9868
9869 # bug 3462 - multiple simultaneous MDC requests
9870 test_73() {
9871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9872
9873         test_mkdir $DIR/d73-1
9874         test_mkdir $DIR/d73-2
9875         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9876         pid1=$!
9877
9878         lctl set_param fail_loc=0x80000129
9879         $MULTIOP $DIR/d73-1/f73-2 Oc &
9880         sleep 1
9881         lctl set_param fail_loc=0
9882
9883         $MULTIOP $DIR/d73-2/f73-3 Oc &
9884         pid3=$!
9885
9886         kill -USR1 $pid1
9887         wait $pid1 || return 1
9888
9889         sleep 25
9890
9891         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9892         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9893         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9894
9895         rm -rf $DIR/d73-*
9896 }
9897 run_test 73 "multiple MDC requests (should not deadlock)"
9898
9899 test_74a() { # bug 6149, 6184
9900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9901
9902         touch $DIR/f74a
9903         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9904         #
9905         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9906         # will spin in a tight reconnection loop
9907         $LCTL set_param fail_loc=0x8000030e
9908         # get any lock that won't be difficult - lookup works.
9909         ls $DIR/f74a
9910         $LCTL set_param fail_loc=0
9911         rm -f $DIR/f74a
9912         true
9913 }
9914 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9915
9916 test_74b() { # bug 13310
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918
9919         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9920         #
9921         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9922         # will spin in a tight reconnection loop
9923         $LCTL set_param fail_loc=0x8000030e
9924         # get a "difficult" lock
9925         touch $DIR/f74b
9926         $LCTL set_param fail_loc=0
9927         rm -f $DIR/f74b
9928         true
9929 }
9930 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9931
9932 test_74c() {
9933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9934
9935         #define OBD_FAIL_LDLM_NEW_LOCK
9936         $LCTL set_param fail_loc=0x319
9937         touch $DIR/$tfile && error "touch successful"
9938         $LCTL set_param fail_loc=0
9939         true
9940 }
9941 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9942
9943 slab_lic=/sys/kernel/slab/lustre_inode_cache
9944 num_objects() {
9945         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9946         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9947                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9948 }
9949
9950 test_76a() { # Now for b=20433, added originally in b=1443
9951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9952
9953         cancel_lru_locks osc
9954         # there may be some slab objects cached per core
9955         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9956         local before=$(num_objects)
9957         local count=$((512 * cpus))
9958         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9959         local margin=$((count / 10))
9960         if [[ -f $slab_lic/aliases ]]; then
9961                 local aliases=$(cat $slab_lic/aliases)
9962                 (( aliases > 0 )) && margin=$((margin * aliases))
9963         fi
9964
9965         echo "before slab objects: $before"
9966         for i in $(seq $count); do
9967                 touch $DIR/$tfile
9968                 rm -f $DIR/$tfile
9969         done
9970         cancel_lru_locks osc
9971         local after=$(num_objects)
9972         echo "created: $count, after slab objects: $after"
9973         # shared slab counts are not very accurate, allow significant margin
9974         # the main goal is that the cache growth is not permanently > $count
9975         while (( after > before + margin )); do
9976                 sleep 1
9977                 after=$(num_objects)
9978                 wait=$((wait + 1))
9979                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9980                 if (( wait > 60 )); then
9981                         error "inode slab grew from $before+$margin to $after"
9982                 fi
9983         done
9984 }
9985 run_test 76a "confirm clients recycle inodes properly ===="
9986
9987 test_76b() {
9988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9989         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9990
9991         local count=512
9992         local before=$(num_objects)
9993
9994         for i in $(seq $count); do
9995                 mkdir $DIR/$tdir
9996                 rmdir $DIR/$tdir
9997         done
9998
9999         local after=$(num_objects)
10000         local wait=0
10001
10002         while (( after > before )); do
10003                 sleep 1
10004                 after=$(num_objects)
10005                 wait=$((wait + 1))
10006                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10007                 if (( wait > 60 )); then
10008                         error "inode slab grew from $before to $after"
10009                 fi
10010         done
10011
10012         echo "slab objects before: $before, after: $after"
10013 }
10014 run_test 76b "confirm clients recycle directory inodes properly ===="
10015
10016 export ORIG_CSUM=""
10017 set_checksums()
10018 {
10019         # Note: in sptlrpc modes which enable its own bulk checksum, the
10020         # original crc32_le bulk checksum will be automatically disabled,
10021         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10022         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10023         # In this case set_checksums() will not be no-op, because sptlrpc
10024         # bulk checksum will be enabled all through the test.
10025
10026         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10027         lctl set_param -n osc.*.checksums $1
10028         return 0
10029 }
10030
10031 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10032                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10033 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10034                              tr -d [] | head -n1)}
10035 set_checksum_type()
10036 {
10037         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10038         rc=$?
10039         log "set checksum type to $1, rc = $rc"
10040         return $rc
10041 }
10042
10043 get_osc_checksum_type()
10044 {
10045         # arugment 1: OST name, like OST0000
10046         ost=$1
10047         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10048                         sed 's/.*\[\(.*\)\].*/\1/g')
10049         rc=$?
10050         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10051         echo $checksum_type
10052 }
10053
10054 F77_TMP=$TMP/f77-temp
10055 F77SZ=8
10056 setup_f77() {
10057         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10058                 error "error writing to $F77_TMP"
10059 }
10060
10061 test_77a() { # bug 10889
10062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10063         $GSS && skip_env "could not run with gss"
10064
10065         [ ! -f $F77_TMP ] && setup_f77
10066         set_checksums 1
10067         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10068         set_checksums 0
10069         rm -f $DIR/$tfile
10070 }
10071 run_test 77a "normal checksum read/write operation"
10072
10073 test_77b() { # bug 10889
10074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10075         $GSS && skip_env "could not run with gss"
10076
10077         [ ! -f $F77_TMP ] && setup_f77
10078         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10079         $LCTL set_param fail_loc=0x80000409
10080         set_checksums 1
10081
10082         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10083                 error "dd error: $?"
10084         $LCTL set_param fail_loc=0
10085
10086         for algo in $CKSUM_TYPES; do
10087                 cancel_lru_locks osc
10088                 set_checksum_type $algo
10089                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10090                 $LCTL set_param fail_loc=0x80000408
10091                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10092                 $LCTL set_param fail_loc=0
10093         done
10094         set_checksums 0
10095         set_checksum_type $ORIG_CSUM_TYPE
10096         rm -f $DIR/$tfile
10097 }
10098 run_test 77b "checksum error on client write, read"
10099
10100 cleanup_77c() {
10101         trap 0
10102         set_checksums 0
10103         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10104         $check_ost &&
10105                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10106         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10107         $check_ost && [ -n "$ost_file_prefix" ] &&
10108                 do_facet ost1 rm -f ${ost_file_prefix}\*
10109 }
10110
10111 test_77c() {
10112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10113         $GSS && skip_env "could not run with gss"
10114         remote_ost_nodsh && skip "remote OST with nodsh"
10115
10116         local bad1
10117         local osc_file_prefix
10118         local osc_file
10119         local check_ost=false
10120         local ost_file_prefix
10121         local ost_file
10122         local orig_cksum
10123         local dump_cksum
10124         local fid
10125
10126         # ensure corruption will occur on first OSS/OST
10127         $LFS setstripe -i 0 $DIR/$tfile
10128
10129         [ ! -f $F77_TMP ] && setup_f77
10130         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10131                 error "dd write error: $?"
10132         fid=$($LFS path2fid $DIR/$tfile)
10133
10134         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10135         then
10136                 check_ost=true
10137                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10138                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10139         else
10140                 echo "OSS do not support bulk pages dump upon error"
10141         fi
10142
10143         osc_file_prefix=$($LCTL get_param -n debug_path)
10144         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10145
10146         trap cleanup_77c EXIT
10147
10148         set_checksums 1
10149         # enable bulk pages dump upon error on Client
10150         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10151         # enable bulk pages dump upon error on OSS
10152         $check_ost &&
10153                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10154
10155         # flush Client cache to allow next read to reach OSS
10156         cancel_lru_locks osc
10157
10158         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10159         $LCTL set_param fail_loc=0x80000408
10160         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10161         $LCTL set_param fail_loc=0
10162
10163         rm -f $DIR/$tfile
10164
10165         # check cksum dump on Client
10166         osc_file=$(ls ${osc_file_prefix}*)
10167         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10168         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10169         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10170         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10171         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10172                      cksum)
10173         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10174         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10175                 error "dump content does not match on Client"
10176
10177         $check_ost || skip "No need to check cksum dump on OSS"
10178
10179         # check cksum dump on OSS
10180         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10181         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10182         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10183         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10184         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10185                 error "dump content does not match on OSS"
10186
10187         cleanup_77c
10188 }
10189 run_test 77c "checksum error on client read with debug"
10190
10191 test_77d() { # bug 10889
10192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10193         $GSS && skip_env "could not run with gss"
10194
10195         stack_trap "rm -f $DIR/$tfile"
10196         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10197         $LCTL set_param fail_loc=0x80000409
10198         set_checksums 1
10199         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10200                 error "direct write: rc=$?"
10201         $LCTL set_param fail_loc=0
10202         set_checksums 0
10203
10204         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10205         $LCTL set_param fail_loc=0x80000408
10206         set_checksums 1
10207         cancel_lru_locks osc
10208         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10209                 error "direct read: rc=$?"
10210         $LCTL set_param fail_loc=0
10211         set_checksums 0
10212 }
10213 run_test 77d "checksum error on OST direct write, read"
10214
10215 test_77f() { # bug 10889
10216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10217         $GSS && skip_env "could not run with gss"
10218
10219         set_checksums 1
10220         stack_trap "rm -f $DIR/$tfile"
10221         for algo in $CKSUM_TYPES; do
10222                 cancel_lru_locks osc
10223                 set_checksum_type $algo
10224                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10225                 $LCTL set_param fail_loc=0x409
10226                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10227                         error "direct write succeeded"
10228                 $LCTL set_param fail_loc=0
10229         done
10230         set_checksum_type $ORIG_CSUM_TYPE
10231         set_checksums 0
10232 }
10233 run_test 77f "repeat checksum error on write (expect error)"
10234
10235 test_77g() { # bug 10889
10236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10237         $GSS && skip_env "could not run with gss"
10238         remote_ost_nodsh && skip "remote OST with nodsh"
10239
10240         [ ! -f $F77_TMP ] && setup_f77
10241
10242         local file=$DIR/$tfile
10243         stack_trap "rm -f $file" EXIT
10244
10245         $LFS setstripe -c 1 -i 0 $file
10246         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10247         do_facet ost1 lctl set_param fail_loc=0x8000021a
10248         set_checksums 1
10249         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10250                 error "write error: rc=$?"
10251         do_facet ost1 lctl set_param fail_loc=0
10252         set_checksums 0
10253
10254         cancel_lru_locks osc
10255         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10256         do_facet ost1 lctl set_param fail_loc=0x8000021b
10257         set_checksums 1
10258         cmp $F77_TMP $file || error "file compare failed"
10259         do_facet ost1 lctl set_param fail_loc=0
10260         set_checksums 0
10261 }
10262 run_test 77g "checksum error on OST write, read"
10263
10264 test_77k() { # LU-10906
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266         $GSS && skip_env "could not run with gss"
10267
10268         local cksum_param="osc.$FSNAME*.checksums"
10269         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10270         local checksum
10271         local i
10272
10273         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10274         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10275         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10276
10277         for i in 0 1; do
10278                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10279                         error "failed to set checksum=$i on MGS"
10280                 wait_update $HOSTNAME "$get_checksum" $i
10281                 #remount
10282                 echo "remount client, checksum should be $i"
10283                 remount_client $MOUNT || error "failed to remount client"
10284                 checksum=$(eval $get_checksum)
10285                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10286         done
10287         # remove persistent param to avoid races with checksum mountopt below
10288         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10289                 error "failed to delete checksum on MGS"
10290
10291         for opt in "checksum" "nochecksum"; do
10292                 #remount with mount option
10293                 echo "remount client with option $opt, checksum should be $i"
10294                 umount_client $MOUNT || error "failed to umount client"
10295                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10296                         error "failed to mount client with option '$opt'"
10297                 checksum=$(eval $get_checksum)
10298                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10299                 i=$((i - 1))
10300         done
10301
10302         remount_client $MOUNT || error "failed to remount client"
10303 }
10304 run_test 77k "enable/disable checksum correctly"
10305
10306 test_77l() {
10307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10308         $GSS && skip_env "could not run with gss"
10309
10310         set_checksums 1
10311         stack_trap "set_checksums $ORIG_CSUM" EXIT
10312         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10313
10314         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10315
10316         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10317         for algo in $CKSUM_TYPES; do
10318                 set_checksum_type $algo || error "fail to set checksum type $algo"
10319                 osc_algo=$(get_osc_checksum_type OST0000)
10320                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10321
10322                 # no locks, no reqs to let the connection idle
10323                 cancel_lru_locks osc
10324                 lru_resize_disable osc
10325                 wait_osc_import_state client ost1 IDLE
10326
10327                 # ensure ost1 is connected
10328                 stat $DIR/$tfile >/dev/null || error "can't stat"
10329                 wait_osc_import_state client ost1 FULL
10330
10331                 osc_algo=$(get_osc_checksum_type OST0000)
10332                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10333         done
10334         return 0
10335 }
10336 run_test 77l "preferred checksum type is remembered after reconnected"
10337
10338 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10339 rm -f $F77_TMP
10340 unset F77_TMP
10341
10342 test_77m() {
10343         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10344                 skip "Need at least version 2.14.52"
10345         local param=checksum_speed
10346
10347         $LCTL get_param $param || error "reading $param failed"
10348
10349         csum_speeds=$($LCTL get_param -n $param)
10350
10351         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10352                 error "known checksum types are missing"
10353 }
10354 run_test 77m "Verify checksum_speed is correctly read"
10355
10356 check_filefrag_77n() {
10357         local nr_ext=0
10358         local starts=()
10359         local ends=()
10360
10361         while read extidx a b start end rest; do
10362                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10363                         nr_ext=$(( $nr_ext + 1 ))
10364                         starts+=( ${start%..} )
10365                         ends+=( ${end%:} )
10366                 fi
10367         done < <( filefrag -sv $1 )
10368
10369         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10370         return 1
10371 }
10372
10373 test_77n() {
10374         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10375
10376         touch $DIR/$tfile
10377         $TRUNCATE $DIR/$tfile 0
10378         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10379         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10380         check_filefrag_77n $DIR/$tfile ||
10381                 skip "$tfile blocks not contiguous around hole"
10382
10383         set_checksums 1
10384         stack_trap "set_checksums $ORIG_CSUM" EXIT
10385         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10386         stack_trap "rm -f $DIR/$tfile"
10387
10388         for algo in $CKSUM_TYPES; do
10389                 if [[ "$algo" =~ ^t10 ]]; then
10390                         set_checksum_type $algo ||
10391                                 error "fail to set checksum type $algo"
10392                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10393                                 error "fail to read $tfile with $algo"
10394                 fi
10395         done
10396         rm -f $DIR/$tfile
10397         return 0
10398 }
10399 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10400
10401 test_77o() {
10402         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10403                 skip "Need MDS version at least 2.14.55"
10404         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10405                 skip "Need OST version at least 2.14.55"
10406         local ofd=obdfilter
10407         local mdt=mdt
10408
10409         # print OST checksum_type
10410         echo "$ofd.$FSNAME-*.checksum_type:"
10411         do_nodes $(comma_list $(osts_nodes)) \
10412                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10413
10414         # print MDT checksum_type
10415         echo "$mdt.$FSNAME-*.checksum_type:"
10416         do_nodes $(comma_list $(mdts_nodes)) \
10417                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10418
10419         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10420                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10421
10422         (( $o_count == $OSTCOUNT )) ||
10423                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10424
10425         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10426                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10427
10428         (( $m_count == $MDSCOUNT )) ||
10429                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10430 }
10431 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10432
10433 cleanup_test_78() {
10434         trap 0
10435         rm -f $DIR/$tfile
10436 }
10437
10438 test_78() { # bug 10901
10439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10440         remote_ost || skip_env "local OST"
10441
10442         NSEQ=5
10443         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10444         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10445         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10446         echo "MemTotal: $MEMTOTAL"
10447
10448         # reserve 256MB of memory for the kernel and other running processes,
10449         # and then take 1/2 of the remaining memory for the read/write buffers.
10450         if [ $MEMTOTAL -gt 512 ] ;then
10451                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10452         else
10453                 # for those poor memory-starved high-end clusters...
10454                 MEMTOTAL=$((MEMTOTAL / 2))
10455         fi
10456         echo "Mem to use for directio: $MEMTOTAL"
10457
10458         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10459         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10460         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10461         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10462                 head -n1)
10463         echo "Smallest OST: $SMALLESTOST"
10464         [[ $SMALLESTOST -lt 10240 ]] &&
10465                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10466
10467         trap cleanup_test_78 EXIT
10468
10469         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10470                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10471
10472         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10473         echo "File size: $F78SIZE"
10474         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10475         for i in $(seq 1 $NSEQ); do
10476                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10477                 echo directIO rdwr round $i of $NSEQ
10478                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10479         done
10480
10481         cleanup_test_78
10482 }
10483 run_test 78 "handle large O_DIRECT writes correctly ============"
10484
10485 test_79() { # bug 12743
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487
10488         wait_delete_completed
10489
10490         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10491         BKFREE=$(calc_osc_kbytes kbytesfree)
10492         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10493
10494         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10495         DFTOTAL=`echo $STRING | cut -d, -f1`
10496         DFUSED=`echo $STRING  | cut -d, -f2`
10497         DFAVAIL=`echo $STRING | cut -d, -f3`
10498         DFFREE=$(($DFTOTAL - $DFUSED))
10499
10500         ALLOWANCE=$((64 * $OSTCOUNT))
10501
10502         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10503            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10504                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10505         fi
10506         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10507            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10508                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10509         fi
10510         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10511            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10512                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10513         fi
10514 }
10515 run_test 79 "df report consistency check ======================="
10516
10517 test_80() { # bug 10718
10518         remote_ost_nodsh && skip "remote OST with nodsh"
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520
10521         # relax strong synchronous semantics for slow backends like ZFS
10522         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10523                 local soc="obdfilter.*.sync_lock_cancel"
10524                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10525
10526                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10527                 if [ -z "$save" ]; then
10528                         soc="obdfilter.*.sync_on_lock_cancel"
10529                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10530                 fi
10531
10532                 if [ "$save" != "never" ]; then
10533                         local hosts=$(comma_list $(osts_nodes))
10534
10535                         do_nodes $hosts $LCTL set_param $soc=never
10536                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10537                 fi
10538         fi
10539
10540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10541         sync; sleep 1; sync
10542         local before=$(date +%s)
10543         cancel_lru_locks osc
10544         local after=$(date +%s)
10545         local diff=$((after - before))
10546         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10547
10548         rm -f $DIR/$tfile
10549 }
10550 run_test 80 "Page eviction is equally fast at high offsets too"
10551
10552 test_81a() { # LU-456
10553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10557         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10558         do_facet ost1 lctl set_param fail_loc=0x80000228
10559
10560         # write should trigger a retry and success
10561         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10562         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10563         RC=$?
10564         if [ $RC -ne 0 ] ; then
10565                 error "write should success, but failed for $RC"
10566         fi
10567 }
10568 run_test 81a "OST should retry write when get -ENOSPC ==============="
10569
10570 test_81b() { # LU-456
10571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10572         remote_ost_nodsh && skip "remote OST with nodsh"
10573
10574         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10575         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10576         do_facet ost1 lctl set_param fail_loc=0x228
10577
10578         # write should retry several times and return -ENOSPC finally
10579         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10580         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10581         RC=$?
10582         ENOSPC=28
10583         if [ $RC -ne $ENOSPC ] ; then
10584                 error "dd should fail for -ENOSPC, but succeed."
10585         fi
10586 }
10587 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10588
10589 test_99() {
10590         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10591
10592         test_mkdir $DIR/$tdir.cvsroot
10593         chown $RUNAS_ID $DIR/$tdir.cvsroot
10594
10595         cd $TMP
10596         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10597
10598         cd /etc/init.d
10599         # some versions of cvs import exit(1) when asked to import links or
10600         # files they can't read.  ignore those files.
10601         local toignore=$(find . -type l -printf '-I %f\n' -o \
10602                          ! -perm /4 -printf '-I %f\n')
10603         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10604                 $tdir.reposname vtag rtag
10605
10606         cd $DIR
10607         test_mkdir $DIR/$tdir.reposname
10608         chown $RUNAS_ID $DIR/$tdir.reposname
10609         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10610
10611         cd $DIR/$tdir.reposname
10612         $RUNAS touch foo99
10613         $RUNAS cvs add -m 'addmsg' foo99
10614         $RUNAS cvs update
10615         $RUNAS cvs commit -m 'nomsg' foo99
10616         rm -fr $DIR/$tdir.cvsroot
10617 }
10618 run_test 99 "cvs strange file/directory operations"
10619
10620 test_100() {
10621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10622         [[ "$NETTYPE" =~ tcp ]] ||
10623                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10624         remote_ost_nodsh && skip "remote OST with nodsh"
10625         remote_mds_nodsh && skip "remote MDS with nodsh"
10626         remote_servers ||
10627                 skip "useless for local single node setup"
10628
10629         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10630                 [ "$PROT" != "tcp" ] && continue
10631                 RPORT=$(echo $REMOTE | cut -d: -f2)
10632                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10633
10634                 rc=0
10635                 LPORT=`echo $LOCAL | cut -d: -f2`
10636                 if [ $LPORT -ge 1024 ]; then
10637                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10638                         netstat -tna
10639                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10640                 fi
10641         done
10642         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10643 }
10644 run_test 100 "check local port using privileged port ==========="
10645
10646 function get_named_value()
10647 {
10648     local tag=$1
10649
10650     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10651 }
10652
10653 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10654                    awk '/^max_cached_mb/ { print $2 }')
10655
10656 cleanup_101a() {
10657         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10658         trap 0
10659 }
10660
10661 test_101a() {
10662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10663
10664         local s
10665         local discard
10666         local nreads=10000
10667         local cache_limit=32
10668
10669         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10670         trap cleanup_101a EXIT
10671         $LCTL set_param -n llite.*.read_ahead_stats=0
10672         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10673
10674         #
10675         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10676         #
10677         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10678         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10679
10680         discard=0
10681         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10682                    get_named_value 'read.but.discarded'); do
10683                         discard=$(($discard + $s))
10684         done
10685         cleanup_101a
10686
10687         $LCTL get_param osc.*-osc*.rpc_stats
10688         $LCTL get_param llite.*.read_ahead_stats
10689
10690         # Discard is generally zero, but sometimes a few random reads line up
10691         # and trigger larger readahead, which is wasted & leads to discards.
10692         if [[ $(($discard)) -gt $nreads ]]; then
10693                 error "too many ($discard) discarded pages"
10694         fi
10695         rm -f $DIR/$tfile || true
10696 }
10697 run_test 101a "check read-ahead for random reads"
10698
10699 setup_test101bc() {
10700         test_mkdir $DIR/$tdir
10701         local ssize=$1
10702         local FILE_LENGTH=$2
10703         STRIPE_OFFSET=0
10704
10705         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10706
10707         local list=$(comma_list $(osts_nodes))
10708         set_osd_param $list '' read_cache_enable 0
10709         set_osd_param $list '' writethrough_cache_enable 0
10710
10711         trap cleanup_test101bc EXIT
10712         # prepare the read-ahead file
10713         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10714
10715         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10716                                 count=$FILE_SIZE_MB 2> /dev/null
10717
10718 }
10719
10720 cleanup_test101bc() {
10721         trap 0
10722         rm -rf $DIR/$tdir
10723         rm -f $DIR/$tfile
10724
10725         local list=$(comma_list $(osts_nodes))
10726         set_osd_param $list '' read_cache_enable 1
10727         set_osd_param $list '' writethrough_cache_enable 1
10728 }
10729
10730 calc_total() {
10731         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10732 }
10733
10734 ra_check_101() {
10735         local read_size=$1
10736         local stripe_size=$2
10737         local stride_length=$((stripe_size / read_size))
10738         local stride_width=$((stride_length * OSTCOUNT))
10739         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10740                                 (stride_width - stride_length) ))
10741         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10742                   get_named_value 'read.but.discarded' | calc_total)
10743
10744         if [[ $discard -gt $discard_limit ]]; then
10745                 $LCTL get_param llite.*.read_ahead_stats
10746                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10747         else
10748                 echo "Read-ahead success for size ${read_size}"
10749         fi
10750 }
10751
10752 test_101b() {
10753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10754         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10755
10756         local STRIPE_SIZE=1048576
10757         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10758
10759         if [ $SLOW == "yes" ]; then
10760                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10761         else
10762                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10763         fi
10764
10765         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10766
10767         # prepare the read-ahead file
10768         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10769         cancel_lru_locks osc
10770         for BIDX in 2 4 8 16 32 64 128 256
10771         do
10772                 local BSIZE=$((BIDX*4096))
10773                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10774                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10775                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10776                 $LCTL set_param -n llite.*.read_ahead_stats=0
10777                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10778                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10779                 cancel_lru_locks osc
10780                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10781         done
10782         cleanup_test101bc
10783         true
10784 }
10785 run_test 101b "check stride-io mode read-ahead ================="
10786
10787 test_101c() {
10788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10789
10790         local STRIPE_SIZE=1048576
10791         local FILE_LENGTH=$((STRIPE_SIZE*100))
10792         local nreads=10000
10793         local rsize=65536
10794         local osc_rpc_stats
10795
10796         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10797
10798         cancel_lru_locks osc
10799         $LCTL set_param osc.*.rpc_stats=0
10800         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10801         $LCTL get_param osc.*.rpc_stats
10802         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10803                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10804                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10805                 local size
10806
10807                 if [ $lines -le 20 ]; then
10808                         echo "continue debug"
10809                         continue
10810                 fi
10811                 for size in 1 2 4 8; do
10812                         local rpc=$(echo "$stats" |
10813                                     awk '($1 == "'$size':") {print $2; exit; }')
10814                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10815                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10816                 done
10817                 echo "$osc_rpc_stats check passed!"
10818         done
10819         cleanup_test101bc
10820         true
10821 }
10822 run_test 101c "check stripe_size aligned read-ahead"
10823
10824 test_101d() {
10825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10826
10827         local file=$DIR/$tfile
10828         local sz_MB=${FILESIZE_101d:-80}
10829         local ra_MB=${READAHEAD_MB:-40}
10830
10831         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10832         [ $free_MB -lt $sz_MB ] &&
10833                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10834
10835         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10836         $LFS setstripe -c -1 $file || error "setstripe failed"
10837
10838         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10839         echo Cancel LRU locks on lustre client to flush the client cache
10840         cancel_lru_locks osc
10841
10842         echo Disable read-ahead
10843         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10844         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10845         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10846         $LCTL get_param -n llite.*.max_read_ahead_mb
10847
10848         echo "Reading the test file $file with read-ahead disabled"
10849         local sz_KB=$((sz_MB * 1024 / 4))
10850         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10851         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10852         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10853                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10854
10855         echo "Cancel LRU locks on lustre client to flush the client cache"
10856         cancel_lru_locks osc
10857         echo Enable read-ahead with ${ra_MB}MB
10858         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10859
10860         echo "Reading the test file $file with read-ahead enabled"
10861         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10862                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10863
10864         echo "read-ahead disabled time read $raOFF"
10865         echo "read-ahead enabled time read $raON"
10866
10867         rm -f $file
10868         wait_delete_completed
10869
10870         # use awk for this check instead of bash because it handles decimals
10871         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10872                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10873 }
10874 run_test 101d "file read with and without read-ahead enabled"
10875
10876 test_101e() {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878
10879         local file=$DIR/$tfile
10880         local size_KB=500  #KB
10881         local count=100
10882         local bsize=1024
10883
10884         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10885         local need_KB=$((count * size_KB))
10886         [[ $free_KB -le $need_KB ]] &&
10887                 skip_env "Need free space $need_KB, have $free_KB"
10888
10889         echo "Creating $count ${size_KB}K test files"
10890         for ((i = 0; i < $count; i++)); do
10891                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10892         done
10893
10894         echo "Cancel LRU locks on lustre client to flush the client cache"
10895         cancel_lru_locks $OSC
10896
10897         echo "Reset readahead stats"
10898         $LCTL set_param -n llite.*.read_ahead_stats=0
10899
10900         for ((i = 0; i < $count; i++)); do
10901                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10902         done
10903
10904         $LCTL get_param llite.*.max_cached_mb
10905         $LCTL get_param llite.*.read_ahead_stats
10906         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10907                      get_named_value 'misses' | calc_total)
10908
10909         for ((i = 0; i < $count; i++)); do
10910                 rm -rf $file.$i 2>/dev/null
10911         done
10912
10913         #10000 means 20% reads are missing in readahead
10914         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10915 }
10916 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10917
10918 test_101f() {
10919         which iozone || skip_env "no iozone installed"
10920
10921         local old_debug=$($LCTL get_param debug)
10922         old_debug=${old_debug#*=}
10923         $LCTL set_param debug="reada mmap"
10924
10925         # create a test file
10926         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10927
10928         echo Cancel LRU locks on lustre client to flush the client cache
10929         cancel_lru_locks osc
10930
10931         echo Reset readahead stats
10932         $LCTL set_param -n llite.*.read_ahead_stats=0
10933
10934         echo mmap read the file with small block size
10935         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10936                 > /dev/null 2>&1
10937
10938         echo checking missing pages
10939         $LCTL get_param llite.*.read_ahead_stats
10940         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10941                         get_named_value 'misses' | calc_total)
10942
10943         $LCTL set_param debug="$old_debug"
10944         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10945         rm -f $DIR/$tfile
10946 }
10947 run_test 101f "check mmap read performance"
10948
10949 test_101g_brw_size_test() {
10950         local mb=$1
10951         local pages=$((mb * 1048576 / PAGE_SIZE))
10952         local file=$DIR/$tfile
10953
10954         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10955                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10956         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10957                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10958                         return 2
10959         done
10960
10961         stack_trap "rm -f $file" EXIT
10962         $LCTL set_param -n osc.*.rpc_stats=0
10963
10964         # 10 RPCs should be enough for the test
10965         local count=10
10966         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10967                 { error "dd write ${mb} MB blocks failed"; return 3; }
10968         cancel_lru_locks osc
10969         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10970                 { error "dd write ${mb} MB blocks failed"; return 4; }
10971
10972         # calculate number of full-sized read and write RPCs
10973         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10974                 sed -n '/pages per rpc/,/^$/p' |
10975                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10976                 END { print reads,writes }'))
10977         # allow one extra full-sized read RPC for async readahead
10978         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10979                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10980         [[ ${rpcs[1]} == $count ]] ||
10981                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10982 }
10983
10984 test_101g() {
10985         remote_ost_nodsh && skip "remote OST with nodsh"
10986
10987         local rpcs
10988         local osts=$(get_facets OST)
10989         local list=$(comma_list $(osts_nodes))
10990         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10991         local brw_size="obdfilter.*.brw_size"
10992
10993         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10994
10995         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10996
10997         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10998                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10999                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11000            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11001                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11002                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11003
11004                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11005                         suffix="M"
11006
11007                 if [[ $orig_mb -lt 16 ]]; then
11008                         save_lustre_params $osts "$brw_size" > $p
11009                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11010                                 error "set 16MB RPC size failed"
11011
11012                         echo "remount client to enable new RPC size"
11013                         remount_client $MOUNT || error "remount_client failed"
11014                 fi
11015
11016                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11017                 # should be able to set brw_size=12, but no rpc_stats for that
11018                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11019         fi
11020
11021         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11022
11023         if [[ $orig_mb -lt 16 ]]; then
11024                 restore_lustre_params < $p
11025                 remount_client $MOUNT || error "remount_client restore failed"
11026         fi
11027
11028         rm -f $p $DIR/$tfile
11029 }
11030 run_test 101g "Big bulk(4/16 MiB) readahead"
11031
11032 test_101h() {
11033         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11034
11035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11036                 error "dd 70M file failed"
11037         echo Cancel LRU locks on lustre client to flush the client cache
11038         cancel_lru_locks osc
11039
11040         echo "Reset readahead stats"
11041         $LCTL set_param -n llite.*.read_ahead_stats 0
11042
11043         echo "Read 10M of data but cross 64M bundary"
11044         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11045         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11046                      get_named_value 'misses' | calc_total)
11047         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11048         rm -f $p $DIR/$tfile
11049 }
11050 run_test 101h "Readahead should cover current read window"
11051
11052 test_101i() {
11053         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11054                 error "dd 10M file failed"
11055
11056         local max_per_file_mb=$($LCTL get_param -n \
11057                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11058         cancel_lru_locks osc
11059         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11060         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11061                 error "set max_read_ahead_per_file_mb to 1 failed"
11062
11063         echo "Reset readahead stats"
11064         $LCTL set_param llite.*.read_ahead_stats=0
11065
11066         dd if=$DIR/$tfile of=/dev/null bs=2M
11067
11068         $LCTL get_param llite.*.read_ahead_stats
11069         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11070                      awk '/misses/ { print $2 }')
11071         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11072         rm -f $DIR/$tfile
11073 }
11074 run_test 101i "allow current readahead to exceed reservation"
11075
11076 test_101j() {
11077         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11078                 error "setstripe $DIR/$tfile failed"
11079         local file_size=$((1048576 * 16))
11080         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11081         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11082
11083         echo Disable read-ahead
11084         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11085
11086         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11087         for blk in $PAGE_SIZE 1048576 $file_size; do
11088                 cancel_lru_locks osc
11089                 echo "Reset readahead stats"
11090                 $LCTL set_param -n llite.*.read_ahead_stats=0
11091                 local count=$(($file_size / $blk))
11092                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11093                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11094                              get_named_value 'failed.to.fast.read' | calc_total)
11095                 $LCTL get_param -n llite.*.read_ahead_stats
11096                 [ $miss -eq $count ] || error "expected $count got $miss"
11097         done
11098
11099         rm -f $p $DIR/$tfile
11100 }
11101 run_test 101j "A complete read block should be submitted when no RA"
11102
11103 setup_test102() {
11104         test_mkdir $DIR/$tdir
11105         chown $RUNAS_ID $DIR/$tdir
11106         STRIPE_SIZE=65536
11107         STRIPE_OFFSET=1
11108         STRIPE_COUNT=$OSTCOUNT
11109         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11110
11111         trap cleanup_test102 EXIT
11112         cd $DIR
11113         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11114         cd $DIR/$tdir
11115         for num in 1 2 3 4; do
11116                 for count in $(seq 1 $STRIPE_COUNT); do
11117                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11118                                 local size=`expr $STRIPE_SIZE \* $num`
11119                                 local file=file"$num-$idx-$count"
11120                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11121                         done
11122                 done
11123         done
11124
11125         cd $DIR
11126         $1 tar cf $TMP/f102.tar $tdir --xattrs
11127 }
11128
11129 cleanup_test102() {
11130         trap 0
11131         rm -f $TMP/f102.tar
11132         rm -rf $DIR/d0.sanity/d102
11133 }
11134
11135 test_102a() {
11136         [ "$UID" != 0 ] && skip "must run as root"
11137         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11138                 skip_env "must have user_xattr"
11139
11140         [ -z "$(which setfattr 2>/dev/null)" ] &&
11141                 skip_env "could not find setfattr"
11142
11143         local testfile=$DIR/$tfile
11144
11145         touch $testfile
11146         echo "set/get xattr..."
11147         setfattr -n trusted.name1 -v value1 $testfile ||
11148                 error "setfattr -n trusted.name1=value1 $testfile failed"
11149         getfattr -n trusted.name1 $testfile 2> /dev/null |
11150           grep "trusted.name1=.value1" ||
11151                 error "$testfile missing trusted.name1=value1"
11152
11153         setfattr -n user.author1 -v author1 $testfile ||
11154                 error "setfattr -n user.author1=author1 $testfile failed"
11155         getfattr -n user.author1 $testfile 2> /dev/null |
11156           grep "user.author1=.author1" ||
11157                 error "$testfile missing trusted.author1=author1"
11158
11159         echo "listxattr..."
11160         setfattr -n trusted.name2 -v value2 $testfile ||
11161                 error "$testfile unable to set trusted.name2"
11162         setfattr -n trusted.name3 -v value3 $testfile ||
11163                 error "$testfile unable to set trusted.name3"
11164         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11165             grep "trusted.name" | wc -l) -eq 3 ] ||
11166                 error "$testfile missing 3 trusted.name xattrs"
11167
11168         setfattr -n user.author2 -v author2 $testfile ||
11169                 error "$testfile unable to set user.author2"
11170         setfattr -n user.author3 -v author3 $testfile ||
11171                 error "$testfile unable to set user.author3"
11172         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11173             grep "user.author" | wc -l) -eq 3 ] ||
11174                 error "$testfile missing 3 user.author xattrs"
11175
11176         echo "remove xattr..."
11177         setfattr -x trusted.name1 $testfile ||
11178                 error "$testfile error deleting trusted.name1"
11179         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11180                 error "$testfile did not delete trusted.name1 xattr"
11181
11182         setfattr -x user.author1 $testfile ||
11183                 error "$testfile error deleting user.author1"
11184         echo "set lustre special xattr ..."
11185         $LFS setstripe -c1 $testfile
11186         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11187                 awk -F "=" '/trusted.lov/ { print $2 }' )
11188         setfattr -n "trusted.lov" -v $lovea $testfile ||
11189                 error "$testfile doesn't ignore setting trusted.lov again"
11190         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11191                 error "$testfile allow setting invalid trusted.lov"
11192         rm -f $testfile
11193 }
11194 run_test 102a "user xattr test =================================="
11195
11196 check_102b_layout() {
11197         local layout="$*"
11198         local testfile=$DIR/$tfile
11199
11200         echo "test layout '$layout'"
11201         $LFS setstripe $layout $testfile || error "setstripe failed"
11202         $LFS getstripe -y $testfile
11203
11204         echo "get/set/list trusted.lov xattr ..." # b=10930
11205         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11206         [[ "$value" =~ "trusted.lov" ]] ||
11207                 error "can't get trusted.lov from $testfile"
11208         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11209                 error "getstripe failed"
11210
11211         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11212
11213         value=$(cut -d= -f2 <<<$value)
11214         # LU-13168: truncated xattr should fail if short lov_user_md header
11215         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11216                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11217         for len in $lens; do
11218                 echo "setfattr $len $testfile.2"
11219                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11220                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11221         done
11222         local stripe_size=$($LFS getstripe -S $testfile.2)
11223         local stripe_count=$($LFS getstripe -c $testfile.2)
11224         [[ $stripe_size -eq 65536 ]] ||
11225                 error "stripe size $stripe_size != 65536"
11226         [[ $stripe_count -eq $stripe_count_orig ]] ||
11227                 error "stripe count $stripe_count != $stripe_count_orig"
11228         rm $testfile $testfile.2
11229 }
11230
11231 test_102b() {
11232         [ -z "$(which setfattr 2>/dev/null)" ] &&
11233                 skip_env "could not find setfattr"
11234         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11235
11236         # check plain layout
11237         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11238
11239         # and also check composite layout
11240         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11241
11242 }
11243 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11244
11245 test_102c() {
11246         [ -z "$(which setfattr 2>/dev/null)" ] &&
11247                 skip_env "could not find setfattr"
11248         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11249
11250         # b10930: get/set/list lustre.lov xattr
11251         echo "get/set/list lustre.lov xattr ..."
11252         test_mkdir $DIR/$tdir
11253         chown $RUNAS_ID $DIR/$tdir
11254         local testfile=$DIR/$tdir/$tfile
11255         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11256                 error "setstripe failed"
11257         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11258                 error "getstripe failed"
11259         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11260         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11261
11262         local testfile2=${testfile}2
11263         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11264                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11265
11266         $RUNAS $MCREATE $testfile2
11267         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11268         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11269         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11270         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11271         [ $stripe_count -eq $STRIPECOUNT ] ||
11272                 error "stripe count $stripe_count != $STRIPECOUNT"
11273 }
11274 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11275
11276 compare_stripe_info1() {
11277         local stripe_index_all_zero=true
11278
11279         for num in 1 2 3 4; do
11280                 for count in $(seq 1 $STRIPE_COUNT); do
11281                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11282                                 local size=$((STRIPE_SIZE * num))
11283                                 local file=file"$num-$offset-$count"
11284                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11285                                 [[ $stripe_size -ne $size ]] &&
11286                                     error "$file: size $stripe_size != $size"
11287                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11288                                 # allow fewer stripes to be created, ORI-601
11289                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11290                                     error "$file: count $stripe_count != $count"
11291                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11292                                 [[ $stripe_index -ne 0 ]] &&
11293                                         stripe_index_all_zero=false
11294                         done
11295                 done
11296         done
11297         $stripe_index_all_zero &&
11298                 error "all files are being extracted starting from OST index 0"
11299         return 0
11300 }
11301
11302 have_xattrs_include() {
11303         tar --help | grep -q xattrs-include &&
11304                 echo --xattrs-include="lustre.*"
11305 }
11306
11307 test_102d() {
11308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11309         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11310
11311         XINC=$(have_xattrs_include)
11312         setup_test102
11313         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11314         cd $DIR/$tdir/$tdir
11315         compare_stripe_info1
11316 }
11317 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11318
11319 test_102f() {
11320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11321         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11322
11323         XINC=$(have_xattrs_include)
11324         setup_test102
11325         test_mkdir $DIR/$tdir.restore
11326         cd $DIR
11327         tar cf - --xattrs $tdir | tar xf - \
11328                 -C $DIR/$tdir.restore --xattrs $XINC
11329         cd $DIR/$tdir.restore/$tdir
11330         compare_stripe_info1
11331 }
11332 run_test 102f "tar copy files, not keep osts"
11333
11334 grow_xattr() {
11335         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11336                 skip "must have user_xattr"
11337         [ -z "$(which setfattr 2>/dev/null)" ] &&
11338                 skip_env "could not find setfattr"
11339         [ -z "$(which getfattr 2>/dev/null)" ] &&
11340                 skip_env "could not find getfattr"
11341
11342         local xsize=${1:-1024}  # in bytes
11343         local file=$DIR/$tfile
11344         local value="$(generate_string $xsize)"
11345         local xbig=trusted.big
11346         local toobig=$2
11347
11348         touch $file
11349         log "save $xbig on $file"
11350         if [ -z "$toobig" ]
11351         then
11352                 setfattr -n $xbig -v $value $file ||
11353                         error "saving $xbig on $file failed"
11354         else
11355                 setfattr -n $xbig -v $value $file &&
11356                         error "saving $xbig on $file succeeded"
11357                 return 0
11358         fi
11359
11360         local orig=$(get_xattr_value $xbig $file)
11361         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11362
11363         local xsml=trusted.sml
11364         log "save $xsml on $file"
11365         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11366
11367         local new=$(get_xattr_value $xbig $file)
11368         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11369
11370         log "grow $xsml on $file"
11371         setfattr -n $xsml -v "$value" $file ||
11372                 error "growing $xsml on $file failed"
11373
11374         new=$(get_xattr_value $xbig $file)
11375         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11376         log "$xbig still valid after growing $xsml"
11377
11378         rm -f $file
11379 }
11380
11381 test_102h() { # bug 15777
11382         grow_xattr 1024
11383 }
11384 run_test 102h "grow xattr from inside inode to external block"
11385
11386 test_102ha() {
11387         large_xattr_enabled || skip_env "ea_inode feature disabled"
11388
11389         echo "setting xattr of max xattr size: $(max_xattr_size)"
11390         grow_xattr $(max_xattr_size)
11391
11392         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11393         echo "This should fail:"
11394         grow_xattr $(($(max_xattr_size) + 10)) 1
11395 }
11396 run_test 102ha "grow xattr from inside inode to external inode"
11397
11398 test_102i() { # bug 17038
11399         [ -z "$(which getfattr 2>/dev/null)" ] &&
11400                 skip "could not find getfattr"
11401
11402         touch $DIR/$tfile
11403         ln -s $DIR/$tfile $DIR/${tfile}link
11404         getfattr -n trusted.lov $DIR/$tfile ||
11405                 error "lgetxattr on $DIR/$tfile failed"
11406         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11407                 grep -i "no such attr" ||
11408                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11409         rm -f $DIR/$tfile $DIR/${tfile}link
11410 }
11411 run_test 102i "lgetxattr test on symbolic link ============"
11412
11413 test_102j() {
11414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11416
11417         XINC=$(have_xattrs_include)
11418         setup_test102 "$RUNAS"
11419         chown $RUNAS_ID $DIR/$tdir
11420         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11421         cd $DIR/$tdir/$tdir
11422         compare_stripe_info1 "$RUNAS"
11423 }
11424 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11425
11426 test_102k() {
11427         [ -z "$(which setfattr 2>/dev/null)" ] &&
11428                 skip "could not find setfattr"
11429
11430         touch $DIR/$tfile
11431         # b22187 just check that does not crash for regular file.
11432         setfattr -n trusted.lov $DIR/$tfile
11433         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11434         local test_kdir=$DIR/$tdir
11435         test_mkdir $test_kdir
11436         local default_size=$($LFS getstripe -S $test_kdir)
11437         local default_count=$($LFS getstripe -c $test_kdir)
11438         local default_offset=$($LFS getstripe -i $test_kdir)
11439         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11440                 error 'dir setstripe failed'
11441         setfattr -n trusted.lov $test_kdir
11442         local stripe_size=$($LFS getstripe -S $test_kdir)
11443         local stripe_count=$($LFS getstripe -c $test_kdir)
11444         local stripe_offset=$($LFS getstripe -i $test_kdir)
11445         [ $stripe_size -eq $default_size ] ||
11446                 error "stripe size $stripe_size != $default_size"
11447         [ $stripe_count -eq $default_count ] ||
11448                 error "stripe count $stripe_count != $default_count"
11449         [ $stripe_offset -eq $default_offset ] ||
11450                 error "stripe offset $stripe_offset != $default_offset"
11451         rm -rf $DIR/$tfile $test_kdir
11452 }
11453 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11454
11455 test_102l() {
11456         [ -z "$(which getfattr 2>/dev/null)" ] &&
11457                 skip "could not find getfattr"
11458
11459         # LU-532 trusted. xattr is invisible to non-root
11460         local testfile=$DIR/$tfile
11461
11462         touch $testfile
11463
11464         echo "listxattr as user..."
11465         chown $RUNAS_ID $testfile
11466         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11467             grep -q "trusted" &&
11468                 error "$testfile trusted xattrs are user visible"
11469
11470         return 0;
11471 }
11472 run_test 102l "listxattr size test =================================="
11473
11474 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11475         local path=$DIR/$tfile
11476         touch $path
11477
11478         listxattr_size_check $path || error "listattr_size_check $path failed"
11479 }
11480 run_test 102m "Ensure listxattr fails on small bufffer ========"
11481
11482 cleanup_test102
11483
11484 getxattr() { # getxattr path name
11485         # Return the base64 encoding of the value of xattr name on path.
11486         local path=$1
11487         local name=$2
11488
11489         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11490         # file: $path
11491         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11492         #
11493         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11494
11495         getfattr --absolute-names --encoding=base64 --name=$name $path |
11496                 awk -F= -v name=$name '$1 == name {
11497                         print substr($0, index($0, "=") + 1);
11498         }'
11499 }
11500
11501 test_102n() { # LU-4101 mdt: protect internal xattrs
11502         [ -z "$(which setfattr 2>/dev/null)" ] &&
11503                 skip "could not find setfattr"
11504         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11505         then
11506                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11507         fi
11508
11509         local file0=$DIR/$tfile.0
11510         local file1=$DIR/$tfile.1
11511         local xattr0=$TMP/$tfile.0
11512         local xattr1=$TMP/$tfile.1
11513         local namelist="lov lma lmv link fid version som hsm"
11514         local name
11515         local value
11516
11517         rm -rf $file0 $file1 $xattr0 $xattr1
11518         touch $file0 $file1
11519
11520         # Get 'before' xattrs of $file1.
11521         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11522
11523         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11524                 namelist+=" lfsck_namespace"
11525         for name in $namelist; do
11526                 # Try to copy xattr from $file0 to $file1.
11527                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11528
11529                 setfattr --name=trusted.$name --value="$value" $file1 ||
11530                         error "setxattr 'trusted.$name' failed"
11531
11532                 # Try to set a garbage xattr.
11533                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11534
11535                 if [[ x$name == "xlov" ]]; then
11536                         setfattr --name=trusted.lov --value="$value" $file1 &&
11537                         error "setxattr invalid 'trusted.lov' success"
11538                 else
11539                         setfattr --name=trusted.$name --value="$value" $file1 ||
11540                                 error "setxattr invalid 'trusted.$name' failed"
11541                 fi
11542
11543                 # Try to remove the xattr from $file1. We don't care if this
11544                 # appears to succeed or fail, we just don't want there to be
11545                 # any changes or crashes.
11546                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11547         done
11548
11549         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11550         then
11551                 name="lfsck_ns"
11552                 # Try to copy xattr from $file0 to $file1.
11553                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11554
11555                 setfattr --name=trusted.$name --value="$value" $file1 ||
11556                         error "setxattr 'trusted.$name' failed"
11557
11558                 # Try to set a garbage xattr.
11559                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11560
11561                 setfattr --name=trusted.$name --value="$value" $file1 ||
11562                         error "setxattr 'trusted.$name' failed"
11563
11564                 # Try to remove the xattr from $file1. We don't care if this
11565                 # appears to succeed or fail, we just don't want there to be
11566                 # any changes or crashes.
11567                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11568         fi
11569
11570         # Get 'after' xattrs of file1.
11571         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11572
11573         if ! diff $xattr0 $xattr1; then
11574                 error "before and after xattrs of '$file1' differ"
11575         fi
11576
11577         rm -rf $file0 $file1 $xattr0 $xattr1
11578
11579         return 0
11580 }
11581 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11582
11583 test_102p() { # LU-4703 setxattr did not check ownership
11584         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11585                 skip "MDS needs to be at least 2.5.56"
11586
11587         local testfile=$DIR/$tfile
11588
11589         touch $testfile
11590
11591         echo "setfacl as user..."
11592         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11593         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11594
11595         echo "setfattr as user..."
11596         setfacl -m "u:$RUNAS_ID:---" $testfile
11597         $RUNAS setfattr -x system.posix_acl_access $testfile
11598         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11599 }
11600 run_test 102p "check setxattr(2) correctly fails without permission"
11601
11602 test_102q() {
11603         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11604                 skip "MDS needs to be at least 2.6.92"
11605
11606         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11607 }
11608 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11609
11610 test_102r() {
11611         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11612                 skip "MDS needs to be at least 2.6.93"
11613
11614         touch $DIR/$tfile || error "touch"
11615         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11616         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11617         rm $DIR/$tfile || error "rm"
11618
11619         #normal directory
11620         mkdir -p $DIR/$tdir || error "mkdir"
11621         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11622         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11623         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11624                 error "$testfile error deleting user.author1"
11625         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11626                 grep "user.$(basename $tdir)" &&
11627                 error "$tdir did not delete user.$(basename $tdir)"
11628         rmdir $DIR/$tdir || error "rmdir"
11629
11630         #striped directory
11631         test_mkdir $DIR/$tdir
11632         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11633         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11634         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11635                 error "$testfile error deleting user.author1"
11636         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11637                 grep "user.$(basename $tdir)" &&
11638                 error "$tdir did not delete user.$(basename $tdir)"
11639         rmdir $DIR/$tdir || error "rm striped dir"
11640 }
11641 run_test 102r "set EAs with empty values"
11642
11643 test_102s() {
11644         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11645                 skip "MDS needs to be at least 2.11.52"
11646
11647         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11648
11649         save_lustre_params client "llite.*.xattr_cache" > $save
11650
11651         for cache in 0 1; do
11652                 lctl set_param llite.*.xattr_cache=$cache
11653
11654                 rm -f $DIR/$tfile
11655                 touch $DIR/$tfile || error "touch"
11656                 for prefix in lustre security system trusted user; do
11657                         # Note getxattr() may fail with 'Operation not
11658                         # supported' or 'No such attribute' depending
11659                         # on prefix and cache.
11660                         getfattr -n $prefix.n102s $DIR/$tfile &&
11661                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11662                 done
11663         done
11664
11665         restore_lustre_params < $save
11666 }
11667 run_test 102s "getting nonexistent xattrs should fail"
11668
11669 test_102t() {
11670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11671                 skip "MDS needs to be at least 2.11.52"
11672
11673         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11674
11675         save_lustre_params client "llite.*.xattr_cache" > $save
11676
11677         for cache in 0 1; do
11678                 lctl set_param llite.*.xattr_cache=$cache
11679
11680                 for buf_size in 0 256; do
11681                         rm -f $DIR/$tfile
11682                         touch $DIR/$tfile || error "touch"
11683                         setfattr -n user.multiop $DIR/$tfile
11684                         $MULTIOP $DIR/$tfile oa$buf_size ||
11685                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11686                 done
11687         done
11688
11689         restore_lustre_params < $save
11690 }
11691 run_test 102t "zero length xattr values handled correctly"
11692
11693 run_acl_subtest()
11694 {
11695         local test=$LUSTRE/tests/acl/$1.test
11696         local tmp=$(mktemp -t $1-XXXXXX).test
11697         local bin=$2
11698         local dmn=$3
11699         local grp=$4
11700         local nbd=$5
11701         export LANG=C
11702
11703
11704         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11705         local sedgroups="-e s/:users/:$grp/g"
11706         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11707
11708         sed $sedusers $sedgroups < $test > $tmp
11709         stack_trap "rm -f $tmp"
11710         [[ -s $tmp ]] || error "sed failed to create test script"
11711
11712         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11713         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11714 }
11715
11716 test_103a() {
11717         [ "$UID" != 0 ] && skip "must run as root"
11718         $GSS && skip_env "could not run under gss"
11719         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11720                 skip_env "must have acl enabled"
11721         which setfacl || skip_env "could not find setfacl"
11722         remote_mds_nodsh && skip "remote MDS with nodsh"
11723
11724         ACLBIN=${ACLBIN:-"bin"}
11725         ACLDMN=${ACLDMN:-"daemon"}
11726         ACLGRP=${ACLGRP:-"users"}
11727         ACLNBD=${ACLNBD:-"nobody"}
11728
11729         if ! id $ACLBIN ||
11730            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11731                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11732                 ACLBIN=$USER0
11733                 if ! id $ACLBIN ; then
11734                         cat /etc/passwd
11735                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11736                 fi
11737         fi
11738         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11739            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11740                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11741                 ACLDMN=$USER1
11742                 if ! id $ACLDMN ; then
11743                         cat /etc/passwd
11744                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11745                 fi
11746         fi
11747         if ! getent group $ACLGRP; then
11748                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11749                 ACLGRP="$TSTUSR"
11750                 if ! getent group $ACLGRP; then
11751                         echo "cannot find group '$ACLGRP', adding it"
11752                         cat /etc/group
11753                         add_group 60000 $ACLGRP
11754                 fi
11755         fi
11756
11757         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11758         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11759         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11760
11761         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11762                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11763                 ACLGRP="$TSTUSR"
11764                 if ! getent group $ACLGRP; then
11765                         echo "cannot find group '$ACLGRP', adding it"
11766                         cat /etc/group
11767                         add_group 60000 $ACLGRP
11768                 fi
11769                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11770                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11771                         cat /etc/group
11772                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11773                 fi
11774         fi
11775
11776         gpasswd -a $ACLDMN $ACLBIN ||
11777                 error "setting client group failed"             # LU-5641
11778         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11779                 error "setting MDS group failed"                # LU-5641
11780
11781         declare -a identity_old
11782
11783         for num in $(seq $MDSCOUNT); do
11784                 switch_identity $num true || identity_old[$num]=$?
11785         done
11786
11787         SAVE_UMASK=$(umask)
11788         umask 0022
11789         mkdir -p $DIR/$tdir
11790         cd $DIR/$tdir
11791
11792         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11793         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11794         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11795         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11796         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11797         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11798         if ! id -u $ACLNBD ||
11799            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11800                 ACLNBD="nfsnobody"
11801                 if ! id -u $ACLNBD; then
11802                         ACLNBD=""
11803                 fi
11804         fi
11805         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11806                 add_group $(id -u $ACLNBD) $ACLNBD
11807                 if ! getent group $ACLNBD; then
11808                         ACLNBD=""
11809                 fi
11810         fi
11811         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11812            [[ -n "$ACLNBD" ]] && which setfattr; then
11813                 run_acl_subtest permissions_xattr \
11814                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11815         elif [[ -z "$ACLNBD" ]]; then
11816                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11817         else
11818                 echo "skip 'permission_xattr' test - missing setfattr command"
11819         fi
11820         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11821
11822         # inheritance test got from HP
11823         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11824         chmod +x make-tree || error "chmod +x failed"
11825         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11826         rm -f make-tree
11827
11828         echo "LU-974 ignore umask when acl is enabled..."
11829         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11830         if [ $MDSCOUNT -ge 2 ]; then
11831                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11832         fi
11833
11834         echo "LU-2561 newly created file is same size as directory..."
11835         if [ "$mds1_FSTYPE" != "zfs" ]; then
11836                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11837         else
11838                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11839         fi
11840
11841         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11842
11843         cd $SAVE_PWD
11844         umask $SAVE_UMASK
11845
11846         for num in $(seq $MDSCOUNT); do
11847                 if [ "${identity_old[$num]}" = 1 ]; then
11848                         switch_identity $num false || identity_old[$num]=$?
11849                 fi
11850         done
11851 }
11852 run_test 103a "acl test"
11853
11854 test_103b() {
11855         declare -a pids
11856         local U
11857
11858         for U in {0..511}; do
11859                 {
11860                 local O=$(printf "%04o" $U)
11861
11862                 umask $(printf "%04o" $((511 ^ $O)))
11863                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11864                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11865
11866                 (( $S == ($O & 0666) )) ||
11867                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11868
11869                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11870                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11871                 (( $S == ($O & 0666) )) ||
11872                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11873
11874                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11875                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11876                 (( $S == ($O & 0666) )) ||
11877                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11878                 rm -f $DIR/$tfile.[smp]$0
11879                 } &
11880                 local pid=$!
11881
11882                 # limit the concurrently running threads to 64. LU-11878
11883                 local idx=$((U % 64))
11884                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11885                 pids[idx]=$pid
11886         done
11887         wait
11888 }
11889 run_test 103b "umask lfs setstripe"
11890
11891 test_103c() {
11892         mkdir -p $DIR/$tdir
11893         cp -rp $DIR/$tdir $DIR/$tdir.bak
11894
11895         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11896                 error "$DIR/$tdir shouldn't contain default ACL"
11897         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11898                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11899         true
11900 }
11901 run_test 103c "'cp -rp' won't set empty acl"
11902
11903 test_103e() {
11904         local numacl
11905         local fileacl
11906         local saved_debug=$($LCTL get_param -n debug)
11907
11908         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11909                 skip "MDS needs to be at least 2.14.52"
11910
11911         large_xattr_enabled || skip_env "ea_inode feature disabled"
11912
11913         mkdir -p $DIR/$tdir
11914         # add big LOV EA to cause reply buffer overflow earlier
11915         $LFS setstripe -C 1000 $DIR/$tdir
11916         lctl set_param mdc.*-mdc*.stats=clear
11917
11918         $LCTL set_param debug=0
11919         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11920         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11921
11922         # add a large number of default ACLs (expect 8000+ for 2.13+)
11923         for U in {2..7000}; do
11924                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11925                         error "Able to add just $U default ACLs"
11926         done
11927         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11928         echo "$numacl default ACLs created"
11929
11930         stat $DIR/$tdir || error "Cannot stat directory"
11931         # check file creation
11932         touch $DIR/$tdir/$tfile ||
11933                 error "failed to create $tfile with $numacl default ACLs"
11934         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11935         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11936         echo "$fileacl ACLs were inherited"
11937         (( $fileacl == $numacl )) ||
11938                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11939         # check that new ACLs creation adds new ACLs to inherited ACLs
11940         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11941                 error "Cannot set new ACL"
11942         numacl=$((numacl + 1))
11943         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11944         (( $fileacl == $numacl )) ||
11945                 error "failed to add new ACL: $fileacl != $numacl as expected"
11946         # adds more ACLs to a file to reach their maximum at 8000+
11947         numacl=0
11948         for U in {20000..25000}; do
11949                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11950                 numacl=$((numacl + 1))
11951         done
11952         echo "Added $numacl more ACLs to the file"
11953         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11954         echo "Total $fileacl ACLs in file"
11955         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11956         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11957         rmdir $DIR/$tdir || error "Cannot remove directory"
11958 }
11959 run_test 103e "inheritance of big amount of default ACLs"
11960
11961 test_103f() {
11962         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11963                 skip "MDS needs to be at least 2.14.51"
11964
11965         large_xattr_enabled || skip_env "ea_inode feature disabled"
11966
11967         # enable changelog to consume more internal MDD buffers
11968         changelog_register
11969
11970         mkdir -p $DIR/$tdir
11971         # add big LOV EA
11972         $LFS setstripe -C 1000 $DIR/$tdir
11973         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11974         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11975         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11976         rmdir $DIR/$tdir || error "Cannot remove directory"
11977 }
11978 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11979
11980 test_104a() {
11981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11982
11983         touch $DIR/$tfile
11984         lfs df || error "lfs df failed"
11985         lfs df -ih || error "lfs df -ih failed"
11986         lfs df -h $DIR || error "lfs df -h $DIR failed"
11987         lfs df -i $DIR || error "lfs df -i $DIR failed"
11988         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11989         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11990
11991         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11992         lctl --device %$OSC deactivate
11993         lfs df || error "lfs df with deactivated OSC failed"
11994         lctl --device %$OSC activate
11995         # wait the osc back to normal
11996         wait_osc_import_ready client ost
11997
11998         lfs df || error "lfs df with reactivated OSC failed"
11999         rm -f $DIR/$tfile
12000 }
12001 run_test 104a "lfs df [-ih] [path] test ========================="
12002
12003 test_104b() {
12004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12005         [ $RUNAS_ID -eq $UID ] &&
12006                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12007
12008         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12009                         grep "Permission denied" | wc -l)))
12010         if [ $denied_cnt -ne 0 ]; then
12011                 error "lfs check servers test failed"
12012         fi
12013 }
12014 run_test 104b "$RUNAS lfs check servers test ===================="
12015
12016 #
12017 # Verify $1 is within range of $2.
12018 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12019 # $1 is <= 2% of $2. Else Fail.
12020 #
12021 value_in_range() {
12022         # Strip all units (M, G, T)
12023         actual=$(echo $1 | tr -d A-Z)
12024         expect=$(echo $2 | tr -d A-Z)
12025
12026         expect_lo=$(($expect * 98 / 100)) # 2% below
12027         expect_hi=$(($expect * 102 / 100)) # 2% above
12028
12029         # permit 2% drift above and below
12030         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12031 }
12032
12033 test_104c() {
12034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12035         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12036
12037         local ost_param="osd-zfs.$FSNAME-OST0000."
12038         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12039         local ofacets=$(get_facets OST)
12040         local mfacets=$(get_facets MDS)
12041         local saved_ost_blocks=
12042         local saved_mdt_blocks=
12043
12044         echo "Before recordsize change"
12045         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12046         df=($(df -h | grep "$MOUNT"$))
12047
12048         # For checking.
12049         echo "lfs output : ${lfs_df[*]}"
12050         echo "df  output : ${df[*]}"
12051
12052         for facet in ${ofacets//,/ }; do
12053                 if [ -z $saved_ost_blocks ]; then
12054                         saved_ost_blocks=$(do_facet $facet \
12055                                 lctl get_param -n $ost_param.blocksize)
12056                         echo "OST Blocksize: $saved_ost_blocks"
12057                 fi
12058                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12059                 do_facet $facet zfs set recordsize=32768 $ost
12060         done
12061
12062         # BS too small. Sufficient for functional testing.
12063         for facet in ${mfacets//,/ }; do
12064                 if [ -z $saved_mdt_blocks ]; then
12065                         saved_mdt_blocks=$(do_facet $facet \
12066                                 lctl get_param -n $mdt_param.blocksize)
12067                         echo "MDT Blocksize: $saved_mdt_blocks"
12068                 fi
12069                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12070                 do_facet $facet zfs set recordsize=32768 $mdt
12071         done
12072
12073         # Give new values chance to reflect change
12074         sleep 2
12075
12076         echo "After recordsize change"
12077         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12078         df_after=($(df -h | grep "$MOUNT"$))
12079
12080         # For checking.
12081         echo "lfs output : ${lfs_df_after[*]}"
12082         echo "df  output : ${df_after[*]}"
12083
12084         # Verify lfs df
12085         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12086                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12087         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12088                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12089         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12090                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12091
12092         # Verify df
12093         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12094                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12095         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12096                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12097         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12098                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12099
12100         # Restore MDT recordize back to original
12101         for facet in ${mfacets//,/ }; do
12102                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12103                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12104         done
12105
12106         # Restore OST recordize back to original
12107         for facet in ${ofacets//,/ }; do
12108                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12109                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12110         done
12111
12112         return 0
12113 }
12114 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12115
12116 test_104d() {
12117         (( $RUNAS_ID != $UID )) ||
12118                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12119
12120         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12121                 skip "lustre version doesn't support lctl dl with non-root"
12122
12123         # debugfs only allows root users to access files, so the
12124         # previous move of the "devices" file to debugfs broke
12125         # "lctl dl" for non-root users. The LU-9680 Netlink
12126         # interface again allows non-root users to list devices.
12127         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12128                 error "lctl dl doesn't work for non root"
12129
12130         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12131         [ "$ost_count" -eq $OSTCOUNT ]  ||
12132                 error "lctl dl reports wrong number of OST devices"
12133
12134         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12135         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12136                 error "lctl dl reports wrong number of MDT devices"
12137 }
12138 run_test 104d "$RUNAS lctl dl test"
12139
12140 test_105a() {
12141         # doesn't work on 2.4 kernels
12142         touch $DIR/$tfile
12143         if $(flock_is_enabled); then
12144                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12145         else
12146                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12147         fi
12148         rm -f $DIR/$tfile
12149 }
12150 run_test 105a "flock when mounted without -o flock test ========"
12151
12152 test_105b() {
12153         touch $DIR/$tfile
12154         if $(flock_is_enabled); then
12155                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12156         else
12157                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12158         fi
12159         rm -f $DIR/$tfile
12160 }
12161 run_test 105b "fcntl when mounted without -o flock test ========"
12162
12163 test_105c() {
12164         touch $DIR/$tfile
12165         if $(flock_is_enabled); then
12166                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12167         else
12168                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12169         fi
12170         rm -f $DIR/$tfile
12171 }
12172 run_test 105c "lockf when mounted without -o flock test"
12173
12174 test_105d() { # bug 15924
12175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12176
12177         test_mkdir $DIR/$tdir
12178         flock_is_enabled || skip_env "mount w/o flock enabled"
12179         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12180         $LCTL set_param fail_loc=0x80000315
12181         flocks_test 2 $DIR/$tdir
12182 }
12183 run_test 105d "flock race (should not freeze) ========"
12184
12185 test_105e() { # bug 22660 && 22040
12186         flock_is_enabled || skip_env "mount w/o flock enabled"
12187
12188         touch $DIR/$tfile
12189         flocks_test 3 $DIR/$tfile
12190 }
12191 run_test 105e "Two conflicting flocks from same process"
12192
12193 test_106() { #bug 10921
12194         test_mkdir $DIR/$tdir
12195         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12196         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12197 }
12198 run_test 106 "attempt exec of dir followed by chown of that dir"
12199
12200 test_107() {
12201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12202
12203         CDIR=`pwd`
12204         local file=core
12205
12206         cd $DIR
12207         rm -f $file
12208
12209         local save_pattern=$(sysctl -n kernel.core_pattern)
12210         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12211         sysctl -w kernel.core_pattern=$file
12212         sysctl -w kernel.core_uses_pid=0
12213
12214         ulimit -c unlimited
12215         sleep 60 &
12216         SLEEPPID=$!
12217
12218         sleep 1
12219
12220         kill -s 11 $SLEEPPID
12221         wait $SLEEPPID
12222         if [ -e $file ]; then
12223                 size=`stat -c%s $file`
12224                 [ $size -eq 0 ] && error "Fail to create core file $file"
12225         else
12226                 error "Fail to create core file $file"
12227         fi
12228         rm -f $file
12229         sysctl -w kernel.core_pattern=$save_pattern
12230         sysctl -w kernel.core_uses_pid=$save_uses_pid
12231         cd $CDIR
12232 }
12233 run_test 107 "Coredump on SIG"
12234
12235 test_110() {
12236         test_mkdir $DIR/$tdir
12237         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12238         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12239                 error "mkdir with 256 char should fail, but did not"
12240         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12241                 error "create with 255 char failed"
12242         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12243                 error "create with 256 char should fail, but did not"
12244
12245         ls -l $DIR/$tdir
12246         rm -rf $DIR/$tdir
12247 }
12248 run_test 110 "filename length checking"
12249
12250 test_116a() { # was previously test_116()
12251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12252         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12253         remote_mds_nodsh && skip "remote MDS with nodsh"
12254
12255         echo -n "Free space priority "
12256         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12257                 head -n1
12258         declare -a AVAIL
12259         free_min_max
12260
12261         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12262         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12263         stack_trap simple_cleanup_common
12264
12265         # Check if we need to generate uneven OSTs
12266         test_mkdir -p $DIR/$tdir/OST${MINI}
12267         local FILL=$((MINV / 4))
12268         local DIFF=$((MAXV - MINV))
12269         local DIFF2=$((DIFF * 100 / MINV))
12270
12271         local threshold=$(do_facet $SINGLEMDS \
12272                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12273         threshold=${threshold%%%}
12274         echo -n "Check for uneven OSTs: "
12275         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12276
12277         if [[ $DIFF2 -gt $threshold ]]; then
12278                 echo "ok"
12279                 echo "Don't need to fill OST$MINI"
12280         else
12281                 # generate uneven OSTs. Write 2% over the QOS threshold value
12282                 echo "no"
12283                 DIFF=$((threshold - DIFF2 + 2))
12284                 DIFF2=$((MINV * DIFF / 100))
12285                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12286                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12287                         error "setstripe failed"
12288                 DIFF=$((DIFF2 / 2048))
12289                 i=0
12290                 while [ $i -lt $DIFF ]; do
12291                         i=$((i + 1))
12292                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12293                                 bs=2M count=1 2>/dev/null
12294                         echo -n .
12295                 done
12296                 echo .
12297                 sync
12298                 sleep_maxage
12299                 free_min_max
12300         fi
12301
12302         DIFF=$((MAXV - MINV))
12303         DIFF2=$((DIFF * 100 / MINV))
12304         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12305         if [ $DIFF2 -gt $threshold ]; then
12306                 echo "ok"
12307         else
12308                 skip "QOS imbalance criteria not met"
12309         fi
12310
12311         MINI1=$MINI
12312         MINV1=$MINV
12313         MAXI1=$MAXI
12314         MAXV1=$MAXV
12315
12316         # now fill using QOS
12317         $LFS setstripe -c 1 $DIR/$tdir
12318         FILL=$((FILL / 200))
12319         if [ $FILL -gt 600 ]; then
12320                 FILL=600
12321         fi
12322         echo "writing $FILL files to QOS-assigned OSTs"
12323         i=0
12324         while [ $i -lt $FILL ]; do
12325                 i=$((i + 1))
12326                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12327                         count=1 2>/dev/null
12328                 echo -n .
12329         done
12330         echo "wrote $i 200k files"
12331         sync
12332         sleep_maxage
12333
12334         echo "Note: free space may not be updated, so measurements might be off"
12335         free_min_max
12336         DIFF2=$((MAXV - MINV))
12337         echo "free space delta: orig $DIFF final $DIFF2"
12338         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12339         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12340         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12341         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12342         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12343         if [[ $DIFF -gt 0 ]]; then
12344                 FILL=$((DIFF2 * 100 / DIFF - 100))
12345                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12346         fi
12347
12348         # Figure out which files were written where
12349         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12350                awk '/'$MINI1': / {print $2; exit}')
12351         echo $UUID
12352         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12353         echo "$MINC files created on smaller OST $MINI1"
12354         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12355                awk '/'$MAXI1': / {print $2; exit}')
12356         echo $UUID
12357         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12358         echo "$MAXC files created on larger OST $MAXI1"
12359         if [[ $MINC -gt 0 ]]; then
12360                 FILL=$((MAXC * 100 / MINC - 100))
12361                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12362         fi
12363         [[ $MAXC -gt $MINC ]] ||
12364                 error_ignore LU-9 "stripe QOS didn't balance free space"
12365 }
12366 run_test 116a "stripe QOS: free space balance ==================="
12367
12368 test_116b() { # LU-2093
12369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12370         remote_mds_nodsh && skip "remote MDS with nodsh"
12371
12372 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12373         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12374                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12375         [ -z "$old_rr" ] && skip "no QOS"
12376         do_facet $SINGLEMDS lctl set_param \
12377                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12378         mkdir -p $DIR/$tdir
12379         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12380         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12381         do_facet $SINGLEMDS lctl set_param fail_loc=0
12382         rm -rf $DIR/$tdir
12383         do_facet $SINGLEMDS lctl set_param \
12384                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12385 }
12386 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12387
12388 test_117() # bug 10891
12389 {
12390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12391
12392         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12393         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12394         lctl set_param fail_loc=0x21e
12395         > $DIR/$tfile || error "truncate failed"
12396         lctl set_param fail_loc=0
12397         echo "Truncate succeeded."
12398         rm -f $DIR/$tfile
12399 }
12400 run_test 117 "verify osd extend =========="
12401
12402 NO_SLOW_RESENDCOUNT=4
12403 export OLD_RESENDCOUNT=""
12404 set_resend_count () {
12405         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12406         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12407         lctl set_param -n $PROC_RESENDCOUNT $1
12408         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12409 }
12410
12411 # for reduce test_118* time (b=14842)
12412 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12413
12414 # Reset async IO behavior after error case
12415 reset_async() {
12416         FILE=$DIR/reset_async
12417
12418         # Ensure all OSCs are cleared
12419         $LFS setstripe -c -1 $FILE
12420         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12421         sync
12422         rm $FILE
12423 }
12424
12425 test_118a() #bug 11710
12426 {
12427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12428
12429         reset_async
12430
12431         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12432         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12433         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12434
12435         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12436                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12437                 return 1;
12438         fi
12439         rm -f $DIR/$tfile
12440 }
12441 run_test 118a "verify O_SYNC works =========="
12442
12443 test_118b()
12444 {
12445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12446         remote_ost_nodsh && skip "remote OST with nodsh"
12447
12448         reset_async
12449
12450         #define OBD_FAIL_SRV_ENOENT 0x217
12451         set_nodes_failloc "$(osts_nodes)" 0x217
12452         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12453         RC=$?
12454         set_nodes_failloc "$(osts_nodes)" 0
12455         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12456         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12457                     grep -c writeback)
12458
12459         if [[ $RC -eq 0 ]]; then
12460                 error "Must return error due to dropped pages, rc=$RC"
12461                 return 1;
12462         fi
12463
12464         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12465                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12466                 return 1;
12467         fi
12468
12469         echo "Dirty pages not leaked on ENOENT"
12470
12471         # Due to the above error the OSC will issue all RPCs syncronously
12472         # until a subsequent RPC completes successfully without error.
12473         $MULTIOP $DIR/$tfile Ow4096yc
12474         rm -f $DIR/$tfile
12475
12476         return 0
12477 }
12478 run_test 118b "Reclaim dirty pages on fatal error =========="
12479
12480 test_118c()
12481 {
12482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12483
12484         # for 118c, restore the original resend count, LU-1940
12485         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12486                                 set_resend_count $OLD_RESENDCOUNT
12487         remote_ost_nodsh && skip "remote OST with nodsh"
12488
12489         reset_async
12490
12491         #define OBD_FAIL_OST_EROFS               0x216
12492         set_nodes_failloc "$(osts_nodes)" 0x216
12493
12494         # multiop should block due to fsync until pages are written
12495         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12496         MULTIPID=$!
12497         sleep 1
12498
12499         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12500                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12501         fi
12502
12503         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12504                     grep -c writeback)
12505         if [[ $WRITEBACK -eq 0 ]]; then
12506                 error "No page in writeback, writeback=$WRITEBACK"
12507         fi
12508
12509         set_nodes_failloc "$(osts_nodes)" 0
12510         wait $MULTIPID
12511         RC=$?
12512         if [[ $RC -ne 0 ]]; then
12513                 error "Multiop fsync failed, rc=$RC"
12514         fi
12515
12516         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12517         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12518                     grep -c writeback)
12519         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12520                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12521         fi
12522
12523         rm -f $DIR/$tfile
12524         echo "Dirty pages flushed via fsync on EROFS"
12525         return 0
12526 }
12527 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12528
12529 # continue to use small resend count to reduce test_118* time (b=14842)
12530 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12531
12532 test_118d()
12533 {
12534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12535         remote_ost_nodsh && skip "remote OST with nodsh"
12536
12537         reset_async
12538
12539         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12540         set_nodes_failloc "$(osts_nodes)" 0x214
12541         # multiop should block due to fsync until pages are written
12542         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12543         MULTIPID=$!
12544         sleep 1
12545
12546         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12547                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12548         fi
12549
12550         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12551                     grep -c writeback)
12552         if [[ $WRITEBACK -eq 0 ]]; then
12553                 error "No page in writeback, writeback=$WRITEBACK"
12554         fi
12555
12556         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12557         set_nodes_failloc "$(osts_nodes)" 0
12558
12559         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12560         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12561                     grep -c writeback)
12562         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12563                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12564         fi
12565
12566         rm -f $DIR/$tfile
12567         echo "Dirty pages gaurenteed flushed via fsync"
12568         return 0
12569 }
12570 run_test 118d "Fsync validation inject a delay of the bulk =========="
12571
12572 test_118f() {
12573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12574
12575         reset_async
12576
12577         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12578         lctl set_param fail_loc=0x8000040a
12579
12580         # Should simulate EINVAL error which is fatal
12581         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12582         RC=$?
12583         if [[ $RC -eq 0 ]]; then
12584                 error "Must return error due to dropped pages, rc=$RC"
12585         fi
12586
12587         lctl set_param fail_loc=0x0
12588
12589         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12590         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12591         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12592                     grep -c writeback)
12593         if [[ $LOCKED -ne 0 ]]; then
12594                 error "Locked pages remain in cache, locked=$LOCKED"
12595         fi
12596
12597         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12598                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12599         fi
12600
12601         rm -f $DIR/$tfile
12602         echo "No pages locked after fsync"
12603
12604         reset_async
12605         return 0
12606 }
12607 run_test 118f "Simulate unrecoverable OSC side error =========="
12608
12609 test_118g() {
12610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12611
12612         reset_async
12613
12614         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12615         lctl set_param fail_loc=0x406
12616
12617         # simulate local -ENOMEM
12618         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12619         RC=$?
12620
12621         lctl set_param fail_loc=0
12622         if [[ $RC -eq 0 ]]; then
12623                 error "Must return error due to dropped pages, rc=$RC"
12624         fi
12625
12626         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12627         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12628         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12629                         grep -c writeback)
12630         if [[ $LOCKED -ne 0 ]]; then
12631                 error "Locked pages remain in cache, locked=$LOCKED"
12632         fi
12633
12634         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12635                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12636         fi
12637
12638         rm -f $DIR/$tfile
12639         echo "No pages locked after fsync"
12640
12641         reset_async
12642         return 0
12643 }
12644 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12645
12646 test_118h() {
12647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12648         remote_ost_nodsh && skip "remote OST with nodsh"
12649
12650         reset_async
12651
12652         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12653         set_nodes_failloc "$(osts_nodes)" 0x20e
12654         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12655         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12656         RC=$?
12657
12658         set_nodes_failloc "$(osts_nodes)" 0
12659         if [[ $RC -eq 0 ]]; then
12660                 error "Must return error due to dropped pages, rc=$RC"
12661         fi
12662
12663         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12664         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12665         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12666                     grep -c writeback)
12667         if [[ $LOCKED -ne 0 ]]; then
12668                 error "Locked pages remain in cache, locked=$LOCKED"
12669         fi
12670
12671         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12672                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12673         fi
12674
12675         rm -f $DIR/$tfile
12676         echo "No pages locked after fsync"
12677
12678         return 0
12679 }
12680 run_test 118h "Verify timeout in handling recoverables errors  =========="
12681
12682 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12683
12684 test_118i() {
12685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12686         remote_ost_nodsh && skip "remote OST with nodsh"
12687
12688         reset_async
12689
12690         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12691         set_nodes_failloc "$(osts_nodes)" 0x20e
12692
12693         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12694         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12695         PID=$!
12696         sleep 5
12697         set_nodes_failloc "$(osts_nodes)" 0
12698
12699         wait $PID
12700         RC=$?
12701         if [[ $RC -ne 0 ]]; then
12702                 error "got error, but should be not, rc=$RC"
12703         fi
12704
12705         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12706         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12707         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12708         if [[ $LOCKED -ne 0 ]]; then
12709                 error "Locked pages remain in cache, locked=$LOCKED"
12710         fi
12711
12712         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12713                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12714         fi
12715
12716         rm -f $DIR/$tfile
12717         echo "No pages locked after fsync"
12718
12719         return 0
12720 }
12721 run_test 118i "Fix error before timeout in recoverable error  =========="
12722
12723 [ "$SLOW" = "no" ] && set_resend_count 4
12724
12725 test_118j() {
12726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12727         remote_ost_nodsh && skip "remote OST with nodsh"
12728
12729         reset_async
12730
12731         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12732         set_nodes_failloc "$(osts_nodes)" 0x220
12733
12734         # return -EIO from OST
12735         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12736         RC=$?
12737         set_nodes_failloc "$(osts_nodes)" 0x0
12738         if [[ $RC -eq 0 ]]; then
12739                 error "Must return error due to dropped pages, rc=$RC"
12740         fi
12741
12742         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12743         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12744         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12745         if [[ $LOCKED -ne 0 ]]; then
12746                 error "Locked pages remain in cache, locked=$LOCKED"
12747         fi
12748
12749         # in recoverable error on OST we want resend and stay until it finished
12750         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12751                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12752         fi
12753
12754         rm -f $DIR/$tfile
12755         echo "No pages locked after fsync"
12756
12757         return 0
12758 }
12759 run_test 118j "Simulate unrecoverable OST side error =========="
12760
12761 test_118k()
12762 {
12763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12764         remote_ost_nodsh && skip "remote OSTs with nodsh"
12765
12766         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12767         set_nodes_failloc "$(osts_nodes)" 0x20e
12768         test_mkdir $DIR/$tdir
12769
12770         for ((i=0;i<10;i++)); do
12771                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12772                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12773                 SLEEPPID=$!
12774                 sleep 0.500s
12775                 kill $SLEEPPID
12776                 wait $SLEEPPID
12777         done
12778
12779         set_nodes_failloc "$(osts_nodes)" 0
12780         rm -rf $DIR/$tdir
12781 }
12782 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12783
12784 test_118l() # LU-646
12785 {
12786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12787
12788         test_mkdir $DIR/$tdir
12789         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12790         rm -rf $DIR/$tdir
12791 }
12792 run_test 118l "fsync dir"
12793
12794 test_118m() # LU-3066
12795 {
12796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12797
12798         test_mkdir $DIR/$tdir
12799         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12800         rm -rf $DIR/$tdir
12801 }
12802 run_test 118m "fdatasync dir ========="
12803
12804 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12805
12806 test_118n()
12807 {
12808         local begin
12809         local end
12810
12811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12812         remote_ost_nodsh && skip "remote OSTs with nodsh"
12813
12814         # Sleep to avoid a cached response.
12815         #define OBD_STATFS_CACHE_SECONDS 1
12816         sleep 2
12817
12818         # Inject a 10 second delay in the OST_STATFS handler.
12819         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12820         set_nodes_failloc "$(osts_nodes)" 0x242
12821
12822         begin=$SECONDS
12823         stat --file-system $MOUNT > /dev/null
12824         end=$SECONDS
12825
12826         set_nodes_failloc "$(osts_nodes)" 0
12827
12828         if ((end - begin > 20)); then
12829             error "statfs took $((end - begin)) seconds, expected 10"
12830         fi
12831 }
12832 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12833
12834 test_119a() # bug 11737
12835 {
12836         BSIZE=$((512 * 1024))
12837         directio write $DIR/$tfile 0 1 $BSIZE
12838         # We ask to read two blocks, which is more than a file size.
12839         # directio will indicate an error when requested and actual
12840         # sizes aren't equeal (a normal situation in this case) and
12841         # print actual read amount.
12842         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12843         if [ "$NOB" != "$BSIZE" ]; then
12844                 error "read $NOB bytes instead of $BSIZE"
12845         fi
12846         rm -f $DIR/$tfile
12847 }
12848 run_test 119a "Short directIO read must return actual read amount"
12849
12850 test_119b() # bug 11737
12851 {
12852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12853
12854         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12855         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12856         sync
12857         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12858                 error "direct read failed"
12859         rm -f $DIR/$tfile
12860 }
12861 run_test 119b "Sparse directIO read must return actual read amount"
12862
12863 test_119c() # bug 13099
12864 {
12865         BSIZE=1048576
12866         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12867         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12868         rm -f $DIR/$tfile
12869 }
12870 run_test 119c "Testing for direct read hitting hole"
12871
12872 test_119d() # bug 15950
12873 {
12874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12875
12876         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12877         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12878         BSIZE=1048576
12879         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12880         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12881         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12882         lctl set_param fail_loc=0x40d
12883         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12884         pid_dio=$!
12885         sleep 1
12886         cat $DIR/$tfile > /dev/null &
12887         lctl set_param fail_loc=0
12888         pid_reads=$!
12889         wait $pid_dio
12890         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12891         sleep 2
12892         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12893         error "the read rpcs have not completed in 2s"
12894         rm -f $DIR/$tfile
12895         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12896 }
12897 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12898
12899 test_120a() {
12900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12901         remote_mds_nodsh && skip "remote MDS with nodsh"
12902         test_mkdir -i0 -c1 $DIR/$tdir
12903         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12904                 skip_env "no early lock cancel on server"
12905
12906         lru_resize_disable mdc
12907         lru_resize_disable osc
12908         cancel_lru_locks mdc
12909         # asynchronous object destroy at MDT could cause bl ast to client
12910         cancel_lru_locks osc
12911
12912         stat $DIR/$tdir > /dev/null
12913         can1=$(do_facet mds1 \
12914                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12915                awk '/ldlm_cancel/ {print $2}')
12916         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12917                awk '/ldlm_bl_callback/ {print $2}')
12918         test_mkdir -i0 -c1 $DIR/$tdir/d1
12919         can2=$(do_facet mds1 \
12920                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12921                awk '/ldlm_cancel/ {print $2}')
12922         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12923                awk '/ldlm_bl_callback/ {print $2}')
12924         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12925         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12926         lru_resize_enable mdc
12927         lru_resize_enable osc
12928 }
12929 run_test 120a "Early Lock Cancel: mkdir test"
12930
12931 test_120b() {
12932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12933         remote_mds_nodsh && skip "remote MDS with nodsh"
12934         test_mkdir $DIR/$tdir
12935         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12936                 skip_env "no early lock cancel on server"
12937
12938         lru_resize_disable mdc
12939         lru_resize_disable osc
12940         cancel_lru_locks mdc
12941         stat $DIR/$tdir > /dev/null
12942         can1=$(do_facet $SINGLEMDS \
12943                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12944                awk '/ldlm_cancel/ {print $2}')
12945         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12946                awk '/ldlm_bl_callback/ {print $2}')
12947         touch $DIR/$tdir/f1
12948         can2=$(do_facet $SINGLEMDS \
12949                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12950                awk '/ldlm_cancel/ {print $2}')
12951         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12952                awk '/ldlm_bl_callback/ {print $2}')
12953         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12954         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12955         lru_resize_enable mdc
12956         lru_resize_enable osc
12957 }
12958 run_test 120b "Early Lock Cancel: create test"
12959
12960 test_120c() {
12961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12962         remote_mds_nodsh && skip "remote MDS with nodsh"
12963         test_mkdir -i0 -c1 $DIR/$tdir
12964         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12965                 skip "no early lock cancel on server"
12966
12967         lru_resize_disable mdc
12968         lru_resize_disable osc
12969         test_mkdir -i0 -c1 $DIR/$tdir/d1
12970         test_mkdir -i0 -c1 $DIR/$tdir/d2
12971         touch $DIR/$tdir/d1/f1
12972         cancel_lru_locks mdc
12973         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12974         can1=$(do_facet mds1 \
12975                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12976                awk '/ldlm_cancel/ {print $2}')
12977         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12978                awk '/ldlm_bl_callback/ {print $2}')
12979         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12980         can2=$(do_facet mds1 \
12981                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12982                awk '/ldlm_cancel/ {print $2}')
12983         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12984                awk '/ldlm_bl_callback/ {print $2}')
12985         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12986         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12987         lru_resize_enable mdc
12988         lru_resize_enable osc
12989 }
12990 run_test 120c "Early Lock Cancel: link test"
12991
12992 test_120d() {
12993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12994         remote_mds_nodsh && skip "remote MDS with nodsh"
12995         test_mkdir -i0 -c1 $DIR/$tdir
12996         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12997                 skip_env "no early lock cancel on server"
12998
12999         lru_resize_disable mdc
13000         lru_resize_disable osc
13001         touch $DIR/$tdir
13002         cancel_lru_locks mdc
13003         stat $DIR/$tdir > /dev/null
13004         can1=$(do_facet mds1 \
13005                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13006                awk '/ldlm_cancel/ {print $2}')
13007         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13008                awk '/ldlm_bl_callback/ {print $2}')
13009         chmod a+x $DIR/$tdir
13010         can2=$(do_facet mds1 \
13011                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13012                awk '/ldlm_cancel/ {print $2}')
13013         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13014                awk '/ldlm_bl_callback/ {print $2}')
13015         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13016         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13017         lru_resize_enable mdc
13018         lru_resize_enable osc
13019 }
13020 run_test 120d "Early Lock Cancel: setattr test"
13021
13022 test_120e() {
13023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13024         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13025                 skip_env "no early lock cancel on server"
13026         remote_mds_nodsh && skip "remote MDS with nodsh"
13027
13028         local dlmtrace_set=false
13029
13030         test_mkdir -i0 -c1 $DIR/$tdir
13031         lru_resize_disable mdc
13032         lru_resize_disable osc
13033         ! $LCTL get_param debug | grep -q dlmtrace &&
13034                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13035         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13036         cancel_lru_locks mdc
13037         cancel_lru_locks osc
13038         dd if=$DIR/$tdir/f1 of=/dev/null
13039         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13040         # XXX client can not do early lock cancel of OST lock
13041         # during unlink (LU-4206), so cancel osc lock now.
13042         sleep 2
13043         cancel_lru_locks osc
13044         can1=$(do_facet mds1 \
13045                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13046                awk '/ldlm_cancel/ {print $2}')
13047         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13048                awk '/ldlm_bl_callback/ {print $2}')
13049         unlink $DIR/$tdir/f1
13050         sleep 5
13051         can2=$(do_facet mds1 \
13052                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13053                awk '/ldlm_cancel/ {print $2}')
13054         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13055                awk '/ldlm_bl_callback/ {print $2}')
13056         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13057                 $LCTL dk $TMP/cancel.debug.txt
13058         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13059                 $LCTL dk $TMP/blocking.debug.txt
13060         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13061         lru_resize_enable mdc
13062         lru_resize_enable osc
13063 }
13064 run_test 120e "Early Lock Cancel: unlink test"
13065
13066 test_120f() {
13067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13068         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13069                 skip_env "no early lock cancel on server"
13070         remote_mds_nodsh && skip "remote MDS with nodsh"
13071
13072         test_mkdir -i0 -c1 $DIR/$tdir
13073         lru_resize_disable mdc
13074         lru_resize_disable osc
13075         test_mkdir -i0 -c1 $DIR/$tdir/d1
13076         test_mkdir -i0 -c1 $DIR/$tdir/d2
13077         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13078         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13079         cancel_lru_locks mdc
13080         cancel_lru_locks osc
13081         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13082         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13083         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13084         # XXX client can not do early lock cancel of OST lock
13085         # during rename (LU-4206), so cancel osc lock now.
13086         sleep 2
13087         cancel_lru_locks osc
13088         can1=$(do_facet mds1 \
13089                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13090                awk '/ldlm_cancel/ {print $2}')
13091         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13092                awk '/ldlm_bl_callback/ {print $2}')
13093         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13094         sleep 5
13095         can2=$(do_facet mds1 \
13096                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13097                awk '/ldlm_cancel/ {print $2}')
13098         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13099                awk '/ldlm_bl_callback/ {print $2}')
13100         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13101         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13102         lru_resize_enable mdc
13103         lru_resize_enable osc
13104 }
13105 run_test 120f "Early Lock Cancel: rename test"
13106
13107 test_120g() {
13108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13109         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13110                 skip_env "no early lock cancel on server"
13111         remote_mds_nodsh && skip "remote MDS with nodsh"
13112
13113         lru_resize_disable mdc
13114         lru_resize_disable osc
13115         count=10000
13116         echo create $count files
13117         test_mkdir $DIR/$tdir
13118         cancel_lru_locks mdc
13119         cancel_lru_locks osc
13120         t0=$(date +%s)
13121
13122         can0=$(do_facet $SINGLEMDS \
13123                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13124                awk '/ldlm_cancel/ {print $2}')
13125         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13126                awk '/ldlm_bl_callback/ {print $2}')
13127         createmany -o $DIR/$tdir/f $count
13128         sync
13129         can1=$(do_facet $SINGLEMDS \
13130                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13131                awk '/ldlm_cancel/ {print $2}')
13132         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13133                awk '/ldlm_bl_callback/ {print $2}')
13134         t1=$(date +%s)
13135         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13136         echo rm $count files
13137         rm -r $DIR/$tdir
13138         sync
13139         can2=$(do_facet $SINGLEMDS \
13140                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13141                awk '/ldlm_cancel/ {print $2}')
13142         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13143                awk '/ldlm_bl_callback/ {print $2}')
13144         t2=$(date +%s)
13145         echo total: $count removes in $((t2-t1))
13146         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13147         sleep 2
13148         # wait for commitment of removal
13149         lru_resize_enable mdc
13150         lru_resize_enable osc
13151 }
13152 run_test 120g "Early Lock Cancel: performance test"
13153
13154 test_121() { #bug #10589
13155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13156
13157         rm -rf $DIR/$tfile
13158         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13159 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13160         lctl set_param fail_loc=0x310
13161         cancel_lru_locks osc > /dev/null
13162         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13163         lctl set_param fail_loc=0
13164         [[ $reads -eq $writes ]] ||
13165                 error "read $reads blocks, must be $writes blocks"
13166 }
13167 run_test 121 "read cancel race ========="
13168
13169 test_123a_base() { # was test 123, statahead(bug 11401)
13170         local lsx="$1"
13171
13172         SLOWOK=0
13173         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13174                 log "testing UP system. Performance may be lower than expected."
13175                 SLOWOK=1
13176         fi
13177         running_in_vm && SLOWOK=1
13178
13179         rm -rf $DIR/$tdir
13180         test_mkdir $DIR/$tdir
13181         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13182         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13183         MULT=10
13184         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13185                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13186
13187                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13188                 lctl set_param -n llite.*.statahead_max 0
13189                 lctl get_param llite.*.statahead_max
13190                 cancel_lru_locks mdc
13191                 cancel_lru_locks osc
13192                 stime=$(date +%s)
13193                 time $lsx $DIR/$tdir | wc -l
13194                 etime=$(date +%s)
13195                 delta=$((etime - stime))
13196                 log "$lsx $i files without statahead: $delta sec"
13197                 lctl set_param llite.*.statahead_max=$max
13198
13199                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13200                          awk '/statahead.wrong:/ { print $NF }')
13201                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13202                 cancel_lru_locks mdc
13203                 cancel_lru_locks osc
13204                 stime=$(date +%s)
13205                 time $lsx $DIR/$tdir | wc -l
13206                 etime=$(date +%s)
13207                 delta_sa=$((etime - stime))
13208                 log "$lsx $i files with statahead: $delta_sa sec"
13209                 lctl get_param -n llite.*.statahead_stats
13210                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13211                          awk '/statahead.wrong:/ { print $NF }')
13212
13213                 [[ $swrong -lt $ewrong ]] &&
13214                         log "statahead was stopped, maybe too many locks held!"
13215                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13216
13217                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13218                         max=$(lctl get_param -n llite.*.statahead_max |
13219                                 head -n 1)
13220                         lctl set_param -n llite.*.statahead_max 0
13221                         lctl get_param llite.*.statahead_max
13222                         cancel_lru_locks mdc
13223                         cancel_lru_locks osc
13224                         stime=$(date +%s)
13225                         time $lsx $DIR/$tdir | wc -l
13226                         etime=$(date +%s)
13227                         delta=$((etime - stime))
13228                         log "$lsx $i files again without statahead: $delta sec"
13229                         lctl set_param llite.*.statahead_max=$max
13230                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13231                                 if [ $SLOWOK -eq 0 ]; then
13232                                         error "$lsx $i files is slower with statahead!"
13233                                 else
13234                                         log "$lsx $i files is slower with statahead!"
13235                                 fi
13236                                 break
13237                         fi
13238                 fi
13239
13240                 [ $delta -gt 20 ] && break
13241                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13242                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13243         done
13244         log "$lsx done"
13245
13246         stime=$(date +%s)
13247         rm -r $DIR/$tdir
13248         sync
13249         etime=$(date +%s)
13250         delta=$((etime - stime))
13251         log "rm -r $DIR/$tdir/: $delta seconds"
13252         log "rm done"
13253         lctl get_param -n llite.*.statahead_stats
13254 }
13255
13256 test_123aa() {
13257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13258
13259         test_123a_base "ls -l"
13260 }
13261 run_test 123aa "verify statahead work"
13262
13263 test_123ab() {
13264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13265
13266         statx_supported || skip_env "Test must be statx() syscall supported"
13267
13268         test_123a_base "$STATX -l"
13269 }
13270 run_test 123ab "verify statahead work by using statx"
13271
13272 test_123ac() {
13273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13274
13275         statx_supported || skip_env "Test must be statx() syscall supported"
13276
13277         local rpcs_before
13278         local rpcs_after
13279         local agl_before
13280         local agl_after
13281
13282         cancel_lru_locks $OSC
13283         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13284         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13285                      awk '/agl.total:/ { print $NF }')
13286         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13287         test_123a_base "$STATX --cached=always -D"
13288         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13289                     awk '/agl.total:/ { print $NF }')
13290         [ $agl_before -eq $agl_after ] ||
13291                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13292         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13293         [ $rpcs_after -eq $rpcs_before ] ||
13294                 error "$STATX should not send glimpse RPCs to $OSC"
13295 }
13296 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13297
13298 test_123b () { # statahead(bug 15027)
13299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13300
13301         test_mkdir $DIR/$tdir
13302         createmany -o $DIR/$tdir/$tfile-%d 1000
13303
13304         cancel_lru_locks mdc
13305         cancel_lru_locks osc
13306
13307 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13308         lctl set_param fail_loc=0x80000803
13309         ls -lR $DIR/$tdir > /dev/null
13310         log "ls done"
13311         lctl set_param fail_loc=0x0
13312         lctl get_param -n llite.*.statahead_stats
13313         rm -r $DIR/$tdir
13314         sync
13315
13316 }
13317 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13318
13319 test_123c() {
13320         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13321
13322         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13323         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13324         touch $DIR/$tdir.1/{1..3}
13325         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13326
13327         remount_client $MOUNT
13328
13329         $MULTIOP $DIR/$tdir.0 Q
13330
13331         # let statahead to complete
13332         ls -l $DIR/$tdir.0 > /dev/null
13333
13334         testid=$(echo $TESTNAME | tr '_' ' ')
13335         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13336                 error "statahead warning" || true
13337 }
13338 run_test 123c "Can not initialize inode warning on DNE statahead"
13339
13340 test_123d() {
13341         local num=100
13342         local swrong
13343         local ewrong
13344
13345         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13346         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13347                 error "setdirstripe $DIR/$tdir failed"
13348         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13349         remount_client $MOUNT
13350         $LCTL get_param llite.*.statahead_max
13351         $LCTL set_param llite.*.statahead_stats=0 ||
13352                 error "clear statahead_stats failed"
13353         swrong=$(lctl get_param -n llite.*.statahead_stats |
13354                  awk '/statahead.wrong:/ { print $NF }')
13355         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13356         # wait for statahead thread finished to update hit/miss stats.
13357         sleep 1
13358         $LCTL get_param -n llite.*.statahead_stats
13359         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13360                  awk '/statahead.wrong:/ { print $NF }')
13361         (( $swrong == $ewrong )) ||
13362                 log "statahead was stopped, maybe too many locks held!"
13363 }
13364 run_test 123d "Statahead on striped directories works correctly"
13365
13366 test_124a() {
13367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13368         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13369                 skip_env "no lru resize on server"
13370
13371         local NR=2000
13372
13373         test_mkdir $DIR/$tdir
13374
13375         log "create $NR files at $DIR/$tdir"
13376         createmany -o $DIR/$tdir/f $NR ||
13377                 error "failed to create $NR files in $DIR/$tdir"
13378
13379         cancel_lru_locks mdc
13380         ls -l $DIR/$tdir > /dev/null
13381
13382         local NSDIR=""
13383         local LRU_SIZE=0
13384         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13385                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13386                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13387                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13388                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13389                         log "NSDIR=$NSDIR"
13390                         log "NS=$(basename $NSDIR)"
13391                         break
13392                 fi
13393         done
13394
13395         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13396                 skip "Not enough cached locks created!"
13397         fi
13398         log "LRU=$LRU_SIZE"
13399
13400         local SLEEP=30
13401
13402         # We know that lru resize allows one client to hold $LIMIT locks
13403         # for 10h. After that locks begin to be killed by client.
13404         local MAX_HRS=10
13405         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13406         log "LIMIT=$LIMIT"
13407         if [ $LIMIT -lt $LRU_SIZE ]; then
13408                 skip "Limit is too small $LIMIT"
13409         fi
13410
13411         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13412         # killing locks. Some time was spent for creating locks. This means
13413         # that up to the moment of sleep finish we must have killed some of
13414         # them (10-100 locks). This depends on how fast ther were created.
13415         # Many of them were touched in almost the same moment and thus will
13416         # be killed in groups.
13417         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13418
13419         # Use $LRU_SIZE_B here to take into account real number of locks
13420         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13421         local LRU_SIZE_B=$LRU_SIZE
13422         log "LVF=$LVF"
13423         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13424         log "OLD_LVF=$OLD_LVF"
13425         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13426
13427         # Let's make sure that we really have some margin. Client checks
13428         # cached locks every 10 sec.
13429         SLEEP=$((SLEEP+20))
13430         log "Sleep ${SLEEP} sec"
13431         local SEC=0
13432         while ((SEC<$SLEEP)); do
13433                 echo -n "..."
13434                 sleep 5
13435                 SEC=$((SEC+5))
13436                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13437                 echo -n "$LRU_SIZE"
13438         done
13439         echo ""
13440         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13441         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13442
13443         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13444                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13445                 unlinkmany $DIR/$tdir/f $NR
13446                 return
13447         }
13448
13449         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13450         log "unlink $NR files at $DIR/$tdir"
13451         unlinkmany $DIR/$tdir/f $NR
13452 }
13453 run_test 124a "lru resize ======================================="
13454
13455 get_max_pool_limit()
13456 {
13457         local limit=$($LCTL get_param \
13458                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13459         local max=0
13460         for l in $limit; do
13461                 if [[ $l -gt $max ]]; then
13462                         max=$l
13463                 fi
13464         done
13465         echo $max
13466 }
13467
13468 test_124b() {
13469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13470         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13471                 skip_env "no lru resize on server"
13472
13473         LIMIT=$(get_max_pool_limit)
13474
13475         NR=$(($(default_lru_size)*20))
13476         if [[ $NR -gt $LIMIT ]]; then
13477                 log "Limit lock number by $LIMIT locks"
13478                 NR=$LIMIT
13479         fi
13480
13481         IFree=$(mdsrate_inodes_available)
13482         if [ $IFree -lt $NR ]; then
13483                 log "Limit lock number by $IFree inodes"
13484                 NR=$IFree
13485         fi
13486
13487         lru_resize_disable mdc
13488         test_mkdir -p $DIR/$tdir/disable_lru_resize
13489
13490         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13491         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13492         cancel_lru_locks mdc
13493         stime=`date +%s`
13494         PID=""
13495         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13496         PID="$PID $!"
13497         sleep 2
13498         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13499         PID="$PID $!"
13500         sleep 2
13501         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13502         PID="$PID $!"
13503         wait $PID
13504         etime=`date +%s`
13505         nolruresize_delta=$((etime-stime))
13506         log "ls -la time: $nolruresize_delta seconds"
13507         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13508         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13509
13510         lru_resize_enable mdc
13511         test_mkdir -p $DIR/$tdir/enable_lru_resize
13512
13513         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13514         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13515         cancel_lru_locks mdc
13516         stime=`date +%s`
13517         PID=""
13518         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13519         PID="$PID $!"
13520         sleep 2
13521         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13522         PID="$PID $!"
13523         sleep 2
13524         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13525         PID="$PID $!"
13526         wait $PID
13527         etime=`date +%s`
13528         lruresize_delta=$((etime-stime))
13529         log "ls -la time: $lruresize_delta seconds"
13530         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13531
13532         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13533                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13534         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13535                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13536         else
13537                 log "lru resize performs the same with no lru resize"
13538         fi
13539         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13540 }
13541 run_test 124b "lru resize (performance test) ======================="
13542
13543 test_124c() {
13544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13545         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13546                 skip_env "no lru resize on server"
13547
13548         # cache ununsed locks on client
13549         local nr=100
13550         cancel_lru_locks mdc
13551         test_mkdir $DIR/$tdir
13552         createmany -o $DIR/$tdir/f $nr ||
13553                 error "failed to create $nr files in $DIR/$tdir"
13554         ls -l $DIR/$tdir > /dev/null
13555
13556         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13557         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13558         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13559         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13560         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13561
13562         # set lru_max_age to 1 sec
13563         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13564         echo "sleep $((recalc_p * 2)) seconds..."
13565         sleep $((recalc_p * 2))
13566
13567         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13568         # restore lru_max_age
13569         $LCTL set_param -n $nsdir.lru_max_age $max_age
13570         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13571         unlinkmany $DIR/$tdir/f $nr
13572 }
13573 run_test 124c "LRUR cancel very aged locks"
13574
13575 test_124d() {
13576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13577         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13578                 skip_env "no lru resize on server"
13579
13580         # cache ununsed locks on client
13581         local nr=100
13582
13583         lru_resize_disable mdc
13584         stack_trap "lru_resize_enable mdc" EXIT
13585
13586         cancel_lru_locks mdc
13587
13588         # asynchronous object destroy at MDT could cause bl ast to client
13589         test_mkdir $DIR/$tdir
13590         createmany -o $DIR/$tdir/f $nr ||
13591                 error "failed to create $nr files in $DIR/$tdir"
13592         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13593
13594         ls -l $DIR/$tdir > /dev/null
13595
13596         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13597         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13598         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13599         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13600
13601         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13602
13603         # set lru_max_age to 1 sec
13604         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13605         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13606
13607         echo "sleep $((recalc_p * 2)) seconds..."
13608         sleep $((recalc_p * 2))
13609
13610         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13611
13612         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13613 }
13614 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13615
13616 test_125() { # 13358
13617         $LCTL get_param -n llite.*.client_type | grep -q local ||
13618                 skip "must run as local client"
13619         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13620                 skip_env "must have acl enabled"
13621         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13622
13623         test_mkdir $DIR/$tdir
13624         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13625         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13626                 error "setfacl $DIR/$tdir failed"
13627         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13628 }
13629 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13630
13631 test_126() { # bug 12829/13455
13632         $GSS && skip_env "must run as gss disabled"
13633         $LCTL get_param -n llite.*.client_type | grep -q local ||
13634                 skip "must run as local client"
13635         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13636
13637         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13638         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13639         rm -f $DIR/$tfile
13640         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13641 }
13642 run_test 126 "check that the fsgid provided by the client is taken into account"
13643
13644 test_127a() { # bug 15521
13645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13646         local name count samp unit min max sum sumsq
13647
13648         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13649         echo "stats before reset"
13650         $LCTL get_param osc.*.stats
13651         $LCTL set_param osc.*.stats=0
13652         local fsize=$((2048 * 1024))
13653
13654         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13655         cancel_lru_locks osc
13656         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13657
13658         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13659         stack_trap "rm -f $TMP/$tfile.tmp"
13660         while read name count samp unit min max sum sumsq; do
13661                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13662                 [ ! $min ] && error "Missing min value for $name proc entry"
13663                 eval $name=$count || error "Wrong proc format"
13664
13665                 case $name in
13666                 read_bytes|write_bytes)
13667                         [[ "$unit" =~ "bytes" ]] ||
13668                                 error "unit is not 'bytes': $unit"
13669                         (( $min >= 4096 )) || error "min is too small: $min"
13670                         (( $min <= $fsize )) || error "min is too big: $min"
13671                         (( $max >= 4096 )) || error "max is too small: $max"
13672                         (( $max <= $fsize )) || error "max is too big: $max"
13673                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13674                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13675                                 error "sumsquare is too small: $sumsq"
13676                         (( $sumsq <= $fsize * $fsize )) ||
13677                                 error "sumsquare is too big: $sumsq"
13678                         ;;
13679                 ost_read|ost_write)
13680                         [[ "$unit" =~ "usec" ]] ||
13681                                 error "unit is not 'usec': $unit"
13682                         ;;
13683                 *)      ;;
13684                 esac
13685         done < $DIR/$tfile.tmp
13686
13687         #check that we actually got some stats
13688         [ "$read_bytes" ] || error "Missing read_bytes stats"
13689         [ "$write_bytes" ] || error "Missing write_bytes stats"
13690         [ "$read_bytes" != 0 ] || error "no read done"
13691         [ "$write_bytes" != 0 ] || error "no write done"
13692 }
13693 run_test 127a "verify the client stats are sane"
13694
13695 test_127b() { # bug LU-333
13696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13697         local name count samp unit min max sum sumsq
13698
13699         echo "stats before reset"
13700         $LCTL get_param llite.*.stats
13701         $LCTL set_param llite.*.stats=0
13702
13703         # perform 2 reads and writes so MAX is different from SUM.
13704         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13705         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13706         cancel_lru_locks osc
13707         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13708         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13709
13710         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13711         stack_trap "rm -f $TMP/$tfile.tmp"
13712         while read name count samp unit min max sum sumsq; do
13713                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13714                 eval $name=$count || error "Wrong proc format"
13715
13716                 case $name in
13717                 read_bytes|write_bytes)
13718                         [[ "$unit" =~ "bytes" ]] ||
13719                                 error "unit is not 'bytes': $unit"
13720                         (( $count == 2 )) || error "count is not 2: $count"
13721                         (( $min == $PAGE_SIZE )) ||
13722                                 error "min is not $PAGE_SIZE: $min"
13723                         (( $max == $PAGE_SIZE )) ||
13724                                 error "max is not $PAGE_SIZE: $max"
13725                         (( $sum == $PAGE_SIZE * 2 )) ||
13726                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13727                         ;;
13728                 read|write)
13729                         [[ "$unit" =~ "usec" ]] ||
13730                                 error "unit is not 'usec': $unit"
13731                         ;;
13732                 *)      ;;
13733                 esac
13734         done < $TMP/$tfile.tmp
13735
13736         #check that we actually got some stats
13737         [ "$read_bytes" ] || error "Missing read_bytes stats"
13738         [ "$write_bytes" ] || error "Missing write_bytes stats"
13739         [ "$read_bytes" != 0 ] || error "no read done"
13740         [ "$write_bytes" != 0 ] || error "no write done"
13741 }
13742 run_test 127b "verify the llite client stats are sane"
13743
13744 test_127c() { # LU-12394
13745         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13746         local size
13747         local bsize
13748         local reads
13749         local writes
13750         local count
13751
13752         $LCTL set_param llite.*.extents_stats=1
13753         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13754
13755         # Use two stripes so there is enough space in default config
13756         $LFS setstripe -c 2 $DIR/$tfile
13757
13758         # Extent stats start at 0-4K and go in power of two buckets
13759         # LL_HIST_START = 12 --> 2^12 = 4K
13760         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13761         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13762         # small configs
13763         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13764                 do
13765                 # Write and read, 2x each, second time at a non-zero offset
13766                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13767                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13768                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13769                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13770                 rm -f $DIR/$tfile
13771         done
13772
13773         $LCTL get_param llite.*.extents_stats
13774
13775         count=2
13776         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13777                 do
13778                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13779                                 grep -m 1 $bsize)
13780                 reads=$(echo $bucket | awk '{print $5}')
13781                 writes=$(echo $bucket | awk '{print $9}')
13782                 [ "$reads" -eq $count ] ||
13783                         error "$reads reads in < $bsize bucket, expect $count"
13784                 [ "$writes" -eq $count ] ||
13785                         error "$writes writes in < $bsize bucket, expect $count"
13786         done
13787
13788         # Test mmap write and read
13789         $LCTL set_param llite.*.extents_stats=c
13790         size=512
13791         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13792         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13793         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13794
13795         $LCTL get_param llite.*.extents_stats
13796
13797         count=$(((size*1024) / PAGE_SIZE))
13798
13799         bsize=$((2 * PAGE_SIZE / 1024))K
13800
13801         bucket=$($LCTL get_param -n llite.*.extents_stats |
13802                         grep -m 1 $bsize)
13803         reads=$(echo $bucket | awk '{print $5}')
13804         writes=$(echo $bucket | awk '{print $9}')
13805         # mmap writes fault in the page first, creating an additonal read
13806         [ "$reads" -eq $((2 * count)) ] ||
13807                 error "$reads reads in < $bsize bucket, expect $count"
13808         [ "$writes" -eq $count ] ||
13809                 error "$writes writes in < $bsize bucket, expect $count"
13810 }
13811 run_test 127c "test llite extent stats with regular & mmap i/o"
13812
13813 test_128() { # bug 15212
13814         touch $DIR/$tfile
13815         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13816                 find $DIR/$tfile
13817                 find $DIR/$tfile
13818         EOF
13819
13820         result=$(grep error $TMP/$tfile.log)
13821         rm -f $DIR/$tfile $TMP/$tfile.log
13822         [ -z "$result" ] ||
13823                 error "consecutive find's under interactive lfs failed"
13824 }
13825 run_test 128 "interactive lfs for 2 consecutive find's"
13826
13827 set_dir_limits () {
13828         local mntdev
13829         local canondev
13830         local node
13831
13832         local ldproc=/proc/fs/ldiskfs
13833         local facets=$(get_facets MDS)
13834
13835         for facet in ${facets//,/ }; do
13836                 canondev=$(ldiskfs_canon \
13837                            *.$(convert_facet2label $facet).mntdev $facet)
13838                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13839                         ldproc=/sys/fs/ldiskfs
13840                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13841                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13842         done
13843 }
13844
13845 check_mds_dmesg() {
13846         local facets=$(get_facets MDS)
13847         for facet in ${facets//,/ }; do
13848                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13849         done
13850         return 1
13851 }
13852
13853 test_129() {
13854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13855         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13856                 skip "Need MDS version with at least 2.5.56"
13857         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13858                 skip_env "ldiskfs only test"
13859         fi
13860         remote_mds_nodsh && skip "remote MDS with nodsh"
13861
13862         local ENOSPC=28
13863         local has_warning=false
13864
13865         rm -rf $DIR/$tdir
13866         mkdir -p $DIR/$tdir
13867
13868         # block size of mds1
13869         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13870         set_dir_limits $maxsize $((maxsize * 6 / 8))
13871         stack_trap "set_dir_limits 0 0"
13872         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13873         local dirsize=$(stat -c%s "$DIR/$tdir")
13874         local nfiles=0
13875         while (( $dirsize <= $maxsize )); do
13876                 $MCREATE $DIR/$tdir/file_base_$nfiles
13877                 rc=$?
13878                 # check two errors:
13879                 # ENOSPC for ext4 max_dir_size, which has been used since
13880                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13881                 if (( rc == ENOSPC )); then
13882                         set_dir_limits 0 0
13883                         echo "rc=$rc returned as expected after $nfiles files"
13884
13885                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13886                                 error "create failed w/o dir size limit"
13887
13888                         # messages may be rate limited if test is run repeatedly
13889                         check_mds_dmesg '"is approaching max"' ||
13890                                 echo "warning message should be output"
13891                         check_mds_dmesg '"has reached max"' ||
13892                                 echo "reached message should be output"
13893
13894                         dirsize=$(stat -c%s "$DIR/$tdir")
13895
13896                         [[ $dirsize -ge $maxsize ]] && return 0
13897                         error "dirsize $dirsize < $maxsize after $nfiles files"
13898                 elif (( rc != 0 )); then
13899                         break
13900                 fi
13901                 nfiles=$((nfiles + 1))
13902                 dirsize=$(stat -c%s "$DIR/$tdir")
13903         done
13904
13905         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13906 }
13907 run_test 129 "test directory size limit ========================"
13908
13909 OLDIFS="$IFS"
13910 cleanup_130() {
13911         trap 0
13912         IFS="$OLDIFS"
13913 }
13914
13915 test_130a() {
13916         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13917         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
13918
13919         trap cleanup_130 EXIT RETURN
13920
13921         local fm_file=$DIR/$tfile
13922         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13923         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13924                 error "dd failed for $fm_file"
13925
13926         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
13927         filefrag -ves $fm_file
13928         local rc=$?
13929         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13930                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13931         (( $rc == 0 )) || error "filefrag $fm_file failed"
13932
13933         filefrag_op=$(filefrag -ve -k $fm_file |
13934                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13935         local lun=$($LFS getstripe -i $fm_file)
13936
13937         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
13938         IFS=$'\n'
13939         local tot_len=0
13940         for line in $filefrag_op; do
13941                 local frag_lun=$(echo $line | cut -d: -f5)
13942                 local ext_len=$(echo $line | cut -d: -f4)
13943
13944                 if (( $frag_lun != $lun )); then
13945                         error "FIEMAP on 1-stripe file($fm_file) failed"
13946                         return
13947                 fi
13948                 (( tot_len += ext_len ))
13949         done
13950
13951         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13952                 error "FIEMAP on 1-stripe file($fm_file) failed"
13953                 return
13954         fi
13955
13956         echo "FIEMAP on single striped file succeeded"
13957 }
13958 run_test 130a "FIEMAP (1-stripe file)"
13959
13960 test_130b() {
13961         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13962
13963         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
13964         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
13965         [[ "$ost1_FSTYPE" != "zfs" ]] ||
13966                 skip "LU-1941: FIEMAP unimplemented on ZFS"
13967
13968         trap cleanup_130 EXIT RETURN
13969
13970         local fm_file=$DIR/$tfile
13971         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13972                 error "setstripe on $fm_file"
13973
13974         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13975                 error "dd failed on $fm_file"
13976
13977         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13978         filefrag_op=$(filefrag -ve -k $fm_file |
13979                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13980
13981         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
13982                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13983
13984         IFS=$'\n'
13985         local tot_len=0
13986         local num_luns=1
13987
13988         for line in $filefrag_op; do
13989                 local frag_lun=$(echo $line | cut -d: -f5 |
13990                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13991                 local ext_len=$(echo $line | cut -d: -f4)
13992                 if (( $frag_lun != $last_lun )); then
13993                         if (( tot_len != 1024 )); then
13994                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
13995                                 return
13996                         else
13997                                 (( num_luns += 1 ))
13998                                 tot_len=0
13999                         fi
14000                 fi
14001                 (( tot_len += ext_len ))
14002                 last_lun=$frag_lun
14003         done
14004         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14005                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14006                 return
14007         fi
14008
14009         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14010 }
14011 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14012
14013 test_130c() {
14014         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14015
14016         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14017         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14018         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14019                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14020
14021         trap cleanup_130 EXIT RETURN
14022
14023         local fm_file=$DIR/$tfile
14024         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14025
14026         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14027                 error "dd failed on $fm_file"
14028
14029         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14030         filefrag_op=$(filefrag -ve -k $fm_file |
14031                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14032
14033         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14034                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14035
14036         IFS=$'\n'
14037         local tot_len=0
14038         local num_luns=1
14039         for line in $filefrag_op; do
14040                 local frag_lun=$(echo $line | cut -d: -f5 |
14041                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14042                 local ext_len=$(echo $line | cut -d: -f4)
14043                 if (( $frag_lun != $last_lun )); then
14044                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14045                         if (( logical != 512 )); then
14046                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14047                                 return
14048                         fi
14049                         if (( tot_len != 512 )); then
14050                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14051                                 return
14052                         else
14053                                 (( num_luns += 1 ))
14054                                 tot_len=0
14055                         fi
14056                 fi
14057                 (( tot_len += ext_len ))
14058                 last_lun=$frag_lun
14059         done
14060         if (( num_luns != 2 || tot_len != 512 )); then
14061                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14062                 return
14063         fi
14064
14065         echo "FIEMAP on 2-stripe file with hole succeeded"
14066 }
14067 run_test 130c "FIEMAP (2-stripe file with hole)"
14068
14069 test_130d() {
14070         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14071
14072         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14073         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14074         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14075                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14076
14077         trap cleanup_130 EXIT RETURN
14078
14079         local fm_file=$DIR/$tfile
14080         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14081                         error "setstripe on $fm_file"
14082
14083         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14084         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14085                 error "dd failed on $fm_file"
14086
14087         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14088         filefrag_op=$(filefrag -ve -k $fm_file |
14089                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14090
14091         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14092                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14093
14094         IFS=$'\n'
14095         local tot_len=0
14096         local num_luns=1
14097         for line in $filefrag_op; do
14098                 local frag_lun=$(echo $line | cut -d: -f5 |
14099                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14100                 local ext_len=$(echo $line | cut -d: -f4)
14101                 if (( $frag_lun != $last_lun )); then
14102                         if (( tot_len != 1024 )); then
14103                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14104                                 return
14105                         else
14106                                 (( num_luns += 1 ))
14107                                 local tot_len=0
14108                         fi
14109                 fi
14110                 (( tot_len += ext_len ))
14111                 last_lun=$frag_lun
14112         done
14113         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14114                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14115                 return
14116         fi
14117
14118         echo "FIEMAP on N-stripe file succeeded"
14119 }
14120 run_test 130d "FIEMAP (N-stripe file)"
14121
14122 test_130e() {
14123         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14124
14125         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14126         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14127         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14128                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14129
14130         trap cleanup_130 EXIT RETURN
14131
14132         local fm_file=$DIR/$tfile
14133         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14134
14135         local num_blks=512
14136         local expected_len=$(( (num_blks / 2) * 64 ))
14137         for ((i = 0; i < $num_blks; i++)); do
14138                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14139                         conv=notrunc > /dev/null 2>&1
14140         done
14141
14142         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14143         filefrag_op=$(filefrag -ve -k $fm_file |
14144                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14145
14146         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14147
14148         IFS=$'\n'
14149         local tot_len=0
14150         local num_luns=1
14151         for line in $filefrag_op; do
14152                 local frag_lun=$(echo $line | cut -d: -f5)
14153                 local ext_len=$(echo $line | cut -d: -f4)
14154                 if (( $frag_lun != $last_lun )); then
14155                         if (( tot_len != $expected_len )); then
14156                                 error "OST$last_lun $tot_len != $expected_len"
14157                         else
14158                                 (( num_luns += 1 ))
14159                                 tot_len=0
14160                         fi
14161                 fi
14162                 (( tot_len += ext_len ))
14163                 last_lun=$frag_lun
14164         done
14165         if (( num_luns != 2 || tot_len != $expected_len )); then
14166                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14167         fi
14168
14169         echo "FIEMAP with continuation calls succeeded"
14170 }
14171 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14172
14173 test_130f() {
14174         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14175         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14176         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14177                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14178
14179         local fm_file=$DIR/$tfile
14180         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14181                 error "multiop create with lov_delay_create on $fm_file"
14182
14183         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14184         filefrag_extents=$(filefrag -vek $fm_file |
14185                            awk '/extents? found/ { print $2 }')
14186         if (( $filefrag_extents != 0 )); then
14187                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14188         fi
14189
14190         rm -f $fm_file
14191 }
14192 run_test 130f "FIEMAP (unstriped file)"
14193
14194 test_130g() {
14195         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14196                 skip "Need MDS version with at least 2.12.53 for overstriping"
14197         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14198         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14199         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14200                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14201
14202         local file=$DIR/$tfile
14203         local nr=$((OSTCOUNT * 100))
14204
14205         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14206
14207         stack_trap "rm -f $file"
14208         dd if=/dev/zero of=$file count=$nr bs=1M
14209         sync
14210         nr=$($LFS getstripe -c $file)
14211
14212         local extents=$(filefrag -v $file |
14213                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14214
14215         echo "filefrag list $extents extents in file with stripecount $nr"
14216         if (( extents < nr )); then
14217                 $LFS getstripe $file
14218                 filefrag -v $file
14219                 error "filefrag printed $extents < $nr extents"
14220         fi
14221 }
14222 run_test 130g "FIEMAP (overstripe file)"
14223
14224 # Test for writev/readv
14225 test_131a() {
14226         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14227                 error "writev test failed"
14228         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14229                 error "readv failed"
14230         rm -f $DIR/$tfile
14231 }
14232 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14233
14234 test_131b() {
14235         local fsize=$((524288 + 1048576 + 1572864))
14236         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14237                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14238                         error "append writev test failed"
14239
14240         ((fsize += 1572864 + 1048576))
14241         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14242                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14243                         error "append writev test failed"
14244         rm -f $DIR/$tfile
14245 }
14246 run_test 131b "test append writev"
14247
14248 test_131c() {
14249         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14250         error "NOT PASS"
14251 }
14252 run_test 131c "test read/write on file w/o objects"
14253
14254 test_131d() {
14255         rwv -f $DIR/$tfile -w -n 1 1572864
14256         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14257         if [ "$NOB" != 1572864 ]; then
14258                 error "Short read filed: read $NOB bytes instead of 1572864"
14259         fi
14260         rm -f $DIR/$tfile
14261 }
14262 run_test 131d "test short read"
14263
14264 test_131e() {
14265         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14266         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14267         error "read hitting hole failed"
14268         rm -f $DIR/$tfile
14269 }
14270 run_test 131e "test read hitting hole"
14271
14272 check_stats() {
14273         local facet=$1
14274         local op=$2
14275         local want=${3:-0}
14276         local res
14277
14278         # open             11 samples [usecs] 468 4793 13658 35791898
14279         case $facet in
14280         mds*) res=($(do_facet $facet \
14281                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14282                  ;;
14283         ost*) res=($(do_facet $facet \
14284                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14285                  ;;
14286         *) error "Wrong facet '$facet'" ;;
14287         esac
14288         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14289         # if $want is zero, it means any stat increment is ok.
14290         if (( $want > 0 )); then
14291                 local count=${res[1]}
14292
14293                 if (( $count != $want )); then
14294                         if [[ $facet =~ "mds" ]]; then
14295                                 do_nodes $(comma_list $(mdts_nodes)) \
14296                                         $LCTL get_param mdt.*.md_stats
14297                         else
14298                                 do_nodes $(comma_list $(osts-nodes)) \
14299                                         $LCTL get_param obdfilter.*.stats
14300                         fi
14301                         error "The $op counter on $facet is $count, not $want"
14302                 fi
14303         fi
14304 }
14305
14306 test_133a() {
14307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14308         remote_ost_nodsh && skip "remote OST with nodsh"
14309         remote_mds_nodsh && skip "remote MDS with nodsh"
14310         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14311                 skip_env "MDS doesn't support rename stats"
14312
14313         local testdir=$DIR/${tdir}/stats_testdir
14314
14315         mkdir -p $DIR/${tdir}
14316
14317         # clear stats.
14318         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14319         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14320
14321         # verify mdt stats first.
14322         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14323         check_stats $SINGLEMDS "mkdir" 1
14324
14325         # clear "open" from "lfs mkdir" above
14326         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14327         touch ${testdir}/${tfile} || error "touch failed"
14328         check_stats $SINGLEMDS "open" 1
14329         check_stats $SINGLEMDS "close" 1
14330         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14331                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14332                 check_stats $SINGLEMDS "mknod" 2
14333         }
14334         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14335         check_stats $SINGLEMDS "unlink" 1
14336         rm -f ${testdir}/${tfile} || error "file remove failed"
14337         check_stats $SINGLEMDS "unlink" 2
14338
14339         # remove working dir and check mdt stats again.
14340         rmdir ${testdir} || error "rmdir failed"
14341         check_stats $SINGLEMDS "rmdir" 1
14342
14343         local testdir1=$DIR/${tdir}/stats_testdir1
14344         mkdir -p ${testdir}
14345         mkdir -p ${testdir1}
14346         touch ${testdir1}/test1
14347         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14348         check_stats $SINGLEMDS "crossdir_rename" 1
14349
14350         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14351         check_stats $SINGLEMDS "samedir_rename" 1
14352
14353         rm -rf $DIR/${tdir}
14354 }
14355 run_test 133a "Verifying MDT stats ========================================"
14356
14357 test_133b() {
14358         local res
14359
14360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14361         remote_ost_nodsh && skip "remote OST with nodsh"
14362         remote_mds_nodsh && skip "remote MDS with nodsh"
14363
14364         local testdir=$DIR/${tdir}/stats_testdir
14365
14366         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14367         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14368         touch ${testdir}/${tfile} || error "touch failed"
14369         cancel_lru_locks mdc
14370
14371         # clear stats.
14372         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14373         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14374
14375         # extra mdt stats verification.
14376         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14377         check_stats $SINGLEMDS "setattr" 1
14378         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14379         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14380         then            # LU-1740
14381                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14382                 check_stats $SINGLEMDS "getattr" 1
14383         fi
14384         rm -rf $DIR/${tdir}
14385
14386         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14387         # so the check below is not reliable
14388         [ $MDSCOUNT -eq 1 ] || return 0
14389
14390         # Sleep to avoid a cached response.
14391         #define OBD_STATFS_CACHE_SECONDS 1
14392         sleep 2
14393         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14394         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14395         $LFS df || error "lfs failed"
14396         check_stats $SINGLEMDS "statfs" 1
14397
14398         # check aggregated statfs (LU-10018)
14399         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14400                 return 0
14401         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14402                 return 0
14403         sleep 2
14404         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14405         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14406         df $DIR
14407         check_stats $SINGLEMDS "statfs" 1
14408
14409         # We want to check that the client didn't send OST_STATFS to
14410         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14411         # extra care is needed here.
14412         if remote_mds; then
14413                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14414                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14415
14416                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14417                 [ "$res" ] && error "OST got STATFS"
14418         fi
14419
14420         return 0
14421 }
14422 run_test 133b "Verifying extra MDT stats =================================="
14423
14424 test_133c() {
14425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14426         remote_ost_nodsh && skip "remote OST with nodsh"
14427         remote_mds_nodsh && skip "remote MDS with nodsh"
14428
14429         local testdir=$DIR/$tdir/stats_testdir
14430
14431         test_mkdir -p $testdir
14432
14433         # verify obdfilter stats.
14434         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14435         sync
14436         cancel_lru_locks osc
14437         wait_delete_completed
14438
14439         # clear stats.
14440         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14441         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14442
14443         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14444                 error "dd failed"
14445         sync
14446         cancel_lru_locks osc
14447         check_stats ost1 "write" 1
14448
14449         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14450         check_stats ost1 "read" 1
14451
14452         > $testdir/$tfile || error "truncate failed"
14453         check_stats ost1 "punch" 1
14454
14455         rm -f $testdir/$tfile || error "file remove failed"
14456         wait_delete_completed
14457         check_stats ost1 "destroy" 1
14458
14459         rm -rf $DIR/$tdir
14460 }
14461 run_test 133c "Verifying OST stats ========================================"
14462
14463 order_2() {
14464         local value=$1
14465         local orig=$value
14466         local order=1
14467
14468         while [ $value -ge 2 ]; do
14469                 order=$((order*2))
14470                 value=$((value/2))
14471         done
14472
14473         if [ $orig -gt $order ]; then
14474                 order=$((order*2))
14475         fi
14476         echo $order
14477 }
14478
14479 size_in_KMGT() {
14480     local value=$1
14481     local size=('K' 'M' 'G' 'T');
14482     local i=0
14483     local size_string=$value
14484
14485     while [ $value -ge 1024 ]; do
14486         if [ $i -gt 3 ]; then
14487             #T is the biggest unit we get here, if that is bigger,
14488             #just return XXXT
14489             size_string=${value}T
14490             break
14491         fi
14492         value=$((value >> 10))
14493         if [ $value -lt 1024 ]; then
14494             size_string=${value}${size[$i]}
14495             break
14496         fi
14497         i=$((i + 1))
14498     done
14499
14500     echo $size_string
14501 }
14502
14503 get_rename_size() {
14504         local size=$1
14505         local context=${2:-.}
14506         local sample=$(do_facet $SINGLEMDS $LCTL \
14507                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14508                 grep -A1 $context |
14509                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14510         echo $sample
14511 }
14512
14513 test_133d() {
14514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14515         remote_ost_nodsh && skip "remote OST with nodsh"
14516         remote_mds_nodsh && skip "remote MDS with nodsh"
14517         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14518                 skip_env "MDS doesn't support rename stats"
14519
14520         local testdir1=$DIR/${tdir}/stats_testdir1
14521         local testdir2=$DIR/${tdir}/stats_testdir2
14522         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14523
14524         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14525
14526         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14527         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14528
14529         createmany -o $testdir1/test 512 || error "createmany failed"
14530
14531         # check samedir rename size
14532         mv ${testdir1}/test0 ${testdir1}/test_0
14533
14534         local testdir1_size=$(ls -l $DIR/${tdir} |
14535                 awk '/stats_testdir1/ {print $5}')
14536         local testdir2_size=$(ls -l $DIR/${tdir} |
14537                 awk '/stats_testdir2/ {print $5}')
14538
14539         testdir1_size=$(order_2 $testdir1_size)
14540         testdir2_size=$(order_2 $testdir2_size)
14541
14542         testdir1_size=$(size_in_KMGT $testdir1_size)
14543         testdir2_size=$(size_in_KMGT $testdir2_size)
14544
14545         echo "source rename dir size: ${testdir1_size}"
14546         echo "target rename dir size: ${testdir2_size}"
14547
14548         local cmd="do_facet $SINGLEMDS $LCTL "
14549         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14550
14551         eval $cmd || error "$cmd failed"
14552         local samedir=$($cmd | grep 'same_dir')
14553         local same_sample=$(get_rename_size $testdir1_size)
14554         [ -z "$samedir" ] && error "samedir_rename_size count error"
14555         [[ $same_sample -eq 1 ]] ||
14556                 error "samedir_rename_size error $same_sample"
14557         echo "Check same dir rename stats success"
14558
14559         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14560
14561         # check crossdir rename size
14562         mv ${testdir1}/test_0 ${testdir2}/test_0
14563
14564         testdir1_size=$(ls -l $DIR/${tdir} |
14565                 awk '/stats_testdir1/ {print $5}')
14566         testdir2_size=$(ls -l $DIR/${tdir} |
14567                 awk '/stats_testdir2/ {print $5}')
14568
14569         testdir1_size=$(order_2 $testdir1_size)
14570         testdir2_size=$(order_2 $testdir2_size)
14571
14572         testdir1_size=$(size_in_KMGT $testdir1_size)
14573         testdir2_size=$(size_in_KMGT $testdir2_size)
14574
14575         echo "source rename dir size: ${testdir1_size}"
14576         echo "target rename dir size: ${testdir2_size}"
14577
14578         eval $cmd || error "$cmd failed"
14579         local crossdir=$($cmd | grep 'crossdir')
14580         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14581         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14582         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14583         [[ $src_sample -eq 1 ]] ||
14584                 error "crossdir_rename_size error $src_sample"
14585         [[ $tgt_sample -eq 1 ]] ||
14586                 error "crossdir_rename_size error $tgt_sample"
14587         echo "Check cross dir rename stats success"
14588         rm -rf $DIR/${tdir}
14589 }
14590 run_test 133d "Verifying rename_stats ========================================"
14591
14592 test_133e() {
14593         remote_mds_nodsh && skip "remote MDS with nodsh"
14594         remote_ost_nodsh && skip "remote OST with nodsh"
14595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14596
14597         local testdir=$DIR/${tdir}/stats_testdir
14598         local ctr f0 f1 bs=32768 count=42 sum
14599
14600         mkdir -p ${testdir} || error "mkdir failed"
14601
14602         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14603
14604         for ctr in {write,read}_bytes; do
14605                 sync
14606                 cancel_lru_locks osc
14607
14608                 do_facet ost1 $LCTL set_param -n \
14609                         "obdfilter.*.exports.clear=clear"
14610
14611                 if [ $ctr = write_bytes ]; then
14612                         f0=/dev/zero
14613                         f1=${testdir}/${tfile}
14614                 else
14615                         f0=${testdir}/${tfile}
14616                         f1=/dev/null
14617                 fi
14618
14619                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14620                         error "dd failed"
14621                 sync
14622                 cancel_lru_locks osc
14623
14624                 sum=$(do_facet ost1 $LCTL get_param \
14625                         "obdfilter.*.exports.*.stats" |
14626                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14627                                 $1 == ctr { sum += $7 }
14628                                 END { printf("%0.0f", sum) }')
14629
14630                 if ((sum != bs * count)); then
14631                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14632                 fi
14633         done
14634
14635         rm -rf $DIR/${tdir}
14636 }
14637 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14638
14639 test_133f() {
14640         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14641                 skip "too old lustre for get_param -R ($facet_ver)"
14642
14643         # verifying readability.
14644         $LCTL get_param -R '*' &> /dev/null
14645
14646         # Verifing writability with badarea_io.
14647         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14648         local skipped_params='force_lbug|changelog_mask|daemon_file'
14649         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14650                 egrep -v "$skipped_params" |
14651                 xargs -n 1 find $proc_dirs -name |
14652                 xargs -n 1 badarea_io ||
14653                 error "client badarea_io failed"
14654
14655         # remount the FS in case writes/reads /proc break the FS
14656         cleanup || error "failed to unmount"
14657         setup || error "failed to setup"
14658 }
14659 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14660
14661 test_133g() {
14662         remote_mds_nodsh && skip "remote MDS with nodsh"
14663         remote_ost_nodsh && skip "remote OST with nodsh"
14664
14665         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14666         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14667         local facet
14668         for facet in mds1 ost1; do
14669                 local facet_ver=$(lustre_version_code $facet)
14670                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14671                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14672                 else
14673                         log "$facet: too old lustre for get_param -R"
14674                 fi
14675                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14676                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14677                                 tr -d = | egrep -v $skipped_params |
14678                                 xargs -n 1 find $proc_dirs -name |
14679                                 xargs -n 1 badarea_io" ||
14680                                         error "$facet badarea_io failed"
14681                 else
14682                         skip_noexit "$facet: too old lustre for get_param -R"
14683                 fi
14684         done
14685
14686         # remount the FS in case writes/reads /proc break the FS
14687         cleanup || error "failed to unmount"
14688         setup || error "failed to setup"
14689 }
14690 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14691
14692 test_133h() {
14693         remote_mds_nodsh && skip "remote MDS with nodsh"
14694         remote_ost_nodsh && skip "remote OST with nodsh"
14695         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14696                 skip "Need MDS version at least 2.9.54"
14697
14698         local facet
14699         for facet in client mds1 ost1; do
14700                 # Get the list of files that are missing the terminating newline
14701                 local plist=$(do_facet $facet
14702                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14703                 local ent
14704                 for ent in $plist; do
14705                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14706                                 awk -v FS='\v' -v RS='\v\v' \
14707                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14708                                         print FILENAME}'" 2>/dev/null)
14709                         [ -z $missing ] || {
14710                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14711                                 error "file does not end with newline: $facet-$ent"
14712                         }
14713                 done
14714         done
14715 }
14716 run_test 133h "Proc files should end with newlines"
14717
14718 test_134a() {
14719         remote_mds_nodsh && skip "remote MDS with nodsh"
14720         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14721                 skip "Need MDS version at least 2.7.54"
14722
14723         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14724         cancel_lru_locks mdc
14725
14726         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14727         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14728         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14729
14730         local nr=1000
14731         createmany -o $DIR/$tdir/f $nr ||
14732                 error "failed to create $nr files in $DIR/$tdir"
14733         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14734
14735         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14736         do_facet mds1 $LCTL set_param fail_loc=0x327
14737         do_facet mds1 $LCTL set_param fail_val=500
14738         touch $DIR/$tdir/m
14739
14740         echo "sleep 10 seconds ..."
14741         sleep 10
14742         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14743
14744         do_facet mds1 $LCTL set_param fail_loc=0
14745         do_facet mds1 $LCTL set_param fail_val=0
14746         [ $lck_cnt -lt $unused ] ||
14747                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14748
14749         rm $DIR/$tdir/m
14750         unlinkmany $DIR/$tdir/f $nr
14751 }
14752 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14753
14754 test_134b() {
14755         remote_mds_nodsh && skip "remote MDS with nodsh"
14756         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14757                 skip "Need MDS version at least 2.7.54"
14758
14759         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14760         cancel_lru_locks mdc
14761
14762         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14763                         ldlm.lock_reclaim_threshold_mb)
14764         # disable reclaim temporarily
14765         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14766
14767         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14768         do_facet mds1 $LCTL set_param fail_loc=0x328
14769         do_facet mds1 $LCTL set_param fail_val=500
14770
14771         $LCTL set_param debug=+trace
14772
14773         local nr=600
14774         createmany -o $DIR/$tdir/f $nr &
14775         local create_pid=$!
14776
14777         echo "Sleep $TIMEOUT seconds ..."
14778         sleep $TIMEOUT
14779         if ! ps -p $create_pid  > /dev/null 2>&1; then
14780                 do_facet mds1 $LCTL set_param fail_loc=0
14781                 do_facet mds1 $LCTL set_param fail_val=0
14782                 do_facet mds1 $LCTL set_param \
14783                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14784                 error "createmany finished incorrectly!"
14785         fi
14786         do_facet mds1 $LCTL set_param fail_loc=0
14787         do_facet mds1 $LCTL set_param fail_val=0
14788         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14789         wait $create_pid || return 1
14790
14791         unlinkmany $DIR/$tdir/f $nr
14792 }
14793 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14794
14795 test_135() {
14796         remote_mds_nodsh && skip "remote MDS with nodsh"
14797         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14798                 skip "Need MDS version at least 2.13.50"
14799         local fname
14800
14801         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14802
14803 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14804         #set only one record at plain llog
14805         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14806
14807         #fill already existed plain llog each 64767
14808         #wrapping whole catalog
14809         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14810
14811         createmany -o $DIR/$tdir/$tfile_ 64700
14812         for (( i = 0; i < 64700; i = i + 2 ))
14813         do
14814                 rm $DIR/$tdir/$tfile_$i &
14815                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14816                 local pid=$!
14817                 wait $pid
14818         done
14819
14820         #waiting osp synchronization
14821         wait_delete_completed
14822 }
14823 run_test 135 "Race catalog processing"
14824
14825 test_136() {
14826         remote_mds_nodsh && skip "remote MDS with nodsh"
14827         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14828                 skip "Need MDS version at least 2.13.50"
14829         local fname
14830
14831         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14832         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14833         #set only one record at plain llog
14834 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14835         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14836
14837         #fill already existed 2 plain llogs each 64767
14838         #wrapping whole catalog
14839         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14840         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14841         wait_delete_completed
14842
14843         createmany -o $DIR/$tdir/$tfile_ 10
14844         sleep 25
14845
14846         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14847         for (( i = 0; i < 10; i = i + 3 ))
14848         do
14849                 rm $DIR/$tdir/$tfile_$i &
14850                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14851                 local pid=$!
14852                 wait $pid
14853                 sleep 7
14854                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14855         done
14856
14857         #waiting osp synchronization
14858         wait_delete_completed
14859 }
14860 run_test 136 "Race catalog processing 2"
14861
14862 test_140() { #bug-17379
14863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14864
14865         test_mkdir $DIR/$tdir
14866         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14867         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14868
14869         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14870         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14871         local i=0
14872         while i=$((i + 1)); do
14873                 test_mkdir $i
14874                 cd $i || error "Changing to $i"
14875                 ln -s ../stat stat || error "Creating stat symlink"
14876                 # Read the symlink until ELOOP present,
14877                 # not LBUGing the system is considered success,
14878                 # we didn't overrun the stack.
14879                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14880                 if [ $ret -ne 0 ]; then
14881                         if [ $ret -eq 40 ]; then
14882                                 break  # -ELOOP
14883                         else
14884                                 error "Open stat symlink"
14885                                         return
14886                         fi
14887                 fi
14888         done
14889         i=$((i - 1))
14890         echo "The symlink depth = $i"
14891         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14892                 error "Invalid symlink depth"
14893
14894         # Test recursive symlink
14895         ln -s symlink_self symlink_self
14896         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14897         echo "open symlink_self returns $ret"
14898         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14899 }
14900 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14901
14902 test_150a() {
14903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14904
14905         local TF="$TMP/$tfile"
14906
14907         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14908         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14909         cp $TF $DIR/$tfile
14910         cancel_lru_locks $OSC
14911         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14912         remount_client $MOUNT
14913         df -P $MOUNT
14914         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14915
14916         $TRUNCATE $TF 6000
14917         $TRUNCATE $DIR/$tfile 6000
14918         cancel_lru_locks $OSC
14919         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14920
14921         echo "12345" >>$TF
14922         echo "12345" >>$DIR/$tfile
14923         cancel_lru_locks $OSC
14924         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14925
14926         echo "12345" >>$TF
14927         echo "12345" >>$DIR/$tfile
14928         cancel_lru_locks $OSC
14929         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14930 }
14931 run_test 150a "truncate/append tests"
14932
14933 test_150b() {
14934         check_set_fallocate_or_skip
14935         local out
14936
14937         touch $DIR/$tfile
14938         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14939         out=$(check_fallocate $DIR/$tfile 2>&1) ||
14940                 skip_eopnotsupp "$out|check_fallocate failed"
14941 }
14942 run_test 150b "Verify fallocate (prealloc) functionality"
14943
14944 test_150bb() {
14945         check_set_fallocate_or_skip
14946
14947         touch $DIR/$tfile
14948         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14949         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14950         > $DIR/$tfile
14951         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14952         # precomputed md5sum for 20MB of zeroes
14953         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14954         local sum=($(md5sum $DIR/$tfile))
14955
14956         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14957
14958         check_set_fallocate 1
14959
14960         > $DIR/$tfile
14961         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14962         sum=($(md5sum $DIR/$tfile))
14963
14964         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14965 }
14966 run_test 150bb "Verify fallocate modes both zero space"
14967
14968 test_150c() {
14969         check_set_fallocate_or_skip
14970         local striping="-c2"
14971
14972         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14973         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14974         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14975         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14976         local want=$((OSTCOUNT * 1048576))
14977
14978         # Must allocate all requested space, not more than 5% extra
14979         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14980                 error "bytes $bytes is not $want"
14981
14982         rm -f $DIR/$tfile
14983
14984         echo "verify fallocate on PFL file"
14985
14986         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14987
14988         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14989                 error "Create $DIR/$tfile failed"
14990         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14991         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14992         want=$((512 * 1048576))
14993
14994         # Must allocate all requested space, not more than 5% extra
14995         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14996                 error "bytes $bytes is not $want"
14997 }
14998 run_test 150c "Verify fallocate Size and Blocks"
14999
15000 test_150d() {
15001         check_set_fallocate_or_skip
15002         local striping="-c2"
15003
15004         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15005
15006         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15007         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15008                 error "setstripe failed"
15009         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15010         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15011         local want=$((OSTCOUNT * 1048576))
15012
15013         # Must allocate all requested space, not more than 5% extra
15014         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15015                 error "bytes $bytes is not $want"
15016 }
15017 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15018
15019 test_150e() {
15020         check_set_fallocate_or_skip
15021
15022         echo "df before:"
15023         $LFS df
15024         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15025         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15026                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15027
15028         # Find OST with Minimum Size
15029         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15030                        sort -un | head -1)
15031
15032         # Get 100MB per OST of the available space to reduce run time
15033         # else 60% of the available space if we are running SLOW tests
15034         if [ $SLOW == "no" ]; then
15035                 local space=$((1024 * 100 * OSTCOUNT))
15036         else
15037                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15038         fi
15039
15040         fallocate -l${space}k $DIR/$tfile ||
15041                 error "fallocate ${space}k $DIR/$tfile failed"
15042         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15043
15044         # get size immediately after fallocate. This should be correctly
15045         # updated
15046         local size=$(stat -c '%s' $DIR/$tfile)
15047         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15048
15049         # Sleep for a while for statfs to get updated. And not pull from cache.
15050         sleep 2
15051
15052         echo "df after fallocate:"
15053         $LFS df
15054
15055         (( size / 1024 == space )) || error "size $size != requested $space"
15056         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15057                 error "used $used < space $space"
15058
15059         rm $DIR/$tfile || error "rm failed"
15060         sync
15061         wait_delete_completed
15062
15063         echo "df after unlink:"
15064         $LFS df
15065 }
15066 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15067
15068 test_150f() {
15069         local size
15070         local blocks
15071         local want_size_before=20480 # in bytes
15072         local want_blocks_before=40 # 512 sized blocks
15073         local want_blocks_after=24  # 512 sized blocks
15074         local length=$(((want_blocks_before - want_blocks_after) * 512))
15075
15076         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15077                 skip "need at least 2.14.0 for fallocate punch"
15078
15079         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15080                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15081         fi
15082
15083         check_set_fallocate_or_skip
15084         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15085
15086         [[ "x$DOM" == "xyes" ]] &&
15087                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15088
15089         echo "Verify fallocate punch: Range within the file range"
15090         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15091                 error "dd failed for bs 4096 and count 5"
15092
15093         # Call fallocate with punch range which is within the file range
15094         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15095                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15096         # client must see changes immediately after fallocate
15097         size=$(stat -c '%s' $DIR/$tfile)
15098         blocks=$(stat -c '%b' $DIR/$tfile)
15099
15100         # Verify punch worked.
15101         (( blocks == want_blocks_after )) ||
15102                 error "punch failed: blocks $blocks != $want_blocks_after"
15103
15104         (( size == want_size_before )) ||
15105                 error "punch failed: size $size != $want_size_before"
15106
15107         # Verify there is hole in file
15108         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15109         # precomputed md5sum
15110         local expect="4a9a834a2db02452929c0a348273b4aa"
15111
15112         cksum=($(md5sum $DIR/$tfile))
15113         [[ "${cksum[0]}" == "$expect" ]] ||
15114                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15115
15116         # Start second sub-case for fallocate punch.
15117         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15118         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15119                 error "dd failed for bs 4096 and count 5"
15120
15121         # Punch range less than block size will have no change in block count
15122         want_blocks_after=40  # 512 sized blocks
15123
15124         # Punch overlaps two blocks and less than blocksize
15125         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15126                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15127         size=$(stat -c '%s' $DIR/$tfile)
15128         blocks=$(stat -c '%b' $DIR/$tfile)
15129
15130         # Verify punch worked.
15131         (( blocks == want_blocks_after )) ||
15132                 error "punch failed: blocks $blocks != $want_blocks_after"
15133
15134         (( size == want_size_before )) ||
15135                 error "punch failed: size $size != $want_size_before"
15136
15137         # Verify if range is really zero'ed out. We expect Zeros.
15138         # precomputed md5sum
15139         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15140         cksum=($(md5sum $DIR/$tfile))
15141         [[ "${cksum[0]}" == "$expect" ]] ||
15142                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15143 }
15144 run_test 150f "Verify fallocate punch functionality"
15145
15146 test_150g() {
15147         local space
15148         local size
15149         local blocks
15150         local blocks_after
15151         local size_after
15152         local BS=4096 # Block size in bytes
15153
15154         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15155                 skip "need at least 2.14.0 for fallocate punch"
15156
15157         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15158                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15159         fi
15160
15161         check_set_fallocate_or_skip
15162         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15163
15164         if [[ "x$DOM" == "xyes" ]]; then
15165                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15166                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15167         else
15168                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15169                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15170         fi
15171
15172         # Get 100MB per OST of the available space to reduce run time
15173         # else 60% of the available space if we are running SLOW tests
15174         if [ $SLOW == "no" ]; then
15175                 space=$((1024 * 100 * OSTCOUNT))
15176         else
15177                 # Find OST with Minimum Size
15178                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15179                         sort -un | head -1)
15180                 echo "min size OST: $space"
15181                 space=$(((space * 60)/100 * OSTCOUNT))
15182         fi
15183         # space in 1k units, round to 4k blocks
15184         local blkcount=$((space * 1024 / $BS))
15185
15186         echo "Verify fallocate punch: Very large Range"
15187         fallocate -l${space}k $DIR/$tfile ||
15188                 error "fallocate ${space}k $DIR/$tfile failed"
15189         # write 1M at the end, start and in the middle
15190         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15191                 error "dd failed: bs $BS count 256"
15192         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15193                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15194         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15195                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15196
15197         # Gather stats.
15198         size=$(stat -c '%s' $DIR/$tfile)
15199
15200         # gather punch length.
15201         local punch_size=$((size - (BS * 2)))
15202
15203         echo "punch_size = $punch_size"
15204         echo "size - punch_size: $((size - punch_size))"
15205         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15206
15207         # Call fallocate to punch all except 2 blocks. We leave the
15208         # first and the last block
15209         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15210         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15211                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15212
15213         size_after=$(stat -c '%s' $DIR/$tfile)
15214         blocks_after=$(stat -c '%b' $DIR/$tfile)
15215
15216         # Verify punch worked.
15217         # Size should be kept
15218         (( size == size_after )) ||
15219                 error "punch failed: size $size != $size_after"
15220
15221         # two 4k data blocks to remain plus possible 1 extra extent block
15222         (( blocks_after <= ((BS / 512) * 3) )) ||
15223                 error "too many blocks remains: $blocks_after"
15224
15225         # Verify that file has hole between the first and the last blocks
15226         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15227         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15228
15229         echo "Hole at [$hole_start, $hole_end)"
15230         (( hole_start == BS )) ||
15231                 error "no hole at offset $BS after punch"
15232
15233         (( hole_end == BS + punch_size )) ||
15234                 error "data at offset $hole_end < $((BS + punch_size))"
15235 }
15236 run_test 150g "Verify fallocate punch on large range"
15237
15238 #LU-2902 roc_hit was not able to read all values from lproc
15239 function roc_hit_init() {
15240         local list=$(comma_list $(osts_nodes))
15241         local dir=$DIR/$tdir-check
15242         local file=$dir/$tfile
15243         local BEFORE
15244         local AFTER
15245         local idx
15246
15247         test_mkdir $dir
15248         #use setstripe to do a write to every ost
15249         for i in $(seq 0 $((OSTCOUNT-1))); do
15250                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15251                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15252                 idx=$(printf %04x $i)
15253                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15254                         awk '$1 == "cache_access" {sum += $7}
15255                                 END { printf("%0.0f", sum) }')
15256
15257                 cancel_lru_locks osc
15258                 cat $file >/dev/null
15259
15260                 AFTER=$(get_osd_param $list *OST*$idx stats |
15261                         awk '$1 == "cache_access" {sum += $7}
15262                                 END { printf("%0.0f", sum) }')
15263
15264                 echo BEFORE:$BEFORE AFTER:$AFTER
15265                 if ! let "AFTER - BEFORE == 4"; then
15266                         rm -rf $dir
15267                         error "roc_hit is not safe to use"
15268                 fi
15269                 rm $file
15270         done
15271
15272         rm -rf $dir
15273 }
15274
15275 function roc_hit() {
15276         local list=$(comma_list $(osts_nodes))
15277         echo $(get_osd_param $list '' stats |
15278                 awk '$1 == "cache_hit" {sum += $7}
15279                         END { printf("%0.0f", sum) }')
15280 }
15281
15282 function set_cache() {
15283         local on=1
15284
15285         if [ "$2" == "off" ]; then
15286                 on=0;
15287         fi
15288         local list=$(comma_list $(osts_nodes))
15289         set_osd_param $list '' $1_cache_enable $on
15290
15291         cancel_lru_locks osc
15292 }
15293
15294 test_151() {
15295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15296         remote_ost_nodsh && skip "remote OST with nodsh"
15297
15298         local CPAGES=3
15299         local list=$(comma_list $(osts_nodes))
15300
15301         # check whether obdfilter is cache capable at all
15302         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15303                 skip "not cache-capable obdfilter"
15304         fi
15305
15306         # check cache is enabled on all obdfilters
15307         if get_osd_param $list '' read_cache_enable | grep 0; then
15308                 skip "oss cache is disabled"
15309         fi
15310
15311         set_osd_param $list '' writethrough_cache_enable 1
15312
15313         # check write cache is enabled on all obdfilters
15314         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15315                 skip "oss write cache is NOT enabled"
15316         fi
15317
15318         roc_hit_init
15319
15320         #define OBD_FAIL_OBD_NO_LRU  0x609
15321         do_nodes $list $LCTL set_param fail_loc=0x609
15322
15323         # pages should be in the case right after write
15324         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15325                 error "dd failed"
15326
15327         local BEFORE=$(roc_hit)
15328         cancel_lru_locks osc
15329         cat $DIR/$tfile >/dev/null
15330         local AFTER=$(roc_hit)
15331
15332         do_nodes $list $LCTL set_param fail_loc=0
15333
15334         if ! let "AFTER - BEFORE == CPAGES"; then
15335                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15336         fi
15337
15338         cancel_lru_locks osc
15339         # invalidates OST cache
15340         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15341         set_osd_param $list '' read_cache_enable 0
15342         cat $DIR/$tfile >/dev/null
15343
15344         # now data shouldn't be found in the cache
15345         BEFORE=$(roc_hit)
15346         cancel_lru_locks osc
15347         cat $DIR/$tfile >/dev/null
15348         AFTER=$(roc_hit)
15349         if let "AFTER - BEFORE != 0"; then
15350                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15351         fi
15352
15353         set_osd_param $list '' read_cache_enable 1
15354         rm -f $DIR/$tfile
15355 }
15356 run_test 151 "test cache on oss and controls ==============================="
15357
15358 test_152() {
15359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15360
15361         local TF="$TMP/$tfile"
15362
15363         # simulate ENOMEM during write
15364 #define OBD_FAIL_OST_NOMEM      0x226
15365         lctl set_param fail_loc=0x80000226
15366         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15367         cp $TF $DIR/$tfile
15368         sync || error "sync failed"
15369         lctl set_param fail_loc=0
15370
15371         # discard client's cache
15372         cancel_lru_locks osc
15373
15374         # simulate ENOMEM during read
15375         lctl set_param fail_loc=0x80000226
15376         cmp $TF $DIR/$tfile || error "cmp failed"
15377         lctl set_param fail_loc=0
15378
15379         rm -f $TF
15380 }
15381 run_test 152 "test read/write with enomem ============================"
15382
15383 test_153() {
15384         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15385 }
15386 run_test 153 "test if fdatasync does not crash ======================="
15387
15388 dot_lustre_fid_permission_check() {
15389         local fid=$1
15390         local ffid=$MOUNT/.lustre/fid/$fid
15391         local test_dir=$2
15392
15393         echo "stat fid $fid"
15394         stat $ffid || error "stat $ffid failed."
15395         echo "touch fid $fid"
15396         touch $ffid || error "touch $ffid failed."
15397         echo "write to fid $fid"
15398         cat /etc/hosts > $ffid || error "write $ffid failed."
15399         echo "read fid $fid"
15400         diff /etc/hosts $ffid || error "read $ffid failed."
15401         echo "append write to fid $fid"
15402         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15403         echo "rename fid $fid"
15404         mv $ffid $test_dir/$tfile.1 &&
15405                 error "rename $ffid to $tfile.1 should fail."
15406         touch $test_dir/$tfile.1
15407         mv $test_dir/$tfile.1 $ffid &&
15408                 error "rename $tfile.1 to $ffid should fail."
15409         rm -f $test_dir/$tfile.1
15410         echo "truncate fid $fid"
15411         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15412         echo "link fid $fid"
15413         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15414         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15415                 echo "setfacl fid $fid"
15416                 setfacl -R -m u:$USER0:rwx $ffid ||
15417                         error "setfacl $ffid failed"
15418                 echo "getfacl fid $fid"
15419                 getfacl $ffid || error "getfacl $ffid failed."
15420         fi
15421         echo "unlink fid $fid"
15422         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15423         echo "mknod fid $fid"
15424         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15425
15426         fid=[0xf00000400:0x1:0x0]
15427         ffid=$MOUNT/.lustre/fid/$fid
15428
15429         echo "stat non-exist fid $fid"
15430         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15431         echo "write to non-exist fid $fid"
15432         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15433         echo "link new fid $fid"
15434         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15435
15436         mkdir -p $test_dir/$tdir
15437         touch $test_dir/$tdir/$tfile
15438         fid=$($LFS path2fid $test_dir/$tdir)
15439         rc=$?
15440         [ $rc -ne 0 ] &&
15441                 error "error: could not get fid for $test_dir/$dir/$tfile."
15442
15443         ffid=$MOUNT/.lustre/fid/$fid
15444
15445         echo "ls $fid"
15446         ls $ffid || error "ls $ffid failed."
15447         echo "touch $fid/$tfile.1"
15448         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15449
15450         echo "touch $MOUNT/.lustre/fid/$tfile"
15451         touch $MOUNT/.lustre/fid/$tfile && \
15452                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15453
15454         echo "setxattr to $MOUNT/.lustre/fid"
15455         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15456
15457         echo "listxattr for $MOUNT/.lustre/fid"
15458         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15459
15460         echo "delxattr from $MOUNT/.lustre/fid"
15461         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15462
15463         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15464         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15465                 error "touch invalid fid should fail."
15466
15467         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15468         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15469                 error "touch non-normal fid should fail."
15470
15471         echo "rename $tdir to $MOUNT/.lustre/fid"
15472         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15473                 error "rename to $MOUNT/.lustre/fid should fail."
15474
15475         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15476         then            # LU-3547
15477                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15478                 local new_obf_mode=777
15479
15480                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15481                 chmod $new_obf_mode $DIR/.lustre/fid ||
15482                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15483
15484                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15485                 [ $obf_mode -eq $new_obf_mode ] ||
15486                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15487
15488                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15489                 chmod $old_obf_mode $DIR/.lustre/fid ||
15490                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15491         fi
15492
15493         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15494         fid=$($LFS path2fid $test_dir/$tfile-2)
15495
15496         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15497         then # LU-5424
15498                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15499                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15500                         error "create lov data thru .lustre failed"
15501         fi
15502         echo "cp /etc/passwd $test_dir/$tfile-2"
15503         cp /etc/passwd $test_dir/$tfile-2 ||
15504                 error "copy to $test_dir/$tfile-2 failed."
15505         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15506         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15507                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15508
15509         rm -rf $test_dir/tfile.lnk
15510         rm -rf $test_dir/$tfile-2
15511 }
15512
15513 test_154A() {
15514         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15515                 skip "Need MDS version at least 2.4.1"
15516
15517         local tf=$DIR/$tfile
15518         touch $tf
15519
15520         local fid=$($LFS path2fid $tf)
15521         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15522
15523         # check that we get the same pathname back
15524         local rootpath
15525         local found
15526         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15527                 echo "$rootpath $fid"
15528                 found=$($LFS fid2path $rootpath "$fid")
15529                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15530                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15531         done
15532
15533         # check wrong root path format
15534         rootpath=$MOUNT"_wrong"
15535         found=$($LFS fid2path $rootpath "$fid")
15536         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15537 }
15538 run_test 154A "lfs path2fid and fid2path basic checks"
15539
15540 test_154B() {
15541         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15542                 skip "Need MDS version at least 2.4.1"
15543
15544         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15545         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15546         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15547         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15548
15549         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15550         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15551
15552         # check that we get the same pathname
15553         echo "PFID: $PFID, name: $name"
15554         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15555         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15556         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15557                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15558
15559         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15560 }
15561 run_test 154B "verify the ll_decode_linkea tool"
15562
15563 test_154a() {
15564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15565         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15566         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15567                 skip "Need MDS version at least 2.2.51"
15568         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15569
15570         cp /etc/hosts $DIR/$tfile
15571
15572         fid=$($LFS path2fid $DIR/$tfile)
15573         rc=$?
15574         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15575
15576         dot_lustre_fid_permission_check "$fid" $DIR ||
15577                 error "dot lustre permission check $fid failed"
15578
15579         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15580
15581         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15582
15583         touch $MOUNT/.lustre/file &&
15584                 error "creation is not allowed under .lustre"
15585
15586         mkdir $MOUNT/.lustre/dir &&
15587                 error "mkdir is not allowed under .lustre"
15588
15589         rm -rf $DIR/$tfile
15590 }
15591 run_test 154a "Open-by-FID"
15592
15593 test_154b() {
15594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15595         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15596         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15597         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15598                 skip "Need MDS version at least 2.2.51"
15599
15600         local remote_dir=$DIR/$tdir/remote_dir
15601         local MDTIDX=1
15602         local rc=0
15603
15604         mkdir -p $DIR/$tdir
15605         $LFS mkdir -i $MDTIDX $remote_dir ||
15606                 error "create remote directory failed"
15607
15608         cp /etc/hosts $remote_dir/$tfile
15609
15610         fid=$($LFS path2fid $remote_dir/$tfile)
15611         rc=$?
15612         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15613
15614         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15615                 error "dot lustre permission check $fid failed"
15616         rm -rf $DIR/$tdir
15617 }
15618 run_test 154b "Open-by-FID for remote directory"
15619
15620 test_154c() {
15621         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15622                 skip "Need MDS version at least 2.4.1"
15623
15624         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15625         local FID1=$($LFS path2fid $DIR/$tfile.1)
15626         local FID2=$($LFS path2fid $DIR/$tfile.2)
15627         local FID3=$($LFS path2fid $DIR/$tfile.3)
15628
15629         local N=1
15630         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15631                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15632                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15633                 local want=FID$N
15634                 [ "$FID" = "${!want}" ] ||
15635                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15636                 N=$((N + 1))
15637         done
15638
15639         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15640         do
15641                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15642                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15643                 N=$((N + 1))
15644         done
15645 }
15646 run_test 154c "lfs path2fid and fid2path multiple arguments"
15647
15648 test_154d() {
15649         remote_mds_nodsh && skip "remote MDS with nodsh"
15650         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15651                 skip "Need MDS version at least 2.5.53"
15652
15653         if remote_mds; then
15654                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15655         else
15656                 nid="0@lo"
15657         fi
15658         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15659         local fd
15660         local cmd
15661
15662         rm -f $DIR/$tfile
15663         touch $DIR/$tfile
15664
15665         local fid=$($LFS path2fid $DIR/$tfile)
15666         # Open the file
15667         fd=$(free_fd)
15668         cmd="exec $fd<$DIR/$tfile"
15669         eval $cmd
15670         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15671         echo "$fid_list" | grep "$fid"
15672         rc=$?
15673
15674         cmd="exec $fd>/dev/null"
15675         eval $cmd
15676         if [ $rc -ne 0 ]; then
15677                 error "FID $fid not found in open files list $fid_list"
15678         fi
15679 }
15680 run_test 154d "Verify open file fid"
15681
15682 test_154e()
15683 {
15684         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15685                 skip "Need MDS version at least 2.6.50"
15686
15687         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15688                 error ".lustre returned by readdir"
15689         fi
15690 }
15691 run_test 154e ".lustre is not returned by readdir"
15692
15693 test_154f() {
15694         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15695
15696         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15697         mkdir_on_mdt0 $DIR/$tdir
15698         # test dirs inherit from its stripe
15699         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15700         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15701         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15702         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15703         touch $DIR/f
15704
15705         # get fid of parents
15706         local FID0=$($LFS path2fid $DIR/$tdir)
15707         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15708         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15709         local FID3=$($LFS path2fid $DIR)
15710
15711         # check that path2fid --parents returns expected <parent_fid>/name
15712         # 1) test for a directory (single parent)
15713         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15714         [ "$parent" == "$FID0/foo1" ] ||
15715                 error "expected parent: $FID0/foo1, got: $parent"
15716
15717         # 2) test for a file with nlink > 1 (multiple parents)
15718         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15719         echo "$parent" | grep -F "$FID1/$tfile" ||
15720                 error "$FID1/$tfile not returned in parent list"
15721         echo "$parent" | grep -F "$FID2/link" ||
15722                 error "$FID2/link not returned in parent list"
15723
15724         # 3) get parent by fid
15725         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15726         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15727         echo "$parent" | grep -F "$FID1/$tfile" ||
15728                 error "$FID1/$tfile not returned in parent list (by fid)"
15729         echo "$parent" | grep -F "$FID2/link" ||
15730                 error "$FID2/link not returned in parent list (by fid)"
15731
15732         # 4) test for entry in root directory
15733         parent=$($LFS path2fid --parents $DIR/f)
15734         echo "$parent" | grep -F "$FID3/f" ||
15735                 error "$FID3/f not returned in parent list"
15736
15737         # 5) test it on root directory
15738         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15739                 error "$MOUNT should not have parents"
15740
15741         # enable xattr caching and check that linkea is correctly updated
15742         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15743         save_lustre_params client "llite.*.xattr_cache" > $save
15744         lctl set_param llite.*.xattr_cache 1
15745
15746         # 6.1) linkea update on rename
15747         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15748
15749         # get parents by fid
15750         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15751         # foo1 should no longer be returned in parent list
15752         echo "$parent" | grep -F "$FID1" &&
15753                 error "$FID1 should no longer be in parent list"
15754         # the new path should appear
15755         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15756                 error "$FID2/$tfile.moved is not in parent list"
15757
15758         # 6.2) linkea update on unlink
15759         rm -f $DIR/$tdir/foo2/link
15760         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15761         # foo2/link should no longer be returned in parent list
15762         echo "$parent" | grep -F "$FID2/link" &&
15763                 error "$FID2/link should no longer be in parent list"
15764         true
15765
15766         rm -f $DIR/f
15767         restore_lustre_params < $save
15768         rm -f $save
15769 }
15770 run_test 154f "get parent fids by reading link ea"
15771
15772 test_154g()
15773 {
15774         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15775            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15776                 skip "Need MDS version at least 2.6.92"
15777
15778         mkdir_on_mdt0 $DIR/$tdir
15779         llapi_fid_test -d $DIR/$tdir
15780 }
15781 run_test 154g "various llapi FID tests"
15782
15783 test_155_small_load() {
15784     local temp=$TMP/$tfile
15785     local file=$DIR/$tfile
15786
15787     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15788         error "dd of=$temp bs=6096 count=1 failed"
15789     cp $temp $file
15790     cancel_lru_locks $OSC
15791     cmp $temp $file || error "$temp $file differ"
15792
15793     $TRUNCATE $temp 6000
15794     $TRUNCATE $file 6000
15795     cmp $temp $file || error "$temp $file differ (truncate1)"
15796
15797     echo "12345" >>$temp
15798     echo "12345" >>$file
15799     cmp $temp $file || error "$temp $file differ (append1)"
15800
15801     echo "12345" >>$temp
15802     echo "12345" >>$file
15803     cmp $temp $file || error "$temp $file differ (append2)"
15804
15805     rm -f $temp $file
15806     true
15807 }
15808
15809 test_155_big_load() {
15810         remote_ost_nodsh && skip "remote OST with nodsh"
15811
15812         local temp=$TMP/$tfile
15813         local file=$DIR/$tfile
15814
15815         free_min_max
15816         local cache_size=$(do_facet ost$((MAXI+1)) \
15817                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15818
15819         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15820         # pre-set value
15821         if [ -z "$cache_size" ]; then
15822                 cache_size=256
15823         fi
15824         local large_file_size=$((cache_size * 2))
15825
15826         echo "OSS cache size: $cache_size KB"
15827         echo "Large file size: $large_file_size KB"
15828
15829         [ $MAXV -le $large_file_size ] &&
15830                 skip_env "max available OST size needs > $large_file_size KB"
15831
15832         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15833
15834         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15835                 error "dd of=$temp bs=$large_file_size count=1k failed"
15836         cp $temp $file
15837         ls -lh $temp $file
15838         cancel_lru_locks osc
15839         cmp $temp $file || error "$temp $file differ"
15840
15841         rm -f $temp $file
15842         true
15843 }
15844
15845 save_writethrough() {
15846         local facets=$(get_facets OST)
15847
15848         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15849 }
15850
15851 test_155a() {
15852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15853
15854         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15855
15856         save_writethrough $p
15857
15858         set_cache read on
15859         set_cache writethrough on
15860         test_155_small_load
15861         restore_lustre_params < $p
15862         rm -f $p
15863 }
15864 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15865
15866 test_155b() {
15867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15868
15869         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15870
15871         save_writethrough $p
15872
15873         set_cache read on
15874         set_cache writethrough off
15875         test_155_small_load
15876         restore_lustre_params < $p
15877         rm -f $p
15878 }
15879 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15880
15881 test_155c() {
15882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15883
15884         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15885
15886         save_writethrough $p
15887
15888         set_cache read off
15889         set_cache writethrough on
15890         test_155_small_load
15891         restore_lustre_params < $p
15892         rm -f $p
15893 }
15894 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15895
15896 test_155d() {
15897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15898
15899         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15900
15901         save_writethrough $p
15902
15903         set_cache read off
15904         set_cache writethrough off
15905         test_155_small_load
15906         restore_lustre_params < $p
15907         rm -f $p
15908 }
15909 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15910
15911 test_155e() {
15912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15913
15914         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15915
15916         save_writethrough $p
15917
15918         set_cache read on
15919         set_cache writethrough on
15920         test_155_big_load
15921         restore_lustre_params < $p
15922         rm -f $p
15923 }
15924 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15925
15926 test_155f() {
15927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15928
15929         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15930
15931         save_writethrough $p
15932
15933         set_cache read on
15934         set_cache writethrough off
15935         test_155_big_load
15936         restore_lustre_params < $p
15937         rm -f $p
15938 }
15939 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15940
15941 test_155g() {
15942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15943
15944         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15945
15946         save_writethrough $p
15947
15948         set_cache read off
15949         set_cache writethrough on
15950         test_155_big_load
15951         restore_lustre_params < $p
15952         rm -f $p
15953 }
15954 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15955
15956 test_155h() {
15957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15958
15959         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15960
15961         save_writethrough $p
15962
15963         set_cache read off
15964         set_cache writethrough off
15965         test_155_big_load
15966         restore_lustre_params < $p
15967         rm -f $p
15968 }
15969 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15970
15971 test_156() {
15972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15973         remote_ost_nodsh && skip "remote OST with nodsh"
15974         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15975                 skip "stats not implemented on old servers"
15976         [ "$ost1_FSTYPE" = "zfs" ] &&
15977                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15978
15979         local CPAGES=3
15980         local BEFORE
15981         local AFTER
15982         local file="$DIR/$tfile"
15983         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15984
15985         save_writethrough $p
15986         roc_hit_init
15987
15988         log "Turn on read and write cache"
15989         set_cache read on
15990         set_cache writethrough on
15991
15992         log "Write data and read it back."
15993         log "Read should be satisfied from the cache."
15994         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15995         BEFORE=$(roc_hit)
15996         cancel_lru_locks osc
15997         cat $file >/dev/null
15998         AFTER=$(roc_hit)
15999         if ! let "AFTER - BEFORE == CPAGES"; then
16000                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16001         else
16002                 log "cache hits: before: $BEFORE, after: $AFTER"
16003         fi
16004
16005         log "Read again; it should be satisfied from the cache."
16006         BEFORE=$AFTER
16007         cancel_lru_locks osc
16008         cat $file >/dev/null
16009         AFTER=$(roc_hit)
16010         if ! let "AFTER - BEFORE == CPAGES"; then
16011                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16012         else
16013                 log "cache hits:: before: $BEFORE, after: $AFTER"
16014         fi
16015
16016         log "Turn off the read cache and turn on the write cache"
16017         set_cache read off
16018         set_cache writethrough on
16019
16020         log "Read again; it should be satisfied from the cache."
16021         BEFORE=$(roc_hit)
16022         cancel_lru_locks osc
16023         cat $file >/dev/null
16024         AFTER=$(roc_hit)
16025         if ! let "AFTER - BEFORE == CPAGES"; then
16026                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16027         else
16028                 log "cache hits:: before: $BEFORE, after: $AFTER"
16029         fi
16030
16031         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16032                 # > 2.12.56 uses pagecache if cached
16033                 log "Read again; it should not be satisfied from the cache."
16034                 BEFORE=$AFTER
16035                 cancel_lru_locks osc
16036                 cat $file >/dev/null
16037                 AFTER=$(roc_hit)
16038                 if ! let "AFTER - BEFORE == 0"; then
16039                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16040                 else
16041                         log "cache hits:: before: $BEFORE, after: $AFTER"
16042                 fi
16043         fi
16044
16045         log "Write data and read it back."
16046         log "Read should be satisfied from the cache."
16047         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16048         BEFORE=$(roc_hit)
16049         cancel_lru_locks osc
16050         cat $file >/dev/null
16051         AFTER=$(roc_hit)
16052         if ! let "AFTER - BEFORE == CPAGES"; then
16053                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16054         else
16055                 log "cache hits:: before: $BEFORE, after: $AFTER"
16056         fi
16057
16058         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16059                 # > 2.12.56 uses pagecache if cached
16060                 log "Read again; it should not be satisfied from the cache."
16061                 BEFORE=$AFTER
16062                 cancel_lru_locks osc
16063                 cat $file >/dev/null
16064                 AFTER=$(roc_hit)
16065                 if ! let "AFTER - BEFORE == 0"; then
16066                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16067                 else
16068                         log "cache hits:: before: $BEFORE, after: $AFTER"
16069                 fi
16070         fi
16071
16072         log "Turn off read and write cache"
16073         set_cache read off
16074         set_cache writethrough off
16075
16076         log "Write data and read it back"
16077         log "It should not be satisfied from the cache."
16078         rm -f $file
16079         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16080         cancel_lru_locks osc
16081         BEFORE=$(roc_hit)
16082         cat $file >/dev/null
16083         AFTER=$(roc_hit)
16084         if ! let "AFTER - BEFORE == 0"; then
16085                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16086         else
16087                 log "cache hits:: before: $BEFORE, after: $AFTER"
16088         fi
16089
16090         log "Turn on the read cache and turn off the write cache"
16091         set_cache read on
16092         set_cache writethrough off
16093
16094         log "Write data and read it back"
16095         log "It should not be satisfied from the cache."
16096         rm -f $file
16097         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16098         BEFORE=$(roc_hit)
16099         cancel_lru_locks osc
16100         cat $file >/dev/null
16101         AFTER=$(roc_hit)
16102         if ! let "AFTER - BEFORE == 0"; then
16103                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16104         else
16105                 log "cache hits:: before: $BEFORE, after: $AFTER"
16106         fi
16107
16108         log "Read again; it should be satisfied from the cache."
16109         BEFORE=$(roc_hit)
16110         cancel_lru_locks osc
16111         cat $file >/dev/null
16112         AFTER=$(roc_hit)
16113         if ! let "AFTER - BEFORE == CPAGES"; then
16114                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16115         else
16116                 log "cache hits:: before: $BEFORE, after: $AFTER"
16117         fi
16118
16119         restore_lustre_params < $p
16120         rm -f $p $file
16121 }
16122 run_test 156 "Verification of tunables"
16123
16124 test_160a() {
16125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16126         remote_mds_nodsh && skip "remote MDS with nodsh"
16127         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16128                 skip "Need MDS version at least 2.2.0"
16129
16130         changelog_register || error "changelog_register failed"
16131         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16132         changelog_users $SINGLEMDS | grep -q $cl_user ||
16133                 error "User $cl_user not found in changelog_users"
16134
16135         mkdir_on_mdt0 $DIR/$tdir
16136
16137         # change something
16138         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16139         changelog_clear 0 || error "changelog_clear failed"
16140         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16141         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16142         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16143         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16144         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16145         rm $DIR/$tdir/pics/desktop.jpg
16146
16147         echo "verifying changelog mask"
16148         changelog_chmask "-MKDIR"
16149         changelog_chmask "-CLOSE"
16150
16151         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16152         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16153
16154         changelog_chmask "+MKDIR"
16155         changelog_chmask "+CLOSE"
16156
16157         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16158         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16159
16160         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16161         CLOSES=$(changelog_dump | grep -c "CLOSE")
16162         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16163         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16164
16165         # verify contents
16166         echo "verifying target fid"
16167         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16168         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16169         [ "$fidc" == "$fidf" ] ||
16170                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16171         echo "verifying parent fid"
16172         # The FID returned from the Changelog may be the directory shard on
16173         # a different MDT, and not the FID returned by path2fid on the parent.
16174         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16175         # since this is what will matter when recreating this file in the tree.
16176         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16177         local pathp=$($LFS fid2path $MOUNT "$fidp")
16178         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16179                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16180
16181         echo "getting records for $cl_user"
16182         changelog_users $SINGLEMDS
16183         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16184         local nclr=3
16185         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16186                 error "changelog_clear failed"
16187         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16188         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16189         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16190                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16191
16192         local min0_rec=$(changelog_users $SINGLEMDS |
16193                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16194         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16195                           awk '{ print $1; exit; }')
16196
16197         changelog_dump | tail -n 5
16198         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16199         [ $first_rec == $((min0_rec + 1)) ] ||
16200                 error "first index should be $min0_rec + 1 not $first_rec"
16201
16202         # LU-3446 changelog index reset on MDT restart
16203         local cur_rec1=$(changelog_users $SINGLEMDS |
16204                          awk '/^current.index:/ { print $NF }')
16205         changelog_clear 0 ||
16206                 error "clear all changelog records for $cl_user failed"
16207         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16208         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16209                 error "Fail to start $SINGLEMDS"
16210         local cur_rec2=$(changelog_users $SINGLEMDS |
16211                          awk '/^current.index:/ { print $NF }')
16212         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16213         [ $cur_rec1 == $cur_rec2 ] ||
16214                 error "current index should be $cur_rec1 not $cur_rec2"
16215
16216         echo "verifying users from this test are deregistered"
16217         changelog_deregister || error "changelog_deregister failed"
16218         changelog_users $SINGLEMDS | grep -q $cl_user &&
16219                 error "User '$cl_user' still in changelog_users"
16220
16221         # lctl get_param -n mdd.*.changelog_users
16222         # current_index: 144
16223         # ID    index (idle seconds)
16224         # cl3   144   (2) mask=<list>
16225         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16226                 # this is the normal case where all users were deregistered
16227                 # make sure no new records are added when no users are present
16228                 local last_rec1=$(changelog_users $SINGLEMDS |
16229                                   awk '/^current.index:/ { print $NF }')
16230                 touch $DIR/$tdir/chloe
16231                 local last_rec2=$(changelog_users $SINGLEMDS |
16232                                   awk '/^current.index:/ { print $NF }')
16233                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16234                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16235         else
16236                 # any changelog users must be leftovers from a previous test
16237                 changelog_users $SINGLEMDS
16238                 echo "other changelog users; can't verify off"
16239         fi
16240 }
16241 run_test 160a "changelog sanity"
16242
16243 test_160b() { # LU-3587
16244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16245         remote_mds_nodsh && skip "remote MDS with nodsh"
16246         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16247                 skip "Need MDS version at least 2.2.0"
16248
16249         changelog_register || error "changelog_register failed"
16250         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16251         changelog_users $SINGLEMDS | grep -q $cl_user ||
16252                 error "User '$cl_user' not found in changelog_users"
16253
16254         local longname1=$(str_repeat a 255)
16255         local longname2=$(str_repeat b 255)
16256
16257         cd $DIR
16258         echo "creating very long named file"
16259         touch $longname1 || error "create of '$longname1' failed"
16260         echo "renaming very long named file"
16261         mv $longname1 $longname2
16262
16263         changelog_dump | grep RENME | tail -n 5
16264         rm -f $longname2
16265 }
16266 run_test 160b "Verify that very long rename doesn't crash in changelog"
16267
16268 test_160c() {
16269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16270         remote_mds_nodsh && skip "remote MDS with nodsh"
16271
16272         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16273                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16274                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16275                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16276
16277         local rc=0
16278
16279         # Registration step
16280         changelog_register || error "changelog_register failed"
16281
16282         rm -rf $DIR/$tdir
16283         mkdir -p $DIR/$tdir
16284         $MCREATE $DIR/$tdir/foo_160c
16285         changelog_chmask "-TRUNC"
16286         $TRUNCATE $DIR/$tdir/foo_160c 200
16287         changelog_chmask "+TRUNC"
16288         $TRUNCATE $DIR/$tdir/foo_160c 199
16289         changelog_dump | tail -n 5
16290         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16291         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16292 }
16293 run_test 160c "verify that changelog log catch the truncate event"
16294
16295 test_160d() {
16296         remote_mds_nodsh && skip "remote MDS with nodsh"
16297         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16299         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16300                 skip "Need MDS version at least 2.7.60"
16301
16302         # Registration step
16303         changelog_register || error "changelog_register failed"
16304
16305         mkdir -p $DIR/$tdir/migrate_dir
16306         changelog_clear 0 || error "changelog_clear failed"
16307
16308         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16309         changelog_dump | tail -n 5
16310         local migrates=$(changelog_dump | grep -c "MIGRT")
16311         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16312 }
16313 run_test 160d "verify that changelog log catch the migrate event"
16314
16315 test_160e() {
16316         remote_mds_nodsh && skip "remote MDS with nodsh"
16317
16318         # Create a user
16319         changelog_register || error "changelog_register failed"
16320
16321         local MDT0=$(facet_svc $SINGLEMDS)
16322         local rc
16323
16324         # No user (expect fail)
16325         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16326         rc=$?
16327         if [ $rc -eq 0 ]; then
16328                 error "Should fail without user"
16329         elif [ $rc -ne 4 ]; then
16330                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16331         fi
16332
16333         # Delete a future user (expect fail)
16334         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16335         rc=$?
16336         if [ $rc -eq 0 ]; then
16337                 error "Deleted non-existant user cl77"
16338         elif [ $rc -ne 2 ]; then
16339                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16340         fi
16341
16342         # Clear to a bad index (1 billion should be safe)
16343         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16344         rc=$?
16345
16346         if [ $rc -eq 0 ]; then
16347                 error "Successfully cleared to invalid CL index"
16348         elif [ $rc -ne 22 ]; then
16349                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16350         fi
16351 }
16352 run_test 160e "changelog negative testing (should return errors)"
16353
16354 test_160f() {
16355         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16356         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16357                 skip "Need MDS version at least 2.10.56"
16358
16359         local mdts=$(comma_list $(mdts_nodes))
16360
16361         # Create a user
16362         changelog_register || error "first changelog_register failed"
16363         changelog_register || error "second changelog_register failed"
16364         local cl_users
16365         declare -A cl_user1
16366         declare -A cl_user2
16367         local user_rec1
16368         local user_rec2
16369         local i
16370
16371         # generate some changelog records to accumulate on each MDT
16372         # use all_char because created files should be evenly distributed
16373         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16374                 error "test_mkdir $tdir failed"
16375         log "$(date +%s): creating first files"
16376         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16377                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16378                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16379         done
16380
16381         # check changelogs have been generated
16382         local start=$SECONDS
16383         local idle_time=$((MDSCOUNT * 5 + 5))
16384         local nbcl=$(changelog_dump | wc -l)
16385         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16386
16387         for param in "changelog_max_idle_time=$idle_time" \
16388                      "changelog_gc=1" \
16389                      "changelog_min_gc_interval=2" \
16390                      "changelog_min_free_cat_entries=3"; do
16391                 local MDT0=$(facet_svc $SINGLEMDS)
16392                 local var="${param%=*}"
16393                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16394
16395                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16396                 do_nodes $mdts $LCTL set_param mdd.*.$param
16397         done
16398
16399         # force cl_user2 to be idle (1st part), but also cancel the
16400         # cl_user1 records so that it is not evicted later in the test.
16401         local sleep1=$((idle_time / 2))
16402         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16403         sleep $sleep1
16404
16405         # simulate changelog catalog almost full
16406         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16407         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16408
16409         for i in $(seq $MDSCOUNT); do
16410                 cl_users=(${CL_USERS[mds$i]})
16411                 cl_user1[mds$i]="${cl_users[0]}"
16412                 cl_user2[mds$i]="${cl_users[1]}"
16413
16414                 [ -n "${cl_user1[mds$i]}" ] ||
16415                         error "mds$i: no user registered"
16416                 [ -n "${cl_user2[mds$i]}" ] ||
16417                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16418
16419                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16420                 [ -n "$user_rec1" ] ||
16421                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16422                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16423                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16424                 [ -n "$user_rec2" ] ||
16425                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16426                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16427                      "$user_rec1 + 2 == $user_rec2"
16428                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16429                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16430                               "$user_rec1 + 2, but is $user_rec2"
16431                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16432                 [ -n "$user_rec2" ] ||
16433                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16434                 [ $user_rec1 == $user_rec2 ] ||
16435                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16436                               "$user_rec1, but is $user_rec2"
16437         done
16438
16439         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16440         local sleep2=$((idle_time - (SECONDS - start) + 1))
16441         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16442         sleep $sleep2
16443
16444         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16445         # cl_user1 should be OK because it recently processed records.
16446         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16447         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16448                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16449                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16450         done
16451
16452         # ensure gc thread is done
16453         for i in $(mdts_nodes); do
16454                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16455                         error "$i: GC-thread not done"
16456         done
16457
16458         local first_rec
16459         for (( i = 1; i <= MDSCOUNT; i++ )); do
16460                 # check cl_user1 still registered
16461                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16462                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16463                 # check cl_user2 unregistered
16464                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16465                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16466
16467                 # check changelogs are present and starting at $user_rec1 + 1
16468                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16469                 [ -n "$user_rec1" ] ||
16470                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16471                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16472                             awk '{ print $1; exit; }')
16473
16474                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16475                 [ $((user_rec1 + 1)) == $first_rec ] ||
16476                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16477         done
16478 }
16479 run_test 160f "changelog garbage collect (timestamped users)"
16480
16481 test_160g() {
16482         remote_mds_nodsh && skip "remote MDS with nodsh"
16483         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16484                 skip "Need MDS version at least 2.14.55"
16485
16486         local mdts=$(comma_list $(mdts_nodes))
16487
16488         # Create a user
16489         changelog_register || error "first changelog_register failed"
16490         changelog_register || error "second changelog_register failed"
16491         local cl_users
16492         declare -A cl_user1
16493         declare -A cl_user2
16494         local user_rec1
16495         local user_rec2
16496         local i
16497
16498         # generate some changelog records to accumulate on each MDT
16499         # use all_char because created files should be evenly distributed
16500         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16501                 error "test_mkdir $tdir failed"
16502         for ((i = 0; i < MDSCOUNT; i++)); do
16503                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16504                         error "create $DIR/$tdir/d$i.1 failed"
16505         done
16506
16507         # check changelogs have been generated
16508         local nbcl=$(changelog_dump | wc -l)
16509         (( $nbcl > 0 )) || error "no changelogs found"
16510
16511         # reduce the max_idle_indexes value to make sure we exceed it
16512         for param in "changelog_max_idle_indexes=2" \
16513                      "changelog_gc=1" \
16514                      "changelog_min_gc_interval=2"; do
16515                 local MDT0=$(facet_svc $SINGLEMDS)
16516                 local var="${param%=*}"
16517                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16518
16519                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16520                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16521                         error "unable to set mdd.*.$param"
16522         done
16523
16524         local start=$SECONDS
16525         for i in $(seq $MDSCOUNT); do
16526                 cl_users=(${CL_USERS[mds$i]})
16527                 cl_user1[mds$i]="${cl_users[0]}"
16528                 cl_user2[mds$i]="${cl_users[1]}"
16529
16530                 [ -n "${cl_user1[mds$i]}" ] ||
16531                         error "mds$i: user1 is not registered"
16532                 [ -n "${cl_user2[mds$i]}" ] ||
16533                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16534
16535                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16536                 [ -n "$user_rec1" ] ||
16537                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16538                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16539                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16540                 [ -n "$user_rec2" ] ||
16541                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16542                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16543                      "$user_rec1 + 2 == $user_rec2"
16544                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16545                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16546                               "expected $user_rec1 + 2, but is $user_rec2"
16547                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16548                 [ -n "$user_rec2" ] ||
16549                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16550                 [ $user_rec1 == $user_rec2 ] ||
16551                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16552                               "expected $user_rec1, but is $user_rec2"
16553         done
16554
16555         # ensure we are past the previous changelog_min_gc_interval set above
16556         local sleep2=$((start + 2 - SECONDS))
16557         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16558         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16559         # cl_user1 should be OK because it recently processed records.
16560         for ((i = 0; i < MDSCOUNT; i++)); do
16561                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16562                         error "create $DIR/$tdir/d$i.3 failed"
16563         done
16564
16565         # ensure gc thread is done
16566         for i in $(mdts_nodes); do
16567                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16568                         error "$i: GC-thread not done"
16569         done
16570
16571         local first_rec
16572         for (( i = 1; i <= MDSCOUNT; i++ )); do
16573                 # check cl_user1 still registered
16574                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16575                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16576                 # check cl_user2 unregistered
16577                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16578                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16579
16580                 # check changelogs are present and starting at $user_rec1 + 1
16581                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16582                 [ -n "$user_rec1" ] ||
16583                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16584                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16585                             awk '{ print $1; exit; }')
16586
16587                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16588                 [ $((user_rec1 + 1)) == $first_rec ] ||
16589                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16590         done
16591 }
16592 run_test 160g "changelog garbage collect on idle records"
16593
16594 test_160h() {
16595         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16596         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16597                 skip "Need MDS version at least 2.10.56"
16598
16599         local mdts=$(comma_list $(mdts_nodes))
16600
16601         # Create a user
16602         changelog_register || error "first changelog_register failed"
16603         changelog_register || error "second changelog_register failed"
16604         local cl_users
16605         declare -A cl_user1
16606         declare -A cl_user2
16607         local user_rec1
16608         local user_rec2
16609         local i
16610
16611         # generate some changelog records to accumulate on each MDT
16612         # use all_char because created files should be evenly distributed
16613         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16614                 error "test_mkdir $tdir failed"
16615         for ((i = 0; i < MDSCOUNT; i++)); do
16616                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16617                         error "create $DIR/$tdir/d$i.1 failed"
16618         done
16619
16620         # check changelogs have been generated
16621         local nbcl=$(changelog_dump | wc -l)
16622         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16623
16624         for param in "changelog_max_idle_time=10" \
16625                      "changelog_gc=1" \
16626                      "changelog_min_gc_interval=2"; do
16627                 local MDT0=$(facet_svc $SINGLEMDS)
16628                 local var="${param%=*}"
16629                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16630
16631                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16632                 do_nodes $mdts $LCTL set_param mdd.*.$param
16633         done
16634
16635         # force cl_user2 to be idle (1st part)
16636         sleep 9
16637
16638         for i in $(seq $MDSCOUNT); do
16639                 cl_users=(${CL_USERS[mds$i]})
16640                 cl_user1[mds$i]="${cl_users[0]}"
16641                 cl_user2[mds$i]="${cl_users[1]}"
16642
16643                 [ -n "${cl_user1[mds$i]}" ] ||
16644                         error "mds$i: no user registered"
16645                 [ -n "${cl_user2[mds$i]}" ] ||
16646                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16647
16648                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16649                 [ -n "$user_rec1" ] ||
16650                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16651                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16652                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16653                 [ -n "$user_rec2" ] ||
16654                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16655                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16656                      "$user_rec1 + 2 == $user_rec2"
16657                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16658                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16659                               "$user_rec1 + 2, but is $user_rec2"
16660                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16661                 [ -n "$user_rec2" ] ||
16662                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16663                 [ $user_rec1 == $user_rec2 ] ||
16664                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16665                               "$user_rec1, but is $user_rec2"
16666         done
16667
16668         # force cl_user2 to be idle (2nd part) and to reach
16669         # changelog_max_idle_time
16670         sleep 2
16671
16672         # force each GC-thread start and block then
16673         # one per MDT/MDD, set fail_val accordingly
16674         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16675         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16676
16677         # generate more changelogs to trigger fail_loc
16678         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16679                 error "create $DIR/$tdir/${tfile}bis failed"
16680
16681         # stop MDT to stop GC-thread, should be done in back-ground as it will
16682         # block waiting for the thread to be released and exit
16683         declare -A stop_pids
16684         for i in $(seq $MDSCOUNT); do
16685                 stop mds$i &
16686                 stop_pids[mds$i]=$!
16687         done
16688
16689         for i in $(mdts_nodes); do
16690                 local facet
16691                 local nb=0
16692                 local facets=$(facets_up_on_host $i)
16693
16694                 for facet in ${facets//,/ }; do
16695                         if [[ $facet == mds* ]]; then
16696                                 nb=$((nb + 1))
16697                         fi
16698                 done
16699                 # ensure each MDS's gc threads are still present and all in "R"
16700                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16701                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16702                         error "$i: expected $nb GC-thread"
16703                 wait_update $i \
16704                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16705                         "R" 20 ||
16706                         error "$i: GC-thread not found in R-state"
16707                 # check umounts of each MDT on MDS have reached kthread_stop()
16708                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16709                         error "$i: expected $nb umount"
16710                 wait_update $i \
16711                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16712                         error "$i: umount not found in D-state"
16713         done
16714
16715         # release all GC-threads
16716         do_nodes $mdts $LCTL set_param fail_loc=0
16717
16718         # wait for MDT stop to complete
16719         for i in $(seq $MDSCOUNT); do
16720                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16721         done
16722
16723         # XXX
16724         # may try to check if any orphan changelog records are present
16725         # via ldiskfs/zfs and llog_reader...
16726
16727         # re-start/mount MDTs
16728         for i in $(seq $MDSCOUNT); do
16729                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16730                         error "Fail to start mds$i"
16731         done
16732
16733         local first_rec
16734         for i in $(seq $MDSCOUNT); do
16735                 # check cl_user1 still registered
16736                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16737                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16738                 # check cl_user2 unregistered
16739                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16740                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16741
16742                 # check changelogs are present and starting at $user_rec1 + 1
16743                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16744                 [ -n "$user_rec1" ] ||
16745                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16746                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16747                             awk '{ print $1; exit; }')
16748
16749                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16750                 [ $((user_rec1 + 1)) == $first_rec ] ||
16751                         error "mds$i: first index should be $user_rec1 + 1, " \
16752                               "but is $first_rec"
16753         done
16754 }
16755 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16756               "during mount"
16757
16758 test_160i() {
16759
16760         local mdts=$(comma_list $(mdts_nodes))
16761
16762         changelog_register || error "first changelog_register failed"
16763
16764         # generate some changelog records to accumulate on each MDT
16765         # use all_char because created files should be evenly distributed
16766         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16767                 error "test_mkdir $tdir failed"
16768         for ((i = 0; i < MDSCOUNT; i++)); do
16769                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16770                         error "create $DIR/$tdir/d$i.1 failed"
16771         done
16772
16773         # check changelogs have been generated
16774         local nbcl=$(changelog_dump | wc -l)
16775         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16776
16777         # simulate race between register and unregister
16778         # XXX as fail_loc is set per-MDS, with DNE configs the race
16779         # simulation will only occur for one MDT per MDS and for the
16780         # others the normal race scenario will take place
16781         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16782         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16783         do_nodes $mdts $LCTL set_param fail_val=1
16784
16785         # unregister 1st user
16786         changelog_deregister &
16787         local pid1=$!
16788         # wait some time for deregister work to reach race rdv
16789         sleep 2
16790         # register 2nd user
16791         changelog_register || error "2nd user register failed"
16792
16793         wait $pid1 || error "1st user deregister failed"
16794
16795         local i
16796         local last_rec
16797         declare -A LAST_REC
16798         for i in $(seq $MDSCOUNT); do
16799                 if changelog_users mds$i | grep "^cl"; then
16800                         # make sure new records are added with one user present
16801                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16802                                           awk '/^current.index:/ { print $NF }')
16803                 else
16804                         error "mds$i has no user registered"
16805                 fi
16806         done
16807
16808         # generate more changelog records to accumulate on each MDT
16809         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16810                 error "create $DIR/$tdir/${tfile}bis failed"
16811
16812         for i in $(seq $MDSCOUNT); do
16813                 last_rec=$(changelog_users $SINGLEMDS |
16814                            awk '/^current.index:/ { print $NF }')
16815                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16816                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16817                         error "changelogs are off on mds$i"
16818         done
16819 }
16820 run_test 160i "changelog user register/unregister race"
16821
16822 test_160j() {
16823         remote_mds_nodsh && skip "remote MDS with nodsh"
16824         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16825                 skip "Need MDS version at least 2.12.56"
16826
16827         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16828         stack_trap "umount $MOUNT2" EXIT
16829
16830         changelog_register || error "first changelog_register failed"
16831         stack_trap "changelog_deregister" EXIT
16832
16833         # generate some changelog
16834         # use all_char because created files should be evenly distributed
16835         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16836                 error "mkdir $tdir failed"
16837         for ((i = 0; i < MDSCOUNT; i++)); do
16838                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16839                         error "create $DIR/$tdir/d$i.1 failed"
16840         done
16841
16842         # open the changelog device
16843         exec 3>/dev/changelog-$FSNAME-MDT0000
16844         stack_trap "exec 3>&-" EXIT
16845         exec 4</dev/changelog-$FSNAME-MDT0000
16846         stack_trap "exec 4<&-" EXIT
16847
16848         # umount the first lustre mount
16849         umount $MOUNT
16850         stack_trap "mount_client $MOUNT" EXIT
16851
16852         # read changelog, which may or may not fail, but should not crash
16853         cat <&4 >/dev/null
16854
16855         # clear changelog
16856         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16857         changelog_users $SINGLEMDS | grep -q $cl_user ||
16858                 error "User $cl_user not found in changelog_users"
16859
16860         printf 'clear:'$cl_user':0' >&3
16861 }
16862 run_test 160j "client can be umounted while its chanangelog is being used"
16863
16864 test_160k() {
16865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16866         remote_mds_nodsh && skip "remote MDS with nodsh"
16867
16868         mkdir -p $DIR/$tdir/1/1
16869
16870         changelog_register || error "changelog_register failed"
16871         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16872
16873         changelog_users $SINGLEMDS | grep -q $cl_user ||
16874                 error "User '$cl_user' not found in changelog_users"
16875 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16876         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16877         rmdir $DIR/$tdir/1/1 & sleep 1
16878         mkdir $DIR/$tdir/2
16879         touch $DIR/$tdir/2/2
16880         rm -rf $DIR/$tdir/2
16881
16882         wait
16883         sleep 4
16884
16885         changelog_dump | grep rmdir || error "rmdir not recorded"
16886 }
16887 run_test 160k "Verify that changelog records are not lost"
16888
16889 # Verifies that a file passed as a parameter has recently had an operation
16890 # performed on it that has generated an MTIME changelog which contains the
16891 # correct parent FID. As files might reside on a different MDT from the
16892 # parent directory in DNE configurations, the FIDs are translated to paths
16893 # before being compared, which should be identical
16894 compare_mtime_changelog() {
16895         local file="${1}"
16896         local mdtidx
16897         local mtime
16898         local cl_fid
16899         local pdir
16900         local dir
16901
16902         mdtidx=$($LFS getstripe --mdt-index $file)
16903         mdtidx=$(printf "%04x" $mdtidx)
16904
16905         # Obtain the parent FID from the MTIME changelog
16906         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16907         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16908
16909         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16910         [ -z "$cl_fid" ] && error "parent FID not present"
16911
16912         # Verify that the path for the parent FID is the same as the path for
16913         # the test directory
16914         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16915
16916         dir=$(dirname $1)
16917
16918         [[ "${pdir%/}" == "$dir" ]] ||
16919                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16920 }
16921
16922 test_160l() {
16923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16924
16925         remote_mds_nodsh && skip "remote MDS with nodsh"
16926         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16927                 skip "Need MDS version at least 2.13.55"
16928
16929         local cl_user
16930
16931         changelog_register || error "changelog_register failed"
16932         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16933
16934         changelog_users $SINGLEMDS | grep -q $cl_user ||
16935                 error "User '$cl_user' not found in changelog_users"
16936
16937         # Clear some types so that MTIME changelogs are generated
16938         changelog_chmask "-CREAT"
16939         changelog_chmask "-CLOSE"
16940
16941         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16942
16943         # Test CL_MTIME during setattr
16944         touch $DIR/$tdir/$tfile
16945         compare_mtime_changelog $DIR/$tdir/$tfile
16946
16947         # Test CL_MTIME during close
16948         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16949         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16950 }
16951 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16952
16953 test_160m() {
16954         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16955         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16956                 skip "Need MDS version at least 2.14.51"
16957         local cl_users
16958         local cl_user1
16959         local cl_user2
16960         local pid1
16961
16962         # Create a user
16963         changelog_register || error "first changelog_register failed"
16964         changelog_register || error "second changelog_register failed"
16965
16966         cl_users=(${CL_USERS[mds1]})
16967         cl_user1="${cl_users[0]}"
16968         cl_user2="${cl_users[1]}"
16969         # generate some changelog records to accumulate on MDT0
16970         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16971         createmany -m $DIR/$tdir/$tfile 50 ||
16972                 error "create $DIR/$tdir/$tfile failed"
16973         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16974         rm -f $DIR/$tdir
16975
16976         # check changelogs have been generated
16977         local nbcl=$(changelog_dump | wc -l)
16978         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16979
16980 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16981         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16982
16983         __changelog_clear mds1 $cl_user1 +10
16984         __changelog_clear mds1 $cl_user2 0 &
16985         pid1=$!
16986         sleep 2
16987         __changelog_clear mds1 $cl_user1 0 ||
16988                 error "fail to cancel record for $cl_user1"
16989         wait $pid1
16990         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16991 }
16992 run_test 160m "Changelog clear race"
16993
16994 test_160n() {
16995         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16996         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16997                 skip "Need MDS version at least 2.14.51"
16998         local cl_users
16999         local cl_user1
17000         local cl_user2
17001         local pid1
17002         local first_rec
17003         local last_rec=0
17004
17005         # Create a user
17006         changelog_register || error "first changelog_register failed"
17007
17008         cl_users=(${CL_USERS[mds1]})
17009         cl_user1="${cl_users[0]}"
17010
17011         # generate some changelog records to accumulate on MDT0
17012         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17013         first_rec=$(changelog_users $SINGLEMDS |
17014                         awk '/^current.index:/ { print $NF }')
17015         while (( last_rec < (( first_rec + 65000)) )); do
17016                 createmany -m $DIR/$tdir/$tfile 10000 ||
17017                         error "create $DIR/$tdir/$tfile failed"
17018
17019                 for i in $(seq 0 10000); do
17020                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17021                                 > /dev/null
17022                 done
17023
17024                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17025                         error "unlinkmany failed unlink"
17026                 last_rec=$(changelog_users $SINGLEMDS |
17027                         awk '/^current.index:/ { print $NF }')
17028                 echo last record $last_rec
17029                 (( last_rec == 0 )) && error "no changelog found"
17030         done
17031
17032 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17033         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17034
17035         __changelog_clear mds1 $cl_user1 0 &
17036         pid1=$!
17037         sleep 2
17038         __changelog_clear mds1 $cl_user1 0 ||
17039                 error "fail to cancel record for $cl_user1"
17040         wait $pid1
17041         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17042 }
17043 run_test 160n "Changelog destroy race"
17044
17045 test_160o() {
17046         local mdt="$(facet_svc $SINGLEMDS)"
17047
17048         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17049         remote_mds_nodsh && skip "remote MDS with nodsh"
17050         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17051                 skip "Need MDS version at least 2.14.52"
17052
17053         changelog_register --user test_160o -m unlnk+close+open ||
17054                 error "changelog_register failed"
17055
17056         do_facet $SINGLEMDS $LCTL --device $mdt \
17057                                 changelog_register -u "Tt3_-#" &&
17058                 error "bad symbols in name should fail"
17059
17060         do_facet $SINGLEMDS $LCTL --device $mdt \
17061                                 changelog_register -u test_160o &&
17062                 error "the same name registration should fail"
17063
17064         do_facet $SINGLEMDS $LCTL --device $mdt \
17065                         changelog_register -u test_160toolongname &&
17066                 error "too long name registration should fail"
17067
17068         changelog_chmask "MARK+HSM"
17069         lctl get_param mdd.*.changelog*mask
17070         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17071         changelog_users $SINGLEMDS | grep -q $cl_user ||
17072                 error "User $cl_user not found in changelog_users"
17073         #verify username
17074         echo $cl_user | grep -q test_160o ||
17075                 error "User $cl_user has no specific name 'test160o'"
17076
17077         # change something
17078         changelog_clear 0 || error "changelog_clear failed"
17079         # generate some changelog records to accumulate on MDT0
17080         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17081         touch $DIR/$tdir/$tfile                 # open 1
17082
17083         OPENS=$(changelog_dump | grep -c "OPEN")
17084         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17085
17086         # must be no MKDIR it wasn't set as user mask
17087         MKDIR=$(changelog_dump | grep -c "MKDIR")
17088         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17089
17090         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17091                                 mdd.$mdt.changelog_current_mask -n)
17092         # register maskless user
17093         changelog_register || error "changelog_register failed"
17094         # effective mask should be not changed because it is not minimal
17095         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17096                                 mdd.$mdt.changelog_current_mask -n)
17097         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17098         # set server mask to minimal value
17099         changelog_chmask "MARK"
17100         # check effective mask again, should be treated as DEFMASK now
17101         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17102                                 mdd.$mdt.changelog_current_mask -n)
17103         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17104
17105         do_facet $SINGLEMDS $LCTL --device $mdt \
17106                                 changelog_deregister -u test_160o ||
17107                 error "cannot deregister by name"
17108 }
17109 run_test 160o "changelog user name and mask"
17110
17111 test_160p() {
17112         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17113         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17114                 skip "Need MDS version at least 2.14.51"
17115         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17116         local cl_users
17117         local cl_user1
17118         local entry_count
17119
17120         # Create a user
17121         changelog_register || error "first changelog_register failed"
17122
17123         cl_users=(${CL_USERS[mds1]})
17124         cl_user1="${cl_users[0]}"
17125
17126         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17127         createmany -m $DIR/$tdir/$tfile 50 ||
17128                 error "create $DIR/$tdir/$tfile failed"
17129         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17130         rm -rf $DIR/$tdir
17131
17132         # check changelogs have been generated
17133         entry_count=$(changelog_dump | wc -l)
17134         ((entry_count != 0)) || error "no changelog entries found"
17135
17136         # remove changelog_users and check that orphan entries are removed
17137         stop mds1
17138         local dev=$(mdsdevname 1)
17139         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17140         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17141         entry_count=$(changelog_dump | wc -l)
17142         ((entry_count == 0)) ||
17143                 error "found $entry_count changelog entries, expected none"
17144 }
17145 run_test 160p "Changelog orphan cleanup with no users"
17146
17147 test_160q() {
17148         local mdt="$(facet_svc $SINGLEMDS)"
17149         local clu
17150
17151         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17152         remote_mds_nodsh && skip "remote MDS with nodsh"
17153         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17154                 skip "Need MDS version at least 2.14.54"
17155
17156         # set server mask to minimal value like server init does
17157         changelog_chmask "MARK"
17158         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17159                 error "changelog_register failed"
17160         # check effective mask again, should be treated as DEFMASK now
17161         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17162                                 mdd.$mdt.changelog_current_mask -n)
17163         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17164                 error "changelog_deregister failed"
17165         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17166 }
17167 run_test 160q "changelog effective mask is DEFMASK if not set"
17168
17169 test_160s() {
17170         remote_mds_nodsh && skip "remote MDS with nodsh"
17171         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17172                 skip "Need MDS version at least 2.14.55"
17173
17174         local mdts=$(comma_list $(mdts_nodes))
17175
17176         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17177         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17178                                        fail_val=$((24 * 3600 * 10))
17179
17180         # Create a user which is 10 days old
17181         changelog_register || error "first changelog_register failed"
17182         local cl_users
17183         declare -A cl_user1
17184         local i
17185
17186         # generate some changelog records to accumulate on each MDT
17187         # use all_char because created files should be evenly distributed
17188         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17189                 error "test_mkdir $tdir failed"
17190         for ((i = 0; i < MDSCOUNT; i++)); do
17191                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17192                         error "create $DIR/$tdir/d$i.1 failed"
17193         done
17194
17195         # check changelogs have been generated
17196         local nbcl=$(changelog_dump | wc -l)
17197         (( nbcl > 0 )) || error "no changelogs found"
17198
17199         # reduce the max_idle_indexes value to make sure we exceed it
17200         for param in "changelog_max_idle_indexes=2097446912" \
17201                      "changelog_max_idle_time=2592000" \
17202                      "changelog_gc=1" \
17203                      "changelog_min_gc_interval=2"; do
17204                 local MDT0=$(facet_svc $SINGLEMDS)
17205                 local var="${param%=*}"
17206                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17207
17208                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17209                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17210                         error "unable to set mdd.*.$param"
17211         done
17212
17213         local start=$SECONDS
17214         for i in $(seq $MDSCOUNT); do
17215                 cl_users=(${CL_USERS[mds$i]})
17216                 cl_user1[mds$i]="${cl_users[0]}"
17217
17218                 [[ -n "${cl_user1[mds$i]}" ]] ||
17219                         error "mds$i: no user registered"
17220         done
17221
17222         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17223         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17224
17225         # ensure we are past the previous changelog_min_gc_interval set above
17226         local sleep2=$((start + 2 - SECONDS))
17227         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17228
17229         # Generate one more changelog to trigger GC
17230         for ((i = 0; i < MDSCOUNT; i++)); do
17231                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17232                         error "create $DIR/$tdir/d$i.3 failed"
17233         done
17234
17235         # ensure gc thread is done
17236         for node in $(mdts_nodes); do
17237                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17238                         error "$node: GC-thread not done"
17239         done
17240
17241         do_nodes $mdts $LCTL set_param fail_loc=0
17242
17243         for (( i = 1; i <= MDSCOUNT; i++ )); do
17244                 # check cl_user1 is purged
17245                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17246                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17247         done
17248         return 0
17249 }
17250 run_test 160s "changelog garbage collect on idle records * time"
17251
17252 test_160t() {
17253         remote_mds_nodsh && skip "remote MDS with nodsh"
17254         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17255                 skip "Need MDS version at least 2.15.50"
17256
17257         local MDT0=$(facet_svc $SINGLEMDS)
17258         local cl_users
17259         local cl_user1
17260         local cl_user2
17261         local start
17262
17263         changelog_register --user user1 -m all ||
17264                 error "user1 failed to register"
17265
17266         mkdir_on_mdt0 $DIR/$tdir
17267         # create default overstripe to maximize changelog size
17268         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17269         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17270         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17271
17272         # user2 consumes less records so less space
17273         changelog_register --user user2 || error "user2 failed to register"
17274         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17275         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17276
17277         # check changelogs have been generated
17278         local nbcl=$(changelog_dump | wc -l)
17279         (( nbcl > 0 )) || error "no changelogs found"
17280
17281         # reduce the changelog_min_gc_interval to force check
17282         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17283                 local var="${param%=*}"
17284                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17285
17286                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17287                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17288                         error "unable to set mdd.*.$param"
17289         done
17290
17291         start=$SECONDS
17292         cl_users=(${CL_USERS[mds1]})
17293         cl_user1="${cl_users[0]}"
17294         cl_user2="${cl_users[1]}"
17295
17296         [[ -n $cl_user1 ]] ||
17297                 error "mds1: user #1 isn't registered"
17298         [[ -n $cl_user2 ]] ||
17299                 error "mds1: user #2 isn't registered"
17300
17301         # ensure we are past the previous changelog_min_gc_interval set above
17302         local sleep2=$((start + 2 - SECONDS))
17303         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17304
17305         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17306         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17307                         fail_val=$(((llog_size1 + llog_size2) / 2))
17308
17309         # Generate more changelog to trigger GC
17310         createmany -o $DIR/$tdir/u3_ 4 ||
17311                 error "create failed for more files"
17312
17313         # ensure gc thread is done
17314         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17315                 error "mds1: GC-thread not done"
17316
17317         do_facet mds1 $LCTL set_param fail_loc=0
17318
17319         # check cl_user1 is purged
17320         changelog_users mds1 | grep -q "$cl_user1" &&
17321                 error "User $cl_user1 is registered"
17322         # check cl_user2 is not purged
17323         changelog_users mds1 | grep -q "$cl_user2" ||
17324                 error "User $cl_user2 is not registered"
17325 }
17326 run_test 160t "changelog garbage collect on lack of space"
17327
17328 test_161a() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330
17331         test_mkdir -c1 $DIR/$tdir
17332         cp /etc/hosts $DIR/$tdir/$tfile
17333         test_mkdir -c1 $DIR/$tdir/foo1
17334         test_mkdir -c1 $DIR/$tdir/foo2
17335         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17336         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17337         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17338         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17339         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17340         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17341                 $LFS fid2path $DIR $FID
17342                 error "bad link ea"
17343         fi
17344         # middle
17345         rm $DIR/$tdir/foo2/zachary
17346         # last
17347         rm $DIR/$tdir/foo2/thor
17348         # first
17349         rm $DIR/$tdir/$tfile
17350         # rename
17351         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17352         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17353                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17354         rm $DIR/$tdir/foo2/maggie
17355
17356         # overflow the EA
17357         local longname=$tfile.avg_len_is_thirty_two_
17358         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17359                 error_noexit 'failed to unlink many hardlinks'" EXIT
17360         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17361                 error "failed to hardlink many files"
17362         links=$($LFS fid2path $DIR $FID | wc -l)
17363         echo -n "${links}/1000 links in link EA"
17364         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17365 }
17366 run_test 161a "link ea sanity"
17367
17368 test_161b() {
17369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17370         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17371
17372         local MDTIDX=1
17373         local remote_dir=$DIR/$tdir/remote_dir
17374
17375         mkdir -p $DIR/$tdir
17376         $LFS mkdir -i $MDTIDX $remote_dir ||
17377                 error "create remote directory failed"
17378
17379         cp /etc/hosts $remote_dir/$tfile
17380         mkdir -p $remote_dir/foo1
17381         mkdir -p $remote_dir/foo2
17382         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17383         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17384         ln $remote_dir/$tfile $remote_dir/foo1/luna
17385         ln $remote_dir/$tfile $remote_dir/foo2/thor
17386
17387         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17388                      tr -d ']')
17389         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17390                 $LFS fid2path $DIR $FID
17391                 error "bad link ea"
17392         fi
17393         # middle
17394         rm $remote_dir/foo2/zachary
17395         # last
17396         rm $remote_dir/foo2/thor
17397         # first
17398         rm $remote_dir/$tfile
17399         # rename
17400         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17401         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17402         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17403                 $LFS fid2path $DIR $FID
17404                 error "bad link rename"
17405         fi
17406         rm $remote_dir/foo2/maggie
17407
17408         # overflow the EA
17409         local longname=filename_avg_len_is_thirty_two_
17410         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17411                 error "failed to hardlink many files"
17412         links=$($LFS fid2path $DIR $FID | wc -l)
17413         echo -n "${links}/1000 links in link EA"
17414         [[ ${links} -gt 60 ]] ||
17415                 error "expected at least 60 links in link EA"
17416         unlinkmany $remote_dir/foo2/$longname 1000 ||
17417         error "failed to unlink many hardlinks"
17418 }
17419 run_test 161b "link ea sanity under remote directory"
17420
17421 test_161c() {
17422         remote_mds_nodsh && skip "remote MDS with nodsh"
17423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17424         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17425                 skip "Need MDS version at least 2.1.5"
17426
17427         # define CLF_RENAME_LAST 0x0001
17428         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17429         changelog_register || error "changelog_register failed"
17430
17431         rm -rf $DIR/$tdir
17432         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17433         touch $DIR/$tdir/foo_161c
17434         touch $DIR/$tdir/bar_161c
17435         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17436         changelog_dump | grep RENME | tail -n 5
17437         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17438         changelog_clear 0 || error "changelog_clear failed"
17439         if [ x$flags != "x0x1" ]; then
17440                 error "flag $flags is not 0x1"
17441         fi
17442
17443         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17444         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17445         touch $DIR/$tdir/foo_161c
17446         touch $DIR/$tdir/bar_161c
17447         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17448         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17449         changelog_dump | grep RENME | tail -n 5
17450         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17451         changelog_clear 0 || error "changelog_clear failed"
17452         if [ x$flags != "x0x0" ]; then
17453                 error "flag $flags is not 0x0"
17454         fi
17455         echo "rename overwrite a target having nlink > 1," \
17456                 "changelog record has flags of $flags"
17457
17458         # rename doesn't overwrite a target (changelog flag 0x0)
17459         touch $DIR/$tdir/foo_161c
17460         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17461         changelog_dump | grep RENME | tail -n 5
17462         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17463         changelog_clear 0 || error "changelog_clear failed"
17464         if [ x$flags != "x0x0" ]; then
17465                 error "flag $flags is not 0x0"
17466         fi
17467         echo "rename doesn't overwrite a target," \
17468                 "changelog record has flags of $flags"
17469
17470         # define CLF_UNLINK_LAST 0x0001
17471         # unlink a file having nlink = 1 (changelog flag 0x1)
17472         rm -f $DIR/$tdir/foo2_161c
17473         changelog_dump | grep UNLNK | tail -n 5
17474         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17475         changelog_clear 0 || error "changelog_clear failed"
17476         if [ x$flags != "x0x1" ]; then
17477                 error "flag $flags is not 0x1"
17478         fi
17479         echo "unlink a file having nlink = 1," \
17480                 "changelog record has flags of $flags"
17481
17482         # unlink a file having nlink > 1 (changelog flag 0x0)
17483         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17484         rm -f $DIR/$tdir/foobar_161c
17485         changelog_dump | grep UNLNK | tail -n 5
17486         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17487         changelog_clear 0 || error "changelog_clear failed"
17488         if [ x$flags != "x0x0" ]; then
17489                 error "flag $flags is not 0x0"
17490         fi
17491         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17492 }
17493 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17494
17495 test_161d() {
17496         remote_mds_nodsh && skip "remote MDS with nodsh"
17497         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17498
17499         local pid
17500         local fid
17501
17502         changelog_register || error "changelog_register failed"
17503
17504         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17505         # interfer with $MOUNT/.lustre/fid/ access
17506         mkdir $DIR/$tdir
17507         [[ $? -eq 0 ]] || error "mkdir failed"
17508
17509         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17510         $LCTL set_param fail_loc=0x8000140c
17511         # 5s pause
17512         $LCTL set_param fail_val=5
17513
17514         # create file
17515         echo foofoo > $DIR/$tdir/$tfile &
17516         pid=$!
17517
17518         # wait for create to be delayed
17519         sleep 2
17520
17521         ps -p $pid
17522         [[ $? -eq 0 ]] || error "create should be blocked"
17523
17524         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17525         stack_trap "rm -f $tempfile"
17526         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17527         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17528         # some delay may occur during ChangeLog publishing and file read just
17529         # above, that could allow file write to happen finally
17530         [[ -s $tempfile ]] && echo "file should be empty"
17531
17532         $LCTL set_param fail_loc=0
17533
17534         wait $pid
17535         [[ $? -eq 0 ]] || error "create failed"
17536 }
17537 run_test 161d "create with concurrent .lustre/fid access"
17538
17539 check_path() {
17540         local expected="$1"
17541         shift
17542         local fid="$2"
17543
17544         local path
17545         path=$($LFS fid2path "$@")
17546         local rc=$?
17547
17548         if [ $rc -ne 0 ]; then
17549                 error "path looked up of '$expected' failed: rc=$rc"
17550         elif [ "$path" != "$expected" ]; then
17551                 error "path looked up '$path' instead of '$expected'"
17552         else
17553                 echo "FID '$fid' resolves to path '$path' as expected"
17554         fi
17555 }
17556
17557 test_162a() { # was test_162
17558         test_mkdir -p -c1 $DIR/$tdir/d2
17559         touch $DIR/$tdir/d2/$tfile
17560         touch $DIR/$tdir/d2/x1
17561         touch $DIR/$tdir/d2/x2
17562         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17563         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17564         # regular file
17565         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17566         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17567
17568         # softlink
17569         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17570         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17571         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17572
17573         # softlink to wrong file
17574         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17575         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17576         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17577
17578         # hardlink
17579         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17580         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17581         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17582         # fid2path dir/fsname should both work
17583         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17584         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17585
17586         # hardlink count: check that there are 2 links
17587         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17588         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17589
17590         # hardlink indexing: remove the first link
17591         rm $DIR/$tdir/d2/p/q/r/hlink
17592         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17593 }
17594 run_test 162a "path lookup sanity"
17595
17596 test_162b() {
17597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17599
17600         mkdir $DIR/$tdir
17601         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17602                                 error "create striped dir failed"
17603
17604         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17605                                         tail -n 1 | awk '{print $2}')
17606         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17607
17608         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17609         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17610
17611         # regular file
17612         for ((i=0;i<5;i++)); do
17613                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17614                         error "get fid for f$i failed"
17615                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17616
17617                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17618                         error "get fid for d$i failed"
17619                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17620         done
17621
17622         return 0
17623 }
17624 run_test 162b "striped directory path lookup sanity"
17625
17626 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17627 test_162c() {
17628         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17629                 skip "Need MDS version at least 2.7.51"
17630
17631         local lpath=$tdir.local
17632         local rpath=$tdir.remote
17633
17634         test_mkdir $DIR/$lpath
17635         test_mkdir $DIR/$rpath
17636
17637         for ((i = 0; i <= 101; i++)); do
17638                 lpath="$lpath/$i"
17639                 mkdir $DIR/$lpath
17640                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17641                         error "get fid for local directory $DIR/$lpath failed"
17642                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17643
17644                 rpath="$rpath/$i"
17645                 test_mkdir $DIR/$rpath
17646                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17647                         error "get fid for remote directory $DIR/$rpath failed"
17648                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17649         done
17650
17651         return 0
17652 }
17653 run_test 162c "fid2path works with paths 100 or more directories deep"
17654
17655 oalr_event_count() {
17656         local event="${1}"
17657         local trace="${2}"
17658
17659         awk -v name="${FSNAME}-OST0000" \
17660             -v event="${event}" \
17661             '$1 == "TRACE" && $2 == event && $3 == name' \
17662             "${trace}" |
17663         wc -l
17664 }
17665
17666 oalr_expect_event_count() {
17667         local event="${1}"
17668         local trace="${2}"
17669         local expect="${3}"
17670         local count
17671
17672         count=$(oalr_event_count "${event}" "${trace}")
17673         if ((count == expect)); then
17674                 return 0
17675         fi
17676
17677         error_noexit "${event} event count was '${count}', expected ${expect}"
17678         cat "${trace}" >&2
17679         exit 1
17680 }
17681
17682 cleanup_165() {
17683         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17684         stop ost1
17685         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17686 }
17687
17688 setup_165() {
17689         sync # Flush previous IOs so we can count log entries.
17690         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17691         stack_trap cleanup_165 EXIT
17692 }
17693
17694 test_165a() {
17695         local trace="/tmp/${tfile}.trace"
17696         local rc
17697         local count
17698
17699         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17700                 skip "OFD access log unsupported"
17701
17702         setup_165
17703         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17704         sleep 5
17705
17706         do_facet ost1 ofd_access_log_reader --list
17707         stop ost1
17708
17709         do_facet ost1 killall -TERM ofd_access_log_reader
17710         wait
17711         rc=$?
17712
17713         if ((rc != 0)); then
17714                 error "ofd_access_log_reader exited with rc = '${rc}'"
17715         fi
17716
17717         # Parse trace file for discovery events:
17718         oalr_expect_event_count alr_log_add "${trace}" 1
17719         oalr_expect_event_count alr_log_eof "${trace}" 1
17720         oalr_expect_event_count alr_log_free "${trace}" 1
17721 }
17722 run_test 165a "ofd access log discovery"
17723
17724 test_165b() {
17725         local trace="/tmp/${tfile}.trace"
17726         local file="${DIR}/${tfile}"
17727         local pfid1
17728         local pfid2
17729         local -a entry
17730         local rc
17731         local count
17732         local size
17733         local flags
17734
17735         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17736                 skip "OFD access log unsupported"
17737
17738         setup_165
17739         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17740         sleep 5
17741
17742         do_facet ost1 ofd_access_log_reader --list
17743
17744         lfs setstripe -c 1 -i 0 "${file}"
17745         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17746                 error "cannot create '${file}'"
17747
17748         sleep 5
17749         do_facet ost1 killall -TERM ofd_access_log_reader
17750         wait
17751         rc=$?
17752
17753         if ((rc != 0)); then
17754                 error "ofd_access_log_reader exited with rc = '${rc}'"
17755         fi
17756
17757         oalr_expect_event_count alr_log_entry "${trace}" 1
17758
17759         pfid1=$($LFS path2fid "${file}")
17760
17761         # 1     2             3   4    5     6   7    8    9     10
17762         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17763         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17764
17765         echo "entry = '${entry[*]}'" >&2
17766
17767         pfid2=${entry[4]}
17768         if [[ "${pfid1}" != "${pfid2}" ]]; then
17769                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17770         fi
17771
17772         size=${entry[8]}
17773         if ((size != 1048576)); then
17774                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17775         fi
17776
17777         flags=${entry[10]}
17778         if [[ "${flags}" != "w" ]]; then
17779                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17780         fi
17781
17782         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17783         sleep 5
17784
17785         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17786                 error "cannot read '${file}'"
17787         sleep 5
17788
17789         do_facet ost1 killall -TERM ofd_access_log_reader
17790         wait
17791         rc=$?
17792
17793         if ((rc != 0)); then
17794                 error "ofd_access_log_reader exited with rc = '${rc}'"
17795         fi
17796
17797         oalr_expect_event_count alr_log_entry "${trace}" 1
17798
17799         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17800         echo "entry = '${entry[*]}'" >&2
17801
17802         pfid2=${entry[4]}
17803         if [[ "${pfid1}" != "${pfid2}" ]]; then
17804                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17805         fi
17806
17807         size=${entry[8]}
17808         if ((size != 524288)); then
17809                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17810         fi
17811
17812         flags=${entry[10]}
17813         if [[ "${flags}" != "r" ]]; then
17814                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17815         fi
17816 }
17817 run_test 165b "ofd access log entries are produced and consumed"
17818
17819 test_165c() {
17820         local trace="/tmp/${tfile}.trace"
17821         local file="${DIR}/${tdir}/${tfile}"
17822
17823         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17824                 skip "OFD access log unsupported"
17825
17826         test_mkdir "${DIR}/${tdir}"
17827
17828         setup_165
17829         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17830         sleep 5
17831
17832         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17833
17834         # 4096 / 64 = 64. Create twice as many entries.
17835         for ((i = 0; i < 128; i++)); do
17836                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17837                         error "cannot create file"
17838         done
17839
17840         sync
17841
17842         do_facet ost1 killall -TERM ofd_access_log_reader
17843         wait
17844         rc=$?
17845         if ((rc != 0)); then
17846                 error "ofd_access_log_reader exited with rc = '${rc}'"
17847         fi
17848
17849         unlinkmany  "${file}-%d" 128
17850 }
17851 run_test 165c "full ofd access logs do not block IOs"
17852
17853 oal_get_read_count() {
17854         local stats="$1"
17855
17856         # STATS lustre-OST0001 alr_read_count 1
17857
17858         do_facet ost1 cat "${stats}" |
17859         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17860              END { print count; }'
17861 }
17862
17863 oal_expect_read_count() {
17864         local stats="$1"
17865         local count
17866         local expect="$2"
17867
17868         # Ask ofd_access_log_reader to write stats.
17869         do_facet ost1 killall -USR1 ofd_access_log_reader
17870
17871         # Allow some time for things to happen.
17872         sleep 1
17873
17874         count=$(oal_get_read_count "${stats}")
17875         if ((count == expect)); then
17876                 return 0
17877         fi
17878
17879         error_noexit "bad read count, got ${count}, expected ${expect}"
17880         do_facet ost1 cat "${stats}" >&2
17881         exit 1
17882 }
17883
17884 test_165d() {
17885         local stats="/tmp/${tfile}.stats"
17886         local file="${DIR}/${tdir}/${tfile}"
17887         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17888
17889         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17890                 skip "OFD access log unsupported"
17891
17892         test_mkdir "${DIR}/${tdir}"
17893
17894         setup_165
17895         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17896         sleep 5
17897
17898         lfs setstripe -c 1 -i 0 "${file}"
17899
17900         do_facet ost1 lctl set_param "${param}=rw"
17901         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17902                 error "cannot create '${file}'"
17903         oal_expect_read_count "${stats}" 1
17904
17905         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17906                 error "cannot read '${file}'"
17907         oal_expect_read_count "${stats}" 2
17908
17909         do_facet ost1 lctl set_param "${param}=r"
17910         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17911                 error "cannot create '${file}'"
17912         oal_expect_read_count "${stats}" 2
17913
17914         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17915                 error "cannot read '${file}'"
17916         oal_expect_read_count "${stats}" 3
17917
17918         do_facet ost1 lctl set_param "${param}=w"
17919         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17920                 error "cannot create '${file}'"
17921         oal_expect_read_count "${stats}" 4
17922
17923         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17924                 error "cannot read '${file}'"
17925         oal_expect_read_count "${stats}" 4
17926
17927         do_facet ost1 lctl set_param "${param}=0"
17928         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17929                 error "cannot create '${file}'"
17930         oal_expect_read_count "${stats}" 4
17931
17932         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17933                 error "cannot read '${file}'"
17934         oal_expect_read_count "${stats}" 4
17935
17936         do_facet ost1 killall -TERM ofd_access_log_reader
17937         wait
17938         rc=$?
17939         if ((rc != 0)); then
17940                 error "ofd_access_log_reader exited with rc = '${rc}'"
17941         fi
17942 }
17943 run_test 165d "ofd_access_log mask works"
17944
17945 test_165e() {
17946         local stats="/tmp/${tfile}.stats"
17947         local file0="${DIR}/${tdir}-0/${tfile}"
17948         local file1="${DIR}/${tdir}-1/${tfile}"
17949
17950         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17951                 skip "OFD access log unsupported"
17952
17953         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17954
17955         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17956         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17957
17958         lfs setstripe -c 1 -i 0 "${file0}"
17959         lfs setstripe -c 1 -i 0 "${file1}"
17960
17961         setup_165
17962         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17963         sleep 5
17964
17965         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17966                 error "cannot create '${file0}'"
17967         sync
17968         oal_expect_read_count "${stats}" 0
17969
17970         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17971                 error "cannot create '${file1}'"
17972         sync
17973         oal_expect_read_count "${stats}" 1
17974
17975         do_facet ost1 killall -TERM ofd_access_log_reader
17976         wait
17977         rc=$?
17978         if ((rc != 0)); then
17979                 error "ofd_access_log_reader exited with rc = '${rc}'"
17980         fi
17981 }
17982 run_test 165e "ofd_access_log MDT index filter works"
17983
17984 test_165f() {
17985         local trace="/tmp/${tfile}.trace"
17986         local rc
17987         local count
17988
17989         setup_165
17990         do_facet ost1 timeout 60 ofd_access_log_reader \
17991                 --exit-on-close --debug=- --trace=- > "${trace}" &
17992         sleep 5
17993         stop ost1
17994
17995         wait
17996         rc=$?
17997
17998         if ((rc != 0)); then
17999                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18000                 cat "${trace}"
18001                 exit 1
18002         fi
18003 }
18004 run_test 165f "ofd_access_log_reader --exit-on-close works"
18005
18006 test_169() {
18007         # do directio so as not to populate the page cache
18008         log "creating a 10 Mb file"
18009         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18010                 error "multiop failed while creating a file"
18011         log "starting reads"
18012         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18013         log "truncating the file"
18014         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18015                 error "multiop failed while truncating the file"
18016         log "killing dd"
18017         kill %+ || true # reads might have finished
18018         echo "wait until dd is finished"
18019         wait
18020         log "removing the temporary file"
18021         rm -rf $DIR/$tfile || error "tmp file removal failed"
18022 }
18023 run_test 169 "parallel read and truncate should not deadlock"
18024
18025 test_170() {
18026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18027
18028         $LCTL clear     # bug 18514
18029         $LCTL debug_daemon start $TMP/${tfile}_log_good
18030         touch $DIR/$tfile
18031         $LCTL debug_daemon stop
18032         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18033                 error "sed failed to read log_good"
18034
18035         $LCTL debug_daemon start $TMP/${tfile}_log_good
18036         rm -rf $DIR/$tfile
18037         $LCTL debug_daemon stop
18038
18039         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18040                error "lctl df log_bad failed"
18041
18042         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18043         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18044
18045         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18046         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18047
18048         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18049                 error "bad_line good_line1 good_line2 are empty"
18050
18051         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18052         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18053         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18054
18055         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18056         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18057         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18058
18059         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18060                 error "bad_line_new good_line_new are empty"
18061
18062         local expected_good=$((good_line1 + good_line2*2))
18063
18064         rm -f $TMP/${tfile}*
18065         # LU-231, short malformed line may not be counted into bad lines
18066         if [ $bad_line -ne $bad_line_new ] &&
18067                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18068                 error "expected $bad_line bad lines, but got $bad_line_new"
18069                 return 1
18070         fi
18071
18072         if [ $expected_good -ne $good_line_new ]; then
18073                 error "expected $expected_good good lines, but got $good_line_new"
18074                 return 2
18075         fi
18076         true
18077 }
18078 run_test 170 "test lctl df to handle corrupted log ====================="
18079
18080 test_171() { # bug20592
18081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18082
18083         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18084         $LCTL set_param fail_loc=0x50e
18085         $LCTL set_param fail_val=3000
18086         multiop_bg_pause $DIR/$tfile O_s || true
18087         local MULTIPID=$!
18088         kill -USR1 $MULTIPID
18089         # cause log dump
18090         sleep 3
18091         wait $MULTIPID
18092         if dmesg | grep "recursive fault"; then
18093                 error "caught a recursive fault"
18094         fi
18095         $LCTL set_param fail_loc=0
18096         true
18097 }
18098 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18099
18100 test_172() {
18101
18102         #define OBD_FAIL_OBD_CLEANUP  0x60e
18103         $LCTL set_param fail_loc=0x60e
18104         umount $MOUNT || error "umount $MOUNT failed"
18105         stack_trap "mount_client $MOUNT"
18106
18107         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18108                 error "no client OBDs are remained"
18109
18110         $LCTL dl | while read devno state type name foo; do
18111                 case $type in
18112                 lov|osc|lmv|mdc)
18113                         $LCTL --device $name cleanup
18114                         $LCTL --device $name detach
18115                         ;;
18116                 *)
18117                         # skip server devices
18118                         ;;
18119                 esac
18120         done
18121
18122         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18123                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18124                 error "some client OBDs are still remained"
18125         fi
18126
18127 }
18128 run_test 172 "manual device removal with lctl cleanup/detach ======"
18129
18130 # it would be good to share it with obdfilter-survey/iokit-libecho code
18131 setup_obdecho_osc () {
18132         local rc=0
18133         local ost_nid=$1
18134         local obdfilter_name=$2
18135         echo "Creating new osc for $obdfilter_name on $ost_nid"
18136         # make sure we can find loopback nid
18137         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18138
18139         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18140                            ${obdfilter_name}_osc_UUID || rc=2; }
18141         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18142                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18143         return $rc
18144 }
18145
18146 cleanup_obdecho_osc () {
18147         local obdfilter_name=$1
18148         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18149         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18150         return 0
18151 }
18152
18153 obdecho_test() {
18154         local OBD=$1
18155         local node=$2
18156         local pages=${3:-64}
18157         local rc=0
18158         local id
18159
18160         local count=10
18161         local obd_size=$(get_obd_size $node $OBD)
18162         local page_size=$(get_page_size $node)
18163         if [[ -n "$obd_size" ]]; then
18164                 local new_count=$((obd_size / (pages * page_size / 1024)))
18165                 [[ $new_count -ge $count ]] || count=$new_count
18166         fi
18167
18168         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18169         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18170                            rc=2; }
18171         if [ $rc -eq 0 ]; then
18172             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18173             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18174         fi
18175         echo "New object id is $id"
18176         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18177                            rc=4; }
18178         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18179                            "test_brw $count w v $pages $id" || rc=4; }
18180         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18181                            rc=4; }
18182         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18183                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18184         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18185                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18186         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18187         return $rc
18188 }
18189
18190 test_180a() {
18191         skip "obdecho on osc is no longer supported"
18192 }
18193 run_test 180a "test obdecho on osc"
18194
18195 test_180b() {
18196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18197         remote_ost_nodsh && skip "remote OST with nodsh"
18198
18199         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18200                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18201                 error "failed to load module obdecho"
18202
18203         local target=$(do_facet ost1 $LCTL dl |
18204                        awk '/obdfilter/ { print $4; exit; }')
18205
18206         if [ -n "$target" ]; then
18207                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18208         else
18209                 do_facet ost1 $LCTL dl
18210                 error "there is no obdfilter target on ost1"
18211         fi
18212 }
18213 run_test 180b "test obdecho directly on obdfilter"
18214
18215 test_180c() { # LU-2598
18216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18217         remote_ost_nodsh && skip "remote OST with nodsh"
18218         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18219                 skip "Need MDS version at least 2.4.0"
18220
18221         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18222                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18223                 error "failed to load module obdecho"
18224
18225         local target=$(do_facet ost1 $LCTL dl |
18226                        awk '/obdfilter/ { print $4; exit; }')
18227
18228         if [ -n "$target" ]; then
18229                 local pages=16384 # 64MB bulk I/O RPC size
18230
18231                 obdecho_test "$target" ost1 "$pages" ||
18232                         error "obdecho_test with pages=$pages failed with $?"
18233         else
18234                 do_facet ost1 $LCTL dl
18235                 error "there is no obdfilter target on ost1"
18236         fi
18237 }
18238 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18239
18240 test_181() { # bug 22177
18241         test_mkdir $DIR/$tdir
18242         # create enough files to index the directory
18243         createmany -o $DIR/$tdir/foobar 4000
18244         # print attributes for debug purpose
18245         lsattr -d .
18246         # open dir
18247         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18248         MULTIPID=$!
18249         # remove the files & current working dir
18250         unlinkmany $DIR/$tdir/foobar 4000
18251         rmdir $DIR/$tdir
18252         kill -USR1 $MULTIPID
18253         wait $MULTIPID
18254         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18255         return 0
18256 }
18257 run_test 181 "Test open-unlinked dir ========================"
18258
18259 test_182a() {
18260         local fcount=1000
18261         local tcount=10
18262
18263         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18264
18265         $LCTL set_param mdc.*.rpc_stats=clear
18266
18267         for (( i = 0; i < $tcount; i++ )) ; do
18268                 mkdir $DIR/$tdir/$i
18269         done
18270
18271         for (( i = 0; i < $tcount; i++ )) ; do
18272                 createmany -o $DIR/$tdir/$i/f- $fcount &
18273         done
18274         wait
18275
18276         for (( i = 0; i < $tcount; i++ )) ; do
18277                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18278         done
18279         wait
18280
18281         $LCTL get_param mdc.*.rpc_stats
18282
18283         rm -rf $DIR/$tdir
18284 }
18285 run_test 182a "Test parallel modify metadata operations from mdc"
18286
18287 test_182b() {
18288         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18289         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18290         local dcount=1000
18291         local tcount=10
18292         local stime
18293         local etime
18294         local delta
18295
18296         do_facet mds1 $LCTL list_param \
18297                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18298                 skip "MDS lacks parallel RPC handling"
18299
18300         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18301
18302         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18303                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18304
18305         stime=$(date +%s)
18306         createmany -i 0 -d $DIR/$tdir/t- $tcount
18307
18308         for (( i = 0; i < $tcount; i++ )) ; do
18309                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18310         done
18311         wait
18312         etime=$(date +%s)
18313         delta=$((etime - stime))
18314         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18315
18316         stime=$(date +%s)
18317         for (( i = 0; i < $tcount; i++ )) ; do
18318                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18319         done
18320         wait
18321         etime=$(date +%s)
18322         delta=$((etime - stime))
18323         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18324
18325         rm -rf $DIR/$tdir
18326
18327         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18328
18329         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18330
18331         stime=$(date +%s)
18332         createmany -i 0 -d $DIR/$tdir/t- $tcount
18333
18334         for (( i = 0; i < $tcount; i++ )) ; do
18335                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18336         done
18337         wait
18338         etime=$(date +%s)
18339         delta=$((etime - stime))
18340         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18341
18342         stime=$(date +%s)
18343         for (( i = 0; i < $tcount; i++ )) ; do
18344                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18345         done
18346         wait
18347         etime=$(date +%s)
18348         delta=$((etime - stime))
18349         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18350
18351         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18352 }
18353 run_test 182b "Test parallel modify metadata operations from osp"
18354
18355 test_183() { # LU-2275
18356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18357         remote_mds_nodsh && skip "remote MDS with nodsh"
18358         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18359                 skip "Need MDS version at least 2.3.56"
18360
18361         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18362         echo aaa > $DIR/$tdir/$tfile
18363
18364 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18365         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18366
18367         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18368         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18369
18370         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18371
18372         # Flush negative dentry cache
18373         touch $DIR/$tdir/$tfile
18374
18375         # We are not checking for any leaked references here, they'll
18376         # become evident next time we do cleanup with module unload.
18377         rm -rf $DIR/$tdir
18378 }
18379 run_test 183 "No crash or request leak in case of strange dispositions ========"
18380
18381 # test suite 184 is for LU-2016, LU-2017
18382 test_184a() {
18383         check_swap_layouts_support
18384
18385         dir0=$DIR/$tdir/$testnum
18386         test_mkdir -p -c1 $dir0
18387         ref1=/etc/passwd
18388         ref2=/etc/group
18389         file1=$dir0/f1
18390         file2=$dir0/f2
18391         $LFS setstripe -c1 $file1
18392         cp $ref1 $file1
18393         $LFS setstripe -c2 $file2
18394         cp $ref2 $file2
18395         gen1=$($LFS getstripe -g $file1)
18396         gen2=$($LFS getstripe -g $file2)
18397
18398         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18399         gen=$($LFS getstripe -g $file1)
18400         [[ $gen1 != $gen ]] ||
18401                 error "Layout generation on $file1 does not change"
18402         gen=$($LFS getstripe -g $file2)
18403         [[ $gen2 != $gen ]] ||
18404                 error "Layout generation on $file2 does not change"
18405
18406         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18407         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18408
18409         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18410 }
18411 run_test 184a "Basic layout swap"
18412
18413 test_184b() {
18414         check_swap_layouts_support
18415
18416         dir0=$DIR/$tdir/$testnum
18417         mkdir -p $dir0 || error "creating dir $dir0"
18418         file1=$dir0/f1
18419         file2=$dir0/f2
18420         file3=$dir0/f3
18421         dir1=$dir0/d1
18422         dir2=$dir0/d2
18423         mkdir $dir1 $dir2
18424         $LFS setstripe -c1 $file1
18425         $LFS setstripe -c2 $file2
18426         $LFS setstripe -c1 $file3
18427         chown $RUNAS_ID $file3
18428         gen1=$($LFS getstripe -g $file1)
18429         gen2=$($LFS getstripe -g $file2)
18430
18431         $LFS swap_layouts $dir1 $dir2 &&
18432                 error "swap of directories layouts should fail"
18433         $LFS swap_layouts $dir1 $file1 &&
18434                 error "swap of directory and file layouts should fail"
18435         $RUNAS $LFS swap_layouts $file1 $file2 &&
18436                 error "swap of file we cannot write should fail"
18437         $LFS swap_layouts $file1 $file3 &&
18438                 error "swap of file with different owner should fail"
18439         /bin/true # to clear error code
18440 }
18441 run_test 184b "Forbidden layout swap (will generate errors)"
18442
18443 test_184c() {
18444         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18445         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18446         check_swap_layouts_support
18447         check_swap_layout_no_dom $DIR
18448
18449         local dir0=$DIR/$tdir/$testnum
18450         mkdir -p $dir0 || error "creating dir $dir0"
18451
18452         local ref1=$dir0/ref1
18453         local ref2=$dir0/ref2
18454         local file1=$dir0/file1
18455         local file2=$dir0/file2
18456         # create a file large enough for the concurrent test
18457         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18458         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18459         echo "ref file size: ref1($(stat -c %s $ref1))," \
18460              "ref2($(stat -c %s $ref2))"
18461
18462         cp $ref2 $file2
18463         dd if=$ref1 of=$file1 bs=16k &
18464         local DD_PID=$!
18465
18466         # Make sure dd starts to copy file, but wait at most 5 seconds
18467         local loops=0
18468         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18469
18470         $LFS swap_layouts $file1 $file2
18471         local rc=$?
18472         wait $DD_PID
18473         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18474         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18475
18476         # how many bytes copied before swapping layout
18477         local copied=$(stat -c %s $file2)
18478         local remaining=$(stat -c %s $ref1)
18479         remaining=$((remaining - copied))
18480         echo "Copied $copied bytes before swapping layout..."
18481
18482         cmp -n $copied $file1 $ref2 | grep differ &&
18483                 error "Content mismatch [0, $copied) of ref2 and file1"
18484         cmp -n $copied $file2 $ref1 ||
18485                 error "Content mismatch [0, $copied) of ref1 and file2"
18486         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18487                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18488
18489         # clean up
18490         rm -f $ref1 $ref2 $file1 $file2
18491 }
18492 run_test 184c "Concurrent write and layout swap"
18493
18494 test_184d() {
18495         check_swap_layouts_support
18496         check_swap_layout_no_dom $DIR
18497         [ -z "$(which getfattr 2>/dev/null)" ] &&
18498                 skip_env "no getfattr command"
18499
18500         local file1=$DIR/$tdir/$tfile-1
18501         local file2=$DIR/$tdir/$tfile-2
18502         local file3=$DIR/$tdir/$tfile-3
18503         local lovea1
18504         local lovea2
18505
18506         mkdir -p $DIR/$tdir
18507         touch $file1 || error "create $file1 failed"
18508         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18509                 error "create $file2 failed"
18510         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18511                 error "create $file3 failed"
18512         lovea1=$(get_layout_param $file1)
18513
18514         $LFS swap_layouts $file2 $file3 ||
18515                 error "swap $file2 $file3 layouts failed"
18516         $LFS swap_layouts $file1 $file2 ||
18517                 error "swap $file1 $file2 layouts failed"
18518
18519         lovea2=$(get_layout_param $file2)
18520         echo "$lovea1"
18521         echo "$lovea2"
18522         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18523
18524         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18525         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18526 }
18527 run_test 184d "allow stripeless layouts swap"
18528
18529 test_184e() {
18530         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18531                 skip "Need MDS version at least 2.6.94"
18532         check_swap_layouts_support
18533         check_swap_layout_no_dom $DIR
18534         [ -z "$(which getfattr 2>/dev/null)" ] &&
18535                 skip_env "no getfattr command"
18536
18537         local file1=$DIR/$tdir/$tfile-1
18538         local file2=$DIR/$tdir/$tfile-2
18539         local file3=$DIR/$tdir/$tfile-3
18540         local lovea
18541
18542         mkdir -p $DIR/$tdir
18543         touch $file1 || error "create $file1 failed"
18544         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18545                 error "create $file2 failed"
18546         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18547                 error "create $file3 failed"
18548
18549         $LFS swap_layouts $file1 $file2 ||
18550                 error "swap $file1 $file2 layouts failed"
18551
18552         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18553         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18554
18555         echo 123 > $file1 || error "Should be able to write into $file1"
18556
18557         $LFS swap_layouts $file1 $file3 ||
18558                 error "swap $file1 $file3 layouts failed"
18559
18560         echo 123 > $file1 || error "Should be able to write into $file1"
18561
18562         rm -rf $file1 $file2 $file3
18563 }
18564 run_test 184e "Recreate layout after stripeless layout swaps"
18565
18566 test_184f() {
18567         # Create a file with name longer than sizeof(struct stat) ==
18568         # 144 to see if we can get chars from the file name to appear
18569         # in the returned striping. Note that 'f' == 0x66.
18570         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18571
18572         mkdir -p $DIR/$tdir
18573         mcreate $DIR/$tdir/$file
18574         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18575                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18576         fi
18577 }
18578 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18579
18580 test_185() { # LU-2441
18581         # LU-3553 - no volatile file support in old servers
18582         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18583                 skip "Need MDS version at least 2.3.60"
18584
18585         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18586         touch $DIR/$tdir/spoo
18587         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18588         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18589                 error "cannot create/write a volatile file"
18590         [ "$FILESET" == "" ] &&
18591         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18592                 error "FID is still valid after close"
18593
18594         multiop_bg_pause $DIR/$tdir vVw4096_c
18595         local multi_pid=$!
18596
18597         local OLD_IFS=$IFS
18598         IFS=":"
18599         local fidv=($fid)
18600         IFS=$OLD_IFS
18601         # assume that the next FID for this client is sequential, since stdout
18602         # is unfortunately eaten by multiop_bg_pause
18603         local n=$((${fidv[1]} + 1))
18604         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18605         if [ "$FILESET" == "" ]; then
18606                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18607                         error "FID is missing before close"
18608         fi
18609         kill -USR1 $multi_pid
18610         # 1 second delay, so if mtime change we will see it
18611         sleep 1
18612         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18613         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18614 }
18615 run_test 185 "Volatile file support"
18616
18617 function create_check_volatile() {
18618         local idx=$1
18619         local tgt
18620
18621         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18622         local PID=$!
18623         sleep 1
18624         local FID=$(cat /tmp/${tfile}.fid)
18625         [ "$FID" == "" ] && error "can't get FID for volatile"
18626         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18627         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18628         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18629         kill -USR1 $PID
18630         wait
18631         sleep 1
18632         cancel_lru_locks mdc # flush opencache
18633         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18634         return 0
18635 }
18636
18637 test_185a(){
18638         # LU-12516 - volatile creation via .lustre
18639         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18640                 skip "Need MDS version at least 2.3.55"
18641
18642         create_check_volatile 0
18643         [ $MDSCOUNT -lt 2 ] && return 0
18644
18645         # DNE case
18646         create_check_volatile 1
18647
18648         return 0
18649 }
18650 run_test 185a "Volatile file creation in .lustre/fid/"
18651
18652 test_187a() {
18653         remote_mds_nodsh && skip "remote MDS with nodsh"
18654         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18655                 skip "Need MDS version at least 2.3.0"
18656
18657         local dir0=$DIR/$tdir/$testnum
18658         mkdir -p $dir0 || error "creating dir $dir0"
18659
18660         local file=$dir0/file1
18661         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18662         local dv1=$($LFS data_version $file)
18663         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18664         local dv2=$($LFS data_version $file)
18665         [[ $dv1 != $dv2 ]] ||
18666                 error "data version did not change on write $dv1 == $dv2"
18667
18668         # clean up
18669         rm -f $file1
18670 }
18671 run_test 187a "Test data version change"
18672
18673 test_187b() {
18674         remote_mds_nodsh && skip "remote MDS with nodsh"
18675         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18676                 skip "Need MDS version at least 2.3.0"
18677
18678         local dir0=$DIR/$tdir/$testnum
18679         mkdir -p $dir0 || error "creating dir $dir0"
18680
18681         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18682         [[ ${DV[0]} != ${DV[1]} ]] ||
18683                 error "data version did not change on write"\
18684                       " ${DV[0]} == ${DV[1]}"
18685
18686         # clean up
18687         rm -f $file1
18688 }
18689 run_test 187b "Test data version change on volatile file"
18690
18691 test_200() {
18692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18693         remote_mgs_nodsh && skip "remote MGS with nodsh"
18694         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18695
18696         local POOL=${POOL:-cea1}
18697         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18698         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18699         # Pool OST targets
18700         local first_ost=0
18701         local last_ost=$(($OSTCOUNT - 1))
18702         local ost_step=2
18703         local ost_list=$(seq $first_ost $ost_step $last_ost)
18704         local ost_range="$first_ost $last_ost $ost_step"
18705         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18706         local file_dir=$POOL_ROOT/file_tst
18707         local subdir=$test_path/subdir
18708         local rc=0
18709
18710         while : ; do
18711                 # former test_200a test_200b
18712                 pool_add $POOL                          || { rc=$? ; break; }
18713                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18714                 # former test_200c test_200d
18715                 mkdir -p $test_path
18716                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18717                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18718                 mkdir -p $subdir
18719                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18720                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18721                                                         || { rc=$? ; break; }
18722                 # former test_200e test_200f
18723                 local files=$((OSTCOUNT*3))
18724                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18725                                                         || { rc=$? ; break; }
18726                 pool_create_files $POOL $file_dir $files "$ost_list" \
18727                                                         || { rc=$? ; break; }
18728                 # former test_200g test_200h
18729                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18730                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18731
18732                 # former test_201a test_201b test_201c
18733                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18734
18735                 local f=$test_path/$tfile
18736                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18737                 pool_remove $POOL $f                    || { rc=$? ; break; }
18738                 break
18739         done
18740
18741         destroy_test_pools
18742
18743         return $rc
18744 }
18745 run_test 200 "OST pools"
18746
18747 # usage: default_attr <count | size | offset>
18748 default_attr() {
18749         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18750 }
18751
18752 # usage: check_default_stripe_attr
18753 check_default_stripe_attr() {
18754         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18755         case $1 in
18756         --stripe-count|-c)
18757                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18758         --stripe-size|-S)
18759                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18760         --stripe-index|-i)
18761                 EXPECTED=-1;;
18762         *)
18763                 error "unknown getstripe attr '$1'"
18764         esac
18765
18766         [ $ACTUAL == $EXPECTED ] ||
18767                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18768 }
18769
18770 test_204a() {
18771         test_mkdir $DIR/$tdir
18772         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18773
18774         check_default_stripe_attr --stripe-count
18775         check_default_stripe_attr --stripe-size
18776         check_default_stripe_attr --stripe-index
18777 }
18778 run_test 204a "Print default stripe attributes"
18779
18780 test_204b() {
18781         test_mkdir $DIR/$tdir
18782         $LFS setstripe --stripe-count 1 $DIR/$tdir
18783
18784         check_default_stripe_attr --stripe-size
18785         check_default_stripe_attr --stripe-index
18786 }
18787 run_test 204b "Print default stripe size and offset"
18788
18789 test_204c() {
18790         test_mkdir $DIR/$tdir
18791         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18792
18793         check_default_stripe_attr --stripe-count
18794         check_default_stripe_attr --stripe-index
18795 }
18796 run_test 204c "Print default stripe count and offset"
18797
18798 test_204d() {
18799         test_mkdir $DIR/$tdir
18800         $LFS setstripe --stripe-index 0 $DIR/$tdir
18801
18802         check_default_stripe_attr --stripe-count
18803         check_default_stripe_attr --stripe-size
18804 }
18805 run_test 204d "Print default stripe count and size"
18806
18807 test_204e() {
18808         test_mkdir $DIR/$tdir
18809         $LFS setstripe -d $DIR/$tdir
18810
18811         check_default_stripe_attr --stripe-count --raw
18812         check_default_stripe_attr --stripe-size --raw
18813         check_default_stripe_attr --stripe-index --raw
18814 }
18815 run_test 204e "Print raw stripe attributes"
18816
18817 test_204f() {
18818         test_mkdir $DIR/$tdir
18819         $LFS setstripe --stripe-count 1 $DIR/$tdir
18820
18821         check_default_stripe_attr --stripe-size --raw
18822         check_default_stripe_attr --stripe-index --raw
18823 }
18824 run_test 204f "Print raw stripe size and offset"
18825
18826 test_204g() {
18827         test_mkdir $DIR/$tdir
18828         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18829
18830         check_default_stripe_attr --stripe-count --raw
18831         check_default_stripe_attr --stripe-index --raw
18832 }
18833 run_test 204g "Print raw stripe count and offset"
18834
18835 test_204h() {
18836         test_mkdir $DIR/$tdir
18837         $LFS setstripe --stripe-index 0 $DIR/$tdir
18838
18839         check_default_stripe_attr --stripe-count --raw
18840         check_default_stripe_attr --stripe-size --raw
18841 }
18842 run_test 204h "Print raw stripe count and size"
18843
18844 # Figure out which job scheduler is being used, if any,
18845 # or use a fake one
18846 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18847         JOBENV=SLURM_JOB_ID
18848 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18849         JOBENV=LSB_JOBID
18850 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18851         JOBENV=PBS_JOBID
18852 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18853         JOBENV=LOADL_STEP_ID
18854 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18855         JOBENV=JOB_ID
18856 else
18857         $LCTL list_param jobid_name > /dev/null 2>&1
18858         if [ $? -eq 0 ]; then
18859                 JOBENV=nodelocal
18860         else
18861                 JOBENV=FAKE_JOBID
18862         fi
18863 fi
18864 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18865
18866 verify_jobstats() {
18867         local cmd=($1)
18868         shift
18869         local facets="$@"
18870
18871 # we don't really need to clear the stats for this test to work, since each
18872 # command has a unique jobid, but it makes debugging easier if needed.
18873 #       for facet in $facets; do
18874 #               local dev=$(convert_facet2label $facet)
18875 #               # clear old jobstats
18876 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18877 #       done
18878
18879         # use a new JobID for each test, or we might see an old one
18880         [ "$JOBENV" = "FAKE_JOBID" ] &&
18881                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18882
18883         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18884
18885         [ "$JOBENV" = "nodelocal" ] && {
18886                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18887                 $LCTL set_param jobid_name=$FAKE_JOBID
18888                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18889         }
18890
18891         log "Test: ${cmd[*]}"
18892         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18893
18894         if [ $JOBENV = "FAKE_JOBID" ]; then
18895                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18896         else
18897                 ${cmd[*]}
18898         fi
18899
18900         # all files are created on OST0000
18901         for facet in $facets; do
18902                 local stats="*.$(convert_facet2label $facet).job_stats"
18903
18904                 # strip out libtool wrappers for in-tree executables
18905                 if (( $(do_facet $facet lctl get_param $stats |
18906                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18907                         do_facet $facet lctl get_param $stats
18908                         error "No jobstats for $JOBVAL found on $facet::$stats"
18909                 fi
18910         done
18911 }
18912
18913 jobstats_set() {
18914         local new_jobenv=$1
18915
18916         set_persistent_param_and_check client "jobid_var" \
18917                 "$FSNAME.sys.jobid_var" $new_jobenv
18918 }
18919
18920 test_205a() { # Job stats
18921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18922         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18923                 skip "Need MDS version with at least 2.7.1"
18924         remote_mgs_nodsh && skip "remote MGS with nodsh"
18925         remote_mds_nodsh && skip "remote MDS with nodsh"
18926         remote_ost_nodsh && skip "remote OST with nodsh"
18927         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18928                 skip "Server doesn't support jobstats"
18929         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18930
18931         local old_jobenv=$($LCTL get_param -n jobid_var)
18932         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18933
18934         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18935                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18936         else
18937                 stack_trap "do_facet mgs $PERM_CMD \
18938                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18939         fi
18940         changelog_register
18941
18942         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18943                                 mdt.*.job_cleanup_interval | head -n 1)
18944         local new_interval=5
18945         do_facet $SINGLEMDS \
18946                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18947         stack_trap "do_facet $SINGLEMDS \
18948                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18949         local start=$SECONDS
18950
18951         local cmd
18952         # mkdir
18953         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18954         verify_jobstats "$cmd" "$SINGLEMDS"
18955         # rmdir
18956         cmd="rmdir $DIR/$tdir"
18957         verify_jobstats "$cmd" "$SINGLEMDS"
18958         # mkdir on secondary MDT
18959         if [ $MDSCOUNT -gt 1 ]; then
18960                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18961                 verify_jobstats "$cmd" "mds2"
18962         fi
18963         # mknod
18964         cmd="mknod $DIR/$tfile c 1 3"
18965         verify_jobstats "$cmd" "$SINGLEMDS"
18966         # unlink
18967         cmd="rm -f $DIR/$tfile"
18968         verify_jobstats "$cmd" "$SINGLEMDS"
18969         # create all files on OST0000 so verify_jobstats can find OST stats
18970         # open & close
18971         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18972         verify_jobstats "$cmd" "$SINGLEMDS"
18973         # setattr
18974         cmd="touch $DIR/$tfile"
18975         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18976         # write
18977         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18978         verify_jobstats "$cmd" "ost1"
18979         # read
18980         cancel_lru_locks osc
18981         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18982         verify_jobstats "$cmd" "ost1"
18983         # truncate
18984         cmd="$TRUNCATE $DIR/$tfile 0"
18985         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18986         # rename
18987         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18988         verify_jobstats "$cmd" "$SINGLEMDS"
18989         # jobstats expiry - sleep until old stats should be expired
18990         local left=$((new_interval + 5 - (SECONDS - start)))
18991         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18992                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18993                         "0" $left
18994         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18995         verify_jobstats "$cmd" "$SINGLEMDS"
18996         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18997             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18998
18999         # Ensure that jobid are present in changelog (if supported by MDS)
19000         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19001                 changelog_dump | tail -10
19002                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19003                 [ $jobids -eq 9 ] ||
19004                         error "Wrong changelog jobid count $jobids != 9"
19005
19006                 # LU-5862
19007                 JOBENV="disable"
19008                 jobstats_set $JOBENV
19009                 touch $DIR/$tfile
19010                 changelog_dump | grep $tfile
19011                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19012                 [ $jobids -eq 0 ] ||
19013                         error "Unexpected jobids when jobid_var=$JOBENV"
19014         fi
19015
19016         # test '%j' access to environment variable - if supported
19017         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19018                 JOBENV="JOBCOMPLEX"
19019                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19020
19021                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19022         fi
19023
19024         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19025                 JOBENV="JOBCOMPLEX"
19026                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19027
19028                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19029         fi
19030
19031         # test '%j' access to per-session jobid - if supported
19032         if lctl list_param jobid_this_session > /dev/null 2>&1
19033         then
19034                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19035                 lctl set_param jobid_this_session=$USER
19036
19037                 JOBENV="JOBCOMPLEX"
19038                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19039
19040                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19041         fi
19042 }
19043 run_test 205a "Verify job stats"
19044
19045 # LU-13117, LU-13597
19046 test_205b() {
19047         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19048                 skip "Need MDS version at least 2.13.54.91"
19049
19050         local job_stats="mdt.*.job_stats"
19051         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19052
19053         do_facet mds1 $LCTL set_param $job_stats=clear
19054
19055         # Setting jobid_var to USER might not be supported
19056         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19057         $LCTL set_param jobid_var=USER || true
19058         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19059         $LCTL set_param jobid_name="%j.%e.%u"
19060
19061         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19062         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19063                 { do_facet mds1 $LCTL get_param $job_stats;
19064                   error "Unexpected jobid found"; }
19065         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19066                 { do_facet mds1 $LCTL get_param $job_stats;
19067                   error "wrong job_stats format found"; }
19068
19069         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19070                 echo "MDS does not yet escape jobid" && return 0
19071         $LCTL set_param jobid_var=TEST205b
19072         env -i TEST205b="has sp" touch $DIR/$tfile.2
19073         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19074                 { do_facet mds1 $LCTL get_param $job_stats;
19075                   error "jobid not escaped"; }
19076 }
19077 run_test 205b "Verify job stats jobid and output format"
19078
19079 # LU-13733
19080 test_205c() {
19081         $LCTL set_param llite.*.stats=0
19082         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19083         $LCTL get_param llite.*.stats
19084         $LCTL get_param llite.*.stats | grep \
19085                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19086                         error "wrong client stats format found"
19087 }
19088 run_test 205c "Verify client stats format"
19089
19090 test_205d() {
19091         local file=$DIR/$tdir/$tfile
19092
19093         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
19094                 skip "need lustre >= 2.15.51"
19095         (( $OST1_VERSION >= $(version_code 2.15.52) )) ||
19096                 skip "need lustre >= 2.15.51"
19097         verify_yaml_available || skip_env "YAML verification not installed"
19098
19099         test_mkdir $DIR/$tdir
19100         $LFS setstripe -E 1M -L mdt -E -1 $file || error "setstripe failed"
19101
19102         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19103                 error "failed to write data to $file"
19104         mv $file $file.2
19105
19106         echo -n 'verify rename_stats...'
19107         output=$(do_facet mds1 \
19108                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats")
19109         verify_yaml "$output" || error "rename_stats is not valid YAML"
19110         echo " OK"
19111
19112         echo -n 'verify mdt job_stats...'
19113         output=$(do_facet mds1 \
19114                  "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats")
19115         verify_yaml "$output" || error "job_stats on mds1 is not valid YAML"
19116         echo " OK"
19117
19118         echo -n 'verify ost job_stats...'
19119         output=$(do_facet ost1 \
19120                  "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats")
19121         verify_yaml "$output" || error "job_stats on ost1 is not valid YAML"
19122         echo " OK"
19123 }
19124 run_test 205d "verify the format of some stats files"
19125
19126 # LU-1480, LU-1773 and LU-1657
19127 test_206() {
19128         mkdir -p $DIR/$tdir
19129         $LFS setstripe -c -1 $DIR/$tdir
19130 #define OBD_FAIL_LOV_INIT 0x1403
19131         $LCTL set_param fail_loc=0xa0001403
19132         $LCTL set_param fail_val=1
19133         touch $DIR/$tdir/$tfile || true
19134 }
19135 run_test 206 "fail lov_init_raid0() doesn't lbug"
19136
19137 test_207a() {
19138         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19139         local fsz=`stat -c %s $DIR/$tfile`
19140         cancel_lru_locks mdc
19141
19142         # do not return layout in getattr intent
19143 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19144         $LCTL set_param fail_loc=0x170
19145         local sz=`stat -c %s $DIR/$tfile`
19146
19147         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19148
19149         rm -rf $DIR/$tfile
19150 }
19151 run_test 207a "can refresh layout at glimpse"
19152
19153 test_207b() {
19154         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19155         local cksum=`md5sum $DIR/$tfile`
19156         local fsz=`stat -c %s $DIR/$tfile`
19157         cancel_lru_locks mdc
19158         cancel_lru_locks osc
19159
19160         # do not return layout in getattr intent
19161 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19162         $LCTL set_param fail_loc=0x171
19163
19164         # it will refresh layout after the file is opened but before read issues
19165         echo checksum is "$cksum"
19166         echo "$cksum" |md5sum -c --quiet || error "file differs"
19167
19168         rm -rf $DIR/$tfile
19169 }
19170 run_test 207b "can refresh layout at open"
19171
19172 test_208() {
19173         # FIXME: in this test suite, only RD lease is used. This is okay
19174         # for now as only exclusive open is supported. After generic lease
19175         # is done, this test suite should be revised. - Jinshan
19176
19177         remote_mds_nodsh && skip "remote MDS with nodsh"
19178         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19179                 skip "Need MDS version at least 2.4.52"
19180
19181         echo "==== test 1: verify get lease work"
19182         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19183
19184         echo "==== test 2: verify lease can be broken by upcoming open"
19185         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19186         local PID=$!
19187         sleep 2
19188
19189         $MULTIOP $DIR/$tfile oO_RDWR:c
19190         kill -USR1 $PID && wait $PID || error "break lease error"
19191
19192         echo "==== test 3: verify lease can't be granted if an open already exists"
19193         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19194         local PID=$!
19195         sleep 2
19196
19197         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19198         kill -USR1 $PID && wait $PID || error "open file error"
19199
19200         echo "==== test 4: lease can sustain over recovery"
19201         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19202         PID=$!
19203         sleep 2
19204
19205         fail mds1
19206
19207         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19208
19209         echo "==== test 5: lease broken can't be regained by replay"
19210         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19211         PID=$!
19212         sleep 2
19213
19214         # open file to break lease and then recovery
19215         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19216         fail mds1
19217
19218         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19219
19220         rm -f $DIR/$tfile
19221 }
19222 run_test 208 "Exclusive open"
19223
19224 test_209() {
19225         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19226                 skip_env "must have disp_stripe"
19227
19228         touch $DIR/$tfile
19229         sync; sleep 5; sync;
19230
19231         echo 3 > /proc/sys/vm/drop_caches
19232         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19233                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19234         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19235
19236         # open/close 500 times
19237         for i in $(seq 500); do
19238                 cat $DIR/$tfile
19239         done
19240
19241         echo 3 > /proc/sys/vm/drop_caches
19242         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19243                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19244         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19245
19246         echo "before: $req_before, after: $req_after"
19247         [ $((req_after - req_before)) -ge 300 ] &&
19248                 error "open/close requests are not freed"
19249         return 0
19250 }
19251 run_test 209 "read-only open/close requests should be freed promptly"
19252
19253 test_210() {
19254         local pid
19255
19256         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19257         pid=$!
19258         sleep 1
19259
19260         $LFS getstripe $DIR/$tfile
19261         kill -USR1 $pid
19262         wait $pid || error "multiop failed"
19263
19264         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19265         pid=$!
19266         sleep 1
19267
19268         $LFS getstripe $DIR/$tfile
19269         kill -USR1 $pid
19270         wait $pid || error "multiop failed"
19271 }
19272 run_test 210 "lfs getstripe does not break leases"
19273
19274 test_212() {
19275         size=`date +%s`
19276         size=$((size % 8192 + 1))
19277         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19278         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19279         rm -f $DIR/f212 $DIR/f212.xyz
19280 }
19281 run_test 212 "Sendfile test ============================================"
19282
19283 test_213() {
19284         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19285         cancel_lru_locks osc
19286         lctl set_param fail_loc=0x8000040f
19287         # generate a read lock
19288         cat $DIR/$tfile > /dev/null
19289         # write to the file, it will try to cancel the above read lock.
19290         cat /etc/hosts >> $DIR/$tfile
19291 }
19292 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19293
19294 test_214() { # for bug 20133
19295         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19296         for (( i=0; i < 340; i++ )) ; do
19297                 touch $DIR/$tdir/d214c/a$i
19298         done
19299
19300         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19301         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19302         ls $DIR/d214c || error "ls $DIR/d214c failed"
19303         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19304         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19305 }
19306 run_test 214 "hash-indexed directory test - bug 20133"
19307
19308 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19309 create_lnet_proc_files() {
19310         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19311 }
19312
19313 # counterpart of create_lnet_proc_files
19314 remove_lnet_proc_files() {
19315         rm -f $TMP/lnet_$1.sys
19316 }
19317
19318 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19319 # 3rd arg as regexp for body
19320 check_lnet_proc_stats() {
19321         local l=$(cat "$TMP/lnet_$1" |wc -l)
19322         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19323
19324         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19325 }
19326
19327 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19328 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19329 # optional and can be regexp for 2nd line (lnet.routes case)
19330 check_lnet_proc_entry() {
19331         local blp=2          # blp stands for 'position of 1st line of body'
19332         [ -z "$5" ] || blp=3 # lnet.routes case
19333
19334         local l=$(cat "$TMP/lnet_$1" |wc -l)
19335         # subtracting one from $blp because the body can be empty
19336         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19337
19338         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19339                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19340
19341         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19342                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19343
19344         # bail out if any unexpected line happened
19345         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19346         [ "$?" != 0 ] || error "$2 misformatted"
19347 }
19348
19349 test_215() { # for bugs 18102, 21079, 21517
19350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19351
19352         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19353         local P='[1-9][0-9]*'           # positive numeric
19354         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19355         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19356         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19357         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19358
19359         local L1 # regexp for 1st line
19360         local L2 # regexp for 2nd line (optional)
19361         local BR # regexp for the rest (body)
19362
19363         # lnet.stats should look as 11 space-separated non-negative numerics
19364         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19365         create_lnet_proc_files "stats"
19366         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19367         remove_lnet_proc_files "stats"
19368
19369         # lnet.routes should look like this:
19370         # Routing disabled/enabled
19371         # net hops priority state router
19372         # where net is a string like tcp0, hops > 0, priority >= 0,
19373         # state is up/down,
19374         # router is a string like 192.168.1.1@tcp2
19375         L1="^Routing (disabled|enabled)$"
19376         L2="^net +hops +priority +state +router$"
19377         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19378         create_lnet_proc_files "routes"
19379         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19380         remove_lnet_proc_files "routes"
19381
19382         # lnet.routers should look like this:
19383         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19384         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19385         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19386         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19387         L1="^ref +rtr_ref +alive +router$"
19388         BR="^$P +$P +(up|down) +$NID$"
19389         create_lnet_proc_files "routers"
19390         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19391         remove_lnet_proc_files "routers"
19392
19393         # lnet.peers should look like this:
19394         # nid refs state last max rtr min tx min queue
19395         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19396         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19397         # numeric (0 or >0 or <0), queue >= 0.
19398         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19399         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19400         create_lnet_proc_files "peers"
19401         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19402         remove_lnet_proc_files "peers"
19403
19404         # lnet.buffers  should look like this:
19405         # pages count credits min
19406         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19407         L1="^pages +count +credits +min$"
19408         BR="^ +$N +$N +$I +$I$"
19409         create_lnet_proc_files "buffers"
19410         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19411         remove_lnet_proc_files "buffers"
19412
19413         # lnet.nis should look like this:
19414         # nid status alive refs peer rtr max tx min
19415         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19416         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19417         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19418         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19419         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19420         create_lnet_proc_files "nis"
19421         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19422         remove_lnet_proc_files "nis"
19423
19424         # can we successfully write to lnet.stats?
19425         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19426 }
19427 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19428
19429 test_216() { # bug 20317
19430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19431         remote_ost_nodsh && skip "remote OST with nodsh"
19432
19433         local node
19434         local facets=$(get_facets OST)
19435         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19436
19437         save_lustre_params client "osc.*.contention_seconds" > $p
19438         save_lustre_params $facets \
19439                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19440         save_lustre_params $facets \
19441                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19442         save_lustre_params $facets \
19443                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19444         clear_stats osc.*.osc_stats
19445
19446         # agressive lockless i/o settings
19447         do_nodes $(comma_list $(osts_nodes)) \
19448                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19449                         ldlm.namespaces.filter-*.contended_locks=0 \
19450                         ldlm.namespaces.filter-*.contention_seconds=60"
19451         lctl set_param -n osc.*.contention_seconds=60
19452
19453         $DIRECTIO write $DIR/$tfile 0 10 4096
19454         $CHECKSTAT -s 40960 $DIR/$tfile
19455
19456         # disable lockless i/o
19457         do_nodes $(comma_list $(osts_nodes)) \
19458                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19459                         ldlm.namespaces.filter-*.contended_locks=32 \
19460                         ldlm.namespaces.filter-*.contention_seconds=0"
19461         lctl set_param -n osc.*.contention_seconds=0
19462         clear_stats osc.*.osc_stats
19463
19464         dd if=/dev/zero of=$DIR/$tfile count=0
19465         $CHECKSTAT -s 0 $DIR/$tfile
19466
19467         restore_lustre_params <$p
19468         rm -f $p
19469         rm $DIR/$tfile
19470 }
19471 run_test 216 "check lockless direct write updates file size and kms correctly"
19472
19473 test_217() { # bug 22430
19474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19475
19476         local node
19477         local nid
19478
19479         for node in $(nodes_list); do
19480                 nid=$(host_nids_address $node $NETTYPE)
19481                 if [[ $nid = *-* ]] ; then
19482                         echo "lctl ping $(h2nettype $nid)"
19483                         lctl ping $(h2nettype $nid)
19484                 else
19485                         echo "skipping $node (no hyphen detected)"
19486                 fi
19487         done
19488 }
19489 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19490
19491 test_218() {
19492        # do directio so as not to populate the page cache
19493        log "creating a 10 Mb file"
19494        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19495        log "starting reads"
19496        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19497        log "truncating the file"
19498        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19499        log "killing dd"
19500        kill %+ || true # reads might have finished
19501        echo "wait until dd is finished"
19502        wait
19503        log "removing the temporary file"
19504        rm -rf $DIR/$tfile || error "tmp file removal failed"
19505 }
19506 run_test 218 "parallel read and truncate should not deadlock"
19507
19508 test_219() {
19509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19510
19511         # write one partial page
19512         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19513         # set no grant so vvp_io_commit_write will do sync write
19514         $LCTL set_param fail_loc=0x411
19515         # write a full page at the end of file
19516         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19517
19518         $LCTL set_param fail_loc=0
19519         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19520         $LCTL set_param fail_loc=0x411
19521         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19522
19523         # LU-4201
19524         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19525         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19526 }
19527 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19528
19529 test_220() { #LU-325
19530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19531         remote_ost_nodsh && skip "remote OST with nodsh"
19532         remote_mds_nodsh && skip "remote MDS with nodsh"
19533         remote_mgs_nodsh && skip "remote MGS with nodsh"
19534
19535         local OSTIDX=0
19536
19537         # create on MDT0000 so the last_id and next_id are correct
19538         mkdir_on_mdt0 $DIR/$tdir
19539         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19540         OST=${OST%_UUID}
19541
19542         # on the mdt's osc
19543         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19544         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19545                         osp.$mdtosc_proc1.prealloc_last_id)
19546         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19547                         osp.$mdtosc_proc1.prealloc_next_id)
19548
19549         $LFS df -i
19550
19551         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19552         #define OBD_FAIL_OST_ENOINO              0x229
19553         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19554         create_pool $FSNAME.$TESTNAME || return 1
19555         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19556
19557         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19558
19559         MDSOBJS=$((last_id - next_id))
19560         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19561
19562         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19563         echo "OST still has $count kbytes free"
19564
19565         echo "create $MDSOBJS files @next_id..."
19566         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19567
19568         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19569                         osp.$mdtosc_proc1.prealloc_last_id)
19570         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19571                         osp.$mdtosc_proc1.prealloc_next_id)
19572
19573         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19574         $LFS df -i
19575
19576         echo "cleanup..."
19577
19578         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19579         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19580
19581         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19582                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19583         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19584                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19585         echo "unlink $MDSOBJS files @$next_id..."
19586         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19587 }
19588 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19589
19590 test_221() {
19591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19592
19593         dd if=`which date` of=$MOUNT/date oflag=sync
19594         chmod +x $MOUNT/date
19595
19596         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19597         $LCTL set_param fail_loc=0x80001401
19598
19599         $MOUNT/date > /dev/null
19600         rm -f $MOUNT/date
19601 }
19602 run_test 221 "make sure fault and truncate race to not cause OOM"
19603
19604 test_222a () {
19605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19606
19607         rm -rf $DIR/$tdir
19608         test_mkdir $DIR/$tdir
19609         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19610         createmany -o $DIR/$tdir/$tfile 10
19611         cancel_lru_locks mdc
19612         cancel_lru_locks osc
19613         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19614         $LCTL set_param fail_loc=0x31a
19615         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19616         $LCTL set_param fail_loc=0
19617         rm -r $DIR/$tdir
19618 }
19619 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19620
19621 test_222b () {
19622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19623
19624         rm -rf $DIR/$tdir
19625         test_mkdir $DIR/$tdir
19626         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19627         createmany -o $DIR/$tdir/$tfile 10
19628         cancel_lru_locks mdc
19629         cancel_lru_locks osc
19630         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19631         $LCTL set_param fail_loc=0x31a
19632         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19633         $LCTL set_param fail_loc=0
19634 }
19635 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19636
19637 test_223 () {
19638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19639
19640         rm -rf $DIR/$tdir
19641         test_mkdir $DIR/$tdir
19642         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19643         createmany -o $DIR/$tdir/$tfile 10
19644         cancel_lru_locks mdc
19645         cancel_lru_locks osc
19646         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19647         $LCTL set_param fail_loc=0x31b
19648         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19649         $LCTL set_param fail_loc=0
19650         rm -r $DIR/$tdir
19651 }
19652 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19653
19654 test_224a() { # LU-1039, MRP-303
19655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19656         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19657         $LCTL set_param fail_loc=0x508
19658         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19659         $LCTL set_param fail_loc=0
19660         df $DIR
19661 }
19662 run_test 224a "Don't panic on bulk IO failure"
19663
19664 test_224bd_sub() { # LU-1039, MRP-303
19665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19666         local timeout=$1
19667
19668         shift
19669         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19670
19671         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19672
19673         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19674         cancel_lru_locks osc
19675         set_checksums 0
19676         stack_trap "set_checksums $ORIG_CSUM" EXIT
19677         local at_max_saved=0
19678
19679         # adaptive timeouts may prevent seeing the issue
19680         if at_is_enabled; then
19681                 at_max_saved=$(at_max_get mds)
19682                 at_max_set 0 mds client
19683                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19684         fi
19685
19686         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19687         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19688         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19689
19690         do_facet ost1 $LCTL set_param fail_loc=0
19691         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19692         df $DIR
19693 }
19694
19695 test_224b() {
19696         test_224bd_sub 3 error "dd failed"
19697 }
19698 run_test 224b "Don't panic on bulk IO failure"
19699
19700 test_224c() { # LU-6441
19701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19702         remote_mds_nodsh && skip "remote MDS with nodsh"
19703
19704         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19705         save_writethrough $p
19706         set_cache writethrough on
19707
19708         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19709         local at_max=$($LCTL get_param -n at_max)
19710         local timeout=$($LCTL get_param -n timeout)
19711         local test_at="at_max"
19712         local param_at="$FSNAME.sys.at_max"
19713         local test_timeout="timeout"
19714         local param_timeout="$FSNAME.sys.timeout"
19715
19716         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19717
19718         set_persistent_param_and_check client "$test_at" "$param_at" 0
19719         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19720
19721         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19722         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19723         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19724         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19725         sync
19726         do_facet ost1 "$LCTL set_param fail_loc=0"
19727
19728         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19729         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19730                 $timeout
19731
19732         $LCTL set_param -n $pages_per_rpc
19733         restore_lustre_params < $p
19734         rm -f $p
19735 }
19736 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19737
19738 test_224d() { # LU-11169
19739         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19740 }
19741 run_test 224d "Don't corrupt data on bulk IO timeout"
19742
19743 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19744 test_225a () {
19745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19746         if [ -z ${MDSSURVEY} ]; then
19747                 skip_env "mds-survey not found"
19748         fi
19749         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19750                 skip "Need MDS version at least 2.2.51"
19751
19752         local mds=$(facet_host $SINGLEMDS)
19753         local target=$(do_nodes $mds 'lctl dl' |
19754                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19755
19756         local cmd1="file_count=1000 thrhi=4"
19757         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19758         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19759         local cmd="$cmd1 $cmd2 $cmd3"
19760
19761         rm -f ${TMP}/mds_survey*
19762         echo + $cmd
19763         eval $cmd || error "mds-survey with zero-stripe failed"
19764         cat ${TMP}/mds_survey*
19765         rm -f ${TMP}/mds_survey*
19766 }
19767 run_test 225a "Metadata survey sanity with zero-stripe"
19768
19769 test_225b () {
19770         if [ -z ${MDSSURVEY} ]; then
19771                 skip_env "mds-survey not found"
19772         fi
19773         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19774                 skip "Need MDS version at least 2.2.51"
19775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19776         remote_mds_nodsh && skip "remote MDS with nodsh"
19777         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19778                 skip_env "Need to mount OST to test"
19779         fi
19780
19781         local mds=$(facet_host $SINGLEMDS)
19782         local target=$(do_nodes $mds 'lctl dl' |
19783                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19784
19785         local cmd1="file_count=1000 thrhi=4"
19786         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19787         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19788         local cmd="$cmd1 $cmd2 $cmd3"
19789
19790         rm -f ${TMP}/mds_survey*
19791         echo + $cmd
19792         eval $cmd || error "mds-survey with stripe_count failed"
19793         cat ${TMP}/mds_survey*
19794         rm -f ${TMP}/mds_survey*
19795 }
19796 run_test 225b "Metadata survey sanity with stripe_count = 1"
19797
19798 mcreate_path2fid () {
19799         local mode=$1
19800         local major=$2
19801         local minor=$3
19802         local name=$4
19803         local desc=$5
19804         local path=$DIR/$tdir/$name
19805         local fid
19806         local rc
19807         local fid_path
19808
19809         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19810                 error "cannot create $desc"
19811
19812         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19813         rc=$?
19814         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19815
19816         fid_path=$($LFS fid2path $MOUNT $fid)
19817         rc=$?
19818         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19819
19820         [ "$path" == "$fid_path" ] ||
19821                 error "fid2path returned $fid_path, expected $path"
19822
19823         echo "pass with $path and $fid"
19824 }
19825
19826 test_226a () {
19827         rm -rf $DIR/$tdir
19828         mkdir -p $DIR/$tdir
19829
19830         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19831         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19832         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19833         mcreate_path2fid 0040666 0 0 dir "directory"
19834         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19835         mcreate_path2fid 0100666 0 0 file "regular file"
19836         mcreate_path2fid 0120666 0 0 link "symbolic link"
19837         mcreate_path2fid 0140666 0 0 sock "socket"
19838 }
19839 run_test 226a "call path2fid and fid2path on files of all type"
19840
19841 test_226b () {
19842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19843
19844         local MDTIDX=1
19845
19846         rm -rf $DIR/$tdir
19847         mkdir -p $DIR/$tdir
19848         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19849                 error "create remote directory failed"
19850         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19851         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19852                                 "character special file (null)"
19853         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19854                                 "character special file (no device)"
19855         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19856         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19857                                 "block special file (loop)"
19858         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19859         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19860         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19861 }
19862 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19863
19864 test_226c () {
19865         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19866         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19867                 skip "Need MDS version at least 2.13.55"
19868
19869         local submnt=/mnt/submnt
19870         local srcfile=/etc/passwd
19871         local dstfile=$submnt/passwd
19872         local path
19873         local fid
19874
19875         rm -rf $DIR/$tdir
19876         rm -rf $submnt
19877         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19878                 error "create remote directory failed"
19879         mkdir -p $submnt || error "create $submnt failed"
19880         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19881                 error "mount $submnt failed"
19882         stack_trap "umount $submnt" EXIT
19883
19884         cp $srcfile $dstfile
19885         fid=$($LFS path2fid $dstfile)
19886         path=$($LFS fid2path $submnt "$fid")
19887         [ "$path" = "$dstfile" ] ||
19888                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19889 }
19890 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19891
19892 # LU-1299 Executing or running ldd on a truncated executable does not
19893 # cause an out-of-memory condition.
19894 test_227() {
19895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19896         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19897
19898         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19899         chmod +x $MOUNT/date
19900
19901         $MOUNT/date > /dev/null
19902         ldd $MOUNT/date > /dev/null
19903         rm -f $MOUNT/date
19904 }
19905 run_test 227 "running truncated executable does not cause OOM"
19906
19907 # LU-1512 try to reuse idle OI blocks
19908 test_228a() {
19909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19910         remote_mds_nodsh && skip "remote MDS with nodsh"
19911         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19912
19913         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19914         local myDIR=$DIR/$tdir
19915
19916         mkdir -p $myDIR
19917         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19918         $LCTL set_param fail_loc=0x80001002
19919         createmany -o $myDIR/t- 10000
19920         $LCTL set_param fail_loc=0
19921         # The guard is current the largest FID holder
19922         touch $myDIR/guard
19923         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19924                     tr -d '[')
19925         local IDX=$(($SEQ % 64))
19926
19927         do_facet $SINGLEMDS sync
19928         # Make sure journal flushed.
19929         sleep 6
19930         local blk1=$(do_facet $SINGLEMDS \
19931                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19932                      grep Blockcount | awk '{print $4}')
19933
19934         # Remove old files, some OI blocks will become idle.
19935         unlinkmany $myDIR/t- 10000
19936         # Create new files, idle OI blocks should be reused.
19937         createmany -o $myDIR/t- 2000
19938         do_facet $SINGLEMDS sync
19939         # Make sure journal flushed.
19940         sleep 6
19941         local blk2=$(do_facet $SINGLEMDS \
19942                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19943                      grep Blockcount | awk '{print $4}')
19944
19945         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19946 }
19947 run_test 228a "try to reuse idle OI blocks"
19948
19949 test_228b() {
19950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19951         remote_mds_nodsh && skip "remote MDS with nodsh"
19952         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19953
19954         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19955         local myDIR=$DIR/$tdir
19956
19957         mkdir -p $myDIR
19958         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19959         $LCTL set_param fail_loc=0x80001002
19960         createmany -o $myDIR/t- 10000
19961         $LCTL set_param fail_loc=0
19962         # The guard is current the largest FID holder
19963         touch $myDIR/guard
19964         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19965                     tr -d '[')
19966         local IDX=$(($SEQ % 64))
19967
19968         do_facet $SINGLEMDS sync
19969         # Make sure journal flushed.
19970         sleep 6
19971         local blk1=$(do_facet $SINGLEMDS \
19972                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19973                      grep Blockcount | awk '{print $4}')
19974
19975         # Remove old files, some OI blocks will become idle.
19976         unlinkmany $myDIR/t- 10000
19977
19978         # stop the MDT
19979         stop $SINGLEMDS || error "Fail to stop MDT."
19980         # remount the MDT
19981         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19982                 error "Fail to start MDT."
19983
19984         df $MOUNT || error "Fail to df."
19985         # Create new files, idle OI blocks should be reused.
19986         createmany -o $myDIR/t- 2000
19987         do_facet $SINGLEMDS sync
19988         # Make sure journal flushed.
19989         sleep 6
19990         local blk2=$(do_facet $SINGLEMDS \
19991                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19992                      grep Blockcount | awk '{print $4}')
19993
19994         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19995 }
19996 run_test 228b "idle OI blocks can be reused after MDT restart"
19997
19998 #LU-1881
19999 test_228c() {
20000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20001         remote_mds_nodsh && skip "remote MDS with nodsh"
20002         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20003
20004         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20005         local myDIR=$DIR/$tdir
20006
20007         mkdir -p $myDIR
20008         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20009         $LCTL set_param fail_loc=0x80001002
20010         # 20000 files can guarantee there are index nodes in the OI file
20011         createmany -o $myDIR/t- 20000
20012         $LCTL set_param fail_loc=0
20013         # The guard is current the largest FID holder
20014         touch $myDIR/guard
20015         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20016                     tr -d '[')
20017         local IDX=$(($SEQ % 64))
20018
20019         do_facet $SINGLEMDS sync
20020         # Make sure journal flushed.
20021         sleep 6
20022         local blk1=$(do_facet $SINGLEMDS \
20023                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20024                      grep Blockcount | awk '{print $4}')
20025
20026         # Remove old files, some OI blocks will become idle.
20027         unlinkmany $myDIR/t- 20000
20028         rm -f $myDIR/guard
20029         # The OI file should become empty now
20030
20031         # Create new files, idle OI blocks should be reused.
20032         createmany -o $myDIR/t- 2000
20033         do_facet $SINGLEMDS sync
20034         # Make sure journal flushed.
20035         sleep 6
20036         local blk2=$(do_facet $SINGLEMDS \
20037                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20038                      grep Blockcount | awk '{print $4}')
20039
20040         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20041 }
20042 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20043
20044 test_229() { # LU-2482, LU-3448
20045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20046         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20047         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20048                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20049
20050         rm -f $DIR/$tfile
20051
20052         # Create a file with a released layout and stripe count 2.
20053         $MULTIOP $DIR/$tfile H2c ||
20054                 error "failed to create file with released layout"
20055
20056         $LFS getstripe -v $DIR/$tfile
20057
20058         local pattern=$($LFS getstripe -L $DIR/$tfile)
20059         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20060
20061         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20062                 error "getstripe"
20063         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20064         stat $DIR/$tfile || error "failed to stat released file"
20065
20066         chown $RUNAS_ID $DIR/$tfile ||
20067                 error "chown $RUNAS_ID $DIR/$tfile failed"
20068
20069         chgrp $RUNAS_ID $DIR/$tfile ||
20070                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20071
20072         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20073         rm $DIR/$tfile || error "failed to remove released file"
20074 }
20075 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20076
20077 test_230a() {
20078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20079         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20080         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20081                 skip "Need MDS version at least 2.11.52"
20082
20083         local MDTIDX=1
20084
20085         test_mkdir $DIR/$tdir
20086         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20087         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20088         [ $mdt_idx -ne 0 ] &&
20089                 error "create local directory on wrong MDT $mdt_idx"
20090
20091         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20092                         error "create remote directory failed"
20093         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20094         [ $mdt_idx -ne $MDTIDX ] &&
20095                 error "create remote directory on wrong MDT $mdt_idx"
20096
20097         createmany -o $DIR/$tdir/test_230/t- 10 ||
20098                 error "create files on remote directory failed"
20099         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20100         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20101         rm -r $DIR/$tdir || error "unlink remote directory failed"
20102 }
20103 run_test 230a "Create remote directory and files under the remote directory"
20104
20105 test_230b() {
20106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20107         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20108         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20109                 skip "Need MDS version at least 2.11.52"
20110
20111         local MDTIDX=1
20112         local mdt_index
20113         local i
20114         local file
20115         local pid
20116         local stripe_count
20117         local migrate_dir=$DIR/$tdir/migrate_dir
20118         local other_dir=$DIR/$tdir/other_dir
20119
20120         test_mkdir $DIR/$tdir
20121         test_mkdir -i0 -c1 $migrate_dir
20122         test_mkdir -i0 -c1 $other_dir
20123         for ((i=0; i<10; i++)); do
20124                 mkdir -p $migrate_dir/dir_${i}
20125                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20126                         error "create files under remote dir failed $i"
20127         done
20128
20129         cp /etc/passwd $migrate_dir/$tfile
20130         cp /etc/passwd $other_dir/$tfile
20131         chattr +SAD $migrate_dir
20132         chattr +SAD $migrate_dir/$tfile
20133
20134         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20135         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20136         local old_dir_mode=$(stat -c%f $migrate_dir)
20137         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20138
20139         mkdir -p $migrate_dir/dir_default_stripe2
20140         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20141         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20142
20143         mkdir -p $other_dir
20144         ln $migrate_dir/$tfile $other_dir/luna
20145         ln $migrate_dir/$tfile $migrate_dir/sofia
20146         ln $other_dir/$tfile $migrate_dir/david
20147         ln -s $migrate_dir/$tfile $other_dir/zachary
20148         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20149         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20150
20151         local len
20152         local lnktgt
20153
20154         # inline symlink
20155         for len in 58 59 60; do
20156                 lnktgt=$(str_repeat 'l' $len)
20157                 touch $migrate_dir/$lnktgt
20158                 ln -s $lnktgt $migrate_dir/${len}char_ln
20159         done
20160
20161         # PATH_MAX
20162         for len in 4094 4095; do
20163                 lnktgt=$(str_repeat 'l' $len)
20164                 ln -s $lnktgt $migrate_dir/${len}char_ln
20165         done
20166
20167         # NAME_MAX
20168         for len in 254 255; do
20169                 touch $migrate_dir/$(str_repeat 'l' $len)
20170         done
20171
20172         $LFS migrate -m $MDTIDX $migrate_dir ||
20173                 error "fails on migrating remote dir to MDT1"
20174
20175         echo "migratate to MDT1, then checking.."
20176         for ((i = 0; i < 10; i++)); do
20177                 for file in $(find $migrate_dir/dir_${i}); do
20178                         mdt_index=$($LFS getstripe -m $file)
20179                         # broken symlink getstripe will fail
20180                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20181                                 error "$file is not on MDT${MDTIDX}"
20182                 done
20183         done
20184
20185         # the multiple link file should still in MDT0
20186         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20187         [ $mdt_index == 0 ] ||
20188                 error "$file is not on MDT${MDTIDX}"
20189
20190         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20191         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20192                 error " expect $old_dir_flag get $new_dir_flag"
20193
20194         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20195         [ "$old_file_flag" = "$new_file_flag" ] ||
20196                 error " expect $old_file_flag get $new_file_flag"
20197
20198         local new_dir_mode=$(stat -c%f $migrate_dir)
20199         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20200                 error "expect mode $old_dir_mode get $new_dir_mode"
20201
20202         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20203         [ "$old_file_mode" = "$new_file_mode" ] ||
20204                 error "expect mode $old_file_mode get $new_file_mode"
20205
20206         diff /etc/passwd $migrate_dir/$tfile ||
20207                 error "$tfile different after migration"
20208
20209         diff /etc/passwd $other_dir/luna ||
20210                 error "luna different after migration"
20211
20212         diff /etc/passwd $migrate_dir/sofia ||
20213                 error "sofia different after migration"
20214
20215         diff /etc/passwd $migrate_dir/david ||
20216                 error "david different after migration"
20217
20218         diff /etc/passwd $other_dir/zachary ||
20219                 error "zachary different after migration"
20220
20221         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20222                 error "${tfile}_ln different after migration"
20223
20224         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20225                 error "${tfile}_ln_other different after migration"
20226
20227         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20228         [ $stripe_count = 2 ] ||
20229                 error "dir strpe_count $d != 2 after migration."
20230
20231         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20232         [ $stripe_count = 2 ] ||
20233                 error "file strpe_count $d != 2 after migration."
20234
20235         #migrate back to MDT0
20236         MDTIDX=0
20237
20238         $LFS migrate -m $MDTIDX $migrate_dir ||
20239                 error "fails on migrating remote dir to MDT0"
20240
20241         echo "migrate back to MDT0, checking.."
20242         for file in $(find $migrate_dir); do
20243                 mdt_index=$($LFS getstripe -m $file)
20244                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20245                         error "$file is not on MDT${MDTIDX}"
20246         done
20247
20248         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20249         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20250                 error " expect $old_dir_flag get $new_dir_flag"
20251
20252         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20253         [ "$old_file_flag" = "$new_file_flag" ] ||
20254                 error " expect $old_file_flag get $new_file_flag"
20255
20256         local new_dir_mode=$(stat -c%f $migrate_dir)
20257         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20258                 error "expect mode $old_dir_mode get $new_dir_mode"
20259
20260         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20261         [ "$old_file_mode" = "$new_file_mode" ] ||
20262                 error "expect mode $old_file_mode get $new_file_mode"
20263
20264         diff /etc/passwd ${migrate_dir}/$tfile ||
20265                 error "$tfile different after migration"
20266
20267         diff /etc/passwd ${other_dir}/luna ||
20268                 error "luna different after migration"
20269
20270         diff /etc/passwd ${migrate_dir}/sofia ||
20271                 error "sofia different after migration"
20272
20273         diff /etc/passwd ${other_dir}/zachary ||
20274                 error "zachary different after migration"
20275
20276         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20277                 error "${tfile}_ln different after migration"
20278
20279         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20280                 error "${tfile}_ln_other different after migration"
20281
20282         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20283         [ $stripe_count = 2 ] ||
20284                 error "dir strpe_count $d != 2 after migration."
20285
20286         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20287         [ $stripe_count = 2 ] ||
20288                 error "file strpe_count $d != 2 after migration."
20289
20290         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20291 }
20292 run_test 230b "migrate directory"
20293
20294 test_230c() {
20295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20296         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20297         remote_mds_nodsh && skip "remote MDS with nodsh"
20298         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20299                 skip "Need MDS version at least 2.11.52"
20300
20301         local MDTIDX=1
20302         local total=3
20303         local mdt_index
20304         local file
20305         local migrate_dir=$DIR/$tdir/migrate_dir
20306
20307         #If migrating directory fails in the middle, all entries of
20308         #the directory is still accessiable.
20309         test_mkdir $DIR/$tdir
20310         test_mkdir -i0 -c1 $migrate_dir
20311         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20312         stat $migrate_dir
20313         createmany -o $migrate_dir/f $total ||
20314                 error "create files under ${migrate_dir} failed"
20315
20316         # fail after migrating top dir, and this will fail only once, so the
20317         # first sub file migration will fail (currently f3), others succeed.
20318         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20319         do_facet mds1 lctl set_param fail_loc=0x1801
20320         local t=$(ls $migrate_dir | wc -l)
20321         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20322                 error "migrate should fail"
20323         local u=$(ls $migrate_dir | wc -l)
20324         [ "$u" == "$t" ] || error "$u != $t during migration"
20325
20326         # add new dir/file should succeed
20327         mkdir $migrate_dir/dir ||
20328                 error "mkdir failed under migrating directory"
20329         touch $migrate_dir/file ||
20330                 error "create file failed under migrating directory"
20331
20332         # add file with existing name should fail
20333         for file in $migrate_dir/f*; do
20334                 stat $file > /dev/null || error "stat $file failed"
20335                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20336                         error "open(O_CREAT|O_EXCL) $file should fail"
20337                 $MULTIOP $file m && error "create $file should fail"
20338                 touch $DIR/$tdir/remote_dir/$tfile ||
20339                         error "touch $tfile failed"
20340                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20341                         error "link $file should fail"
20342                 mdt_index=$($LFS getstripe -m $file)
20343                 if [ $mdt_index == 0 ]; then
20344                         # file failed to migrate is not allowed to rename to
20345                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20346                                 error "rename to $file should fail"
20347                 else
20348                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20349                                 error "rename to $file failed"
20350                 fi
20351                 echo hello >> $file || error "write $file failed"
20352         done
20353
20354         # resume migration with different options should fail
20355         $LFS migrate -m 0 $migrate_dir &&
20356                 error "migrate -m 0 $migrate_dir should fail"
20357
20358         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20359                 error "migrate -c 2 $migrate_dir should fail"
20360
20361         # resume migration should succeed
20362         $LFS migrate -m $MDTIDX $migrate_dir ||
20363                 error "migrate $migrate_dir failed"
20364
20365         echo "Finish migration, then checking.."
20366         for file in $(find $migrate_dir); do
20367                 mdt_index=$($LFS getstripe -m $file)
20368                 [ $mdt_index == $MDTIDX ] ||
20369                         error "$file is not on MDT${MDTIDX}"
20370         done
20371
20372         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20373 }
20374 run_test 230c "check directory accessiblity if migration failed"
20375
20376 test_230d() {
20377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20378         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20379         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20380                 skip "Need MDS version at least 2.11.52"
20381         # LU-11235
20382         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20383
20384         local migrate_dir=$DIR/$tdir/migrate_dir
20385         local old_index
20386         local new_index
20387         local old_count
20388         local new_count
20389         local new_hash
20390         local mdt_index
20391         local i
20392         local j
20393
20394         old_index=$((RANDOM % MDSCOUNT))
20395         old_count=$((MDSCOUNT - old_index))
20396         new_index=$((RANDOM % MDSCOUNT))
20397         new_count=$((MDSCOUNT - new_index))
20398         new_hash=1 # for all_char
20399
20400         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20401         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20402
20403         test_mkdir $DIR/$tdir
20404         test_mkdir -i $old_index -c $old_count $migrate_dir
20405
20406         for ((i=0; i<100; i++)); do
20407                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20408                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20409                         error "create files under remote dir failed $i"
20410         done
20411
20412         echo -n "Migrate from MDT$old_index "
20413         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20414         echo -n "to MDT$new_index"
20415         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20416         echo
20417
20418         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20419         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20420                 error "migrate remote dir error"
20421
20422         echo "Finish migration, then checking.."
20423         for file in $(find $migrate_dir -maxdepth 1); do
20424                 mdt_index=$($LFS getstripe -m $file)
20425                 if [ $mdt_index -lt $new_index ] ||
20426                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20427                         error "$file is on MDT$mdt_index"
20428                 fi
20429         done
20430
20431         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20432 }
20433 run_test 230d "check migrate big directory"
20434
20435 test_230e() {
20436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20438         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20439                 skip "Need MDS version at least 2.11.52"
20440
20441         local i
20442         local j
20443         local a_fid
20444         local b_fid
20445
20446         mkdir_on_mdt0 $DIR/$tdir
20447         mkdir $DIR/$tdir/migrate_dir
20448         mkdir $DIR/$tdir/other_dir
20449         touch $DIR/$tdir/migrate_dir/a
20450         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20451         ls $DIR/$tdir/other_dir
20452
20453         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20454                 error "migrate dir fails"
20455
20456         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20457         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20458
20459         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20460         [ $mdt_index == 0 ] || error "a is not on MDT0"
20461
20462         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20463                 error "migrate dir fails"
20464
20465         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20466         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20467
20468         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20469         [ $mdt_index == 1 ] || error "a is not on MDT1"
20470
20471         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20472         [ $mdt_index == 1 ] || error "b is not on MDT1"
20473
20474         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20475         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20476
20477         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20478
20479         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20480 }
20481 run_test 230e "migrate mulitple local link files"
20482
20483 test_230f() {
20484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20486         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20487                 skip "Need MDS version at least 2.11.52"
20488
20489         local a_fid
20490         local ln_fid
20491
20492         mkdir -p $DIR/$tdir
20493         mkdir $DIR/$tdir/migrate_dir
20494         $LFS mkdir -i1 $DIR/$tdir/other_dir
20495         touch $DIR/$tdir/migrate_dir/a
20496         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20497         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20498         ls $DIR/$tdir/other_dir
20499
20500         # a should be migrated to MDT1, since no other links on MDT0
20501         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20502                 error "#1 migrate dir fails"
20503         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20504         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20505         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20506         [ $mdt_index == 1 ] || error "a is not on MDT1"
20507
20508         # a should stay on MDT1, because it is a mulitple link file
20509         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20510                 error "#2 migrate dir fails"
20511         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20512         [ $mdt_index == 1 ] || error "a is not on MDT1"
20513
20514         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20515                 error "#3 migrate dir fails"
20516
20517         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20518         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20519         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20520
20521         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20522         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20523
20524         # a should be migrated to MDT0, since no other links on MDT1
20525         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20526                 error "#4 migrate dir fails"
20527         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20528         [ $mdt_index == 0 ] || error "a is not on MDT0"
20529
20530         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20531 }
20532 run_test 230f "migrate mulitple remote link files"
20533
20534 test_230g() {
20535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20537         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20538                 skip "Need MDS version at least 2.11.52"
20539
20540         mkdir -p $DIR/$tdir/migrate_dir
20541
20542         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20543                 error "migrating dir to non-exist MDT succeeds"
20544         true
20545 }
20546 run_test 230g "migrate dir to non-exist MDT"
20547
20548 test_230h() {
20549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20551         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20552                 skip "Need MDS version at least 2.11.52"
20553
20554         local mdt_index
20555
20556         mkdir -p $DIR/$tdir/migrate_dir
20557
20558         $LFS migrate -m1 $DIR &&
20559                 error "migrating mountpoint1 should fail"
20560
20561         $LFS migrate -m1 $DIR/$tdir/.. &&
20562                 error "migrating mountpoint2 should fail"
20563
20564         # same as mv
20565         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20566                 error "migrating $tdir/migrate_dir/.. should fail"
20567
20568         true
20569 }
20570 run_test 230h "migrate .. and root"
20571
20572 test_230i() {
20573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20575         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20576                 skip "Need MDS version at least 2.11.52"
20577
20578         mkdir -p $DIR/$tdir/migrate_dir
20579
20580         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20581                 error "migration fails with a tailing slash"
20582
20583         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20584                 error "migration fails with two tailing slashes"
20585 }
20586 run_test 230i "lfs migrate -m tolerates trailing slashes"
20587
20588 test_230j() {
20589         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20590         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20591                 skip "Need MDS version at least 2.11.52"
20592
20593         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20594         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20595                 error "create $tfile failed"
20596         cat /etc/passwd > $DIR/$tdir/$tfile
20597
20598         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20599
20600         cmp /etc/passwd $DIR/$tdir/$tfile ||
20601                 error "DoM file mismatch after migration"
20602 }
20603 run_test 230j "DoM file data not changed after dir migration"
20604
20605 test_230k() {
20606         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20607         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20608                 skip "Need MDS version at least 2.11.56"
20609
20610         local total=20
20611         local files_on_starting_mdt=0
20612
20613         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20614         $LFS getdirstripe $DIR/$tdir
20615         for i in $(seq $total); do
20616                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20617                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20618                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20619         done
20620
20621         echo "$files_on_starting_mdt files on MDT0"
20622
20623         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20624         $LFS getdirstripe $DIR/$tdir
20625
20626         files_on_starting_mdt=0
20627         for i in $(seq $total); do
20628                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20629                         error "file $tfile.$i mismatch after migration"
20630                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20631                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20632         done
20633
20634         echo "$files_on_starting_mdt files on MDT1 after migration"
20635         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20636
20637         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20638         $LFS getdirstripe $DIR/$tdir
20639
20640         files_on_starting_mdt=0
20641         for i in $(seq $total); do
20642                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20643                         error "file $tfile.$i mismatch after 2nd migration"
20644                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20645                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20646         done
20647
20648         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20649         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20650
20651         true
20652 }
20653 run_test 230k "file data not changed after dir migration"
20654
20655 test_230l() {
20656         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20657         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20658                 skip "Need MDS version at least 2.11.56"
20659
20660         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20661         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20662                 error "create files under remote dir failed $i"
20663         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20664 }
20665 run_test 230l "readdir between MDTs won't crash"
20666
20667 test_230m() {
20668         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20669         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20670                 skip "Need MDS version at least 2.11.56"
20671
20672         local MDTIDX=1
20673         local mig_dir=$DIR/$tdir/migrate_dir
20674         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20675         local shortstr="b"
20676         local val
20677
20678         echo "Creating files and dirs with xattrs"
20679         test_mkdir $DIR/$tdir
20680         test_mkdir -i0 -c1 $mig_dir
20681         mkdir $mig_dir/dir
20682         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20683                 error "cannot set xattr attr1 on dir"
20684         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20685                 error "cannot set xattr attr2 on dir"
20686         touch $mig_dir/dir/f0
20687         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20688                 error "cannot set xattr attr1 on file"
20689         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20690                 error "cannot set xattr attr2 on file"
20691         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20692         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20693         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20694         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20695         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20696         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20697         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20698         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20699         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20700
20701         echo "Migrating to MDT1"
20702         $LFS migrate -m $MDTIDX $mig_dir ||
20703                 error "fails on migrating dir to MDT1"
20704
20705         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20706         echo "Checking xattrs"
20707         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20708         [ "$val" = $longstr ] ||
20709                 error "expecting xattr1 $longstr on dir, found $val"
20710         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20711         [ "$val" = $shortstr ] ||
20712                 error "expecting xattr2 $shortstr on dir, found $val"
20713         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20714         [ "$val" = $longstr ] ||
20715                 error "expecting xattr1 $longstr on file, found $val"
20716         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20717         [ "$val" = $shortstr ] ||
20718                 error "expecting xattr2 $shortstr on file, found $val"
20719 }
20720 run_test 230m "xattrs not changed after dir migration"
20721
20722 test_230n() {
20723         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20724         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20725                 skip "Need MDS version at least 2.13.53"
20726
20727         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20728         cat /etc/hosts > $DIR/$tdir/$tfile
20729         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20730         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20731
20732         cmp /etc/hosts $DIR/$tdir/$tfile ||
20733                 error "File data mismatch after migration"
20734 }
20735 run_test 230n "Dir migration with mirrored file"
20736
20737 test_230o() {
20738         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20739         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20740                 skip "Need MDS version at least 2.13.52"
20741
20742         local mdts=$(comma_list $(mdts_nodes))
20743         local timeout=100
20744         local restripe_status
20745         local delta
20746         local i
20747
20748         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20749
20750         # in case "crush" hash type is not set
20751         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20752
20753         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20754                            mdt.*MDT0000.enable_dir_restripe)
20755         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20756         stack_trap "do_nodes $mdts $LCTL set_param \
20757                     mdt.*.enable_dir_restripe=$restripe_status"
20758
20759         mkdir $DIR/$tdir
20760         createmany -m $DIR/$tdir/f 100 ||
20761                 error "create files under remote dir failed $i"
20762         createmany -d $DIR/$tdir/d 100 ||
20763                 error "create dirs under remote dir failed $i"
20764
20765         for i in $(seq 2 $MDSCOUNT); do
20766                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20767                 $LFS setdirstripe -c $i $DIR/$tdir ||
20768                         error "split -c $i $tdir failed"
20769                 wait_update $HOSTNAME \
20770                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20771                         error "dir split not finished"
20772                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20773                         awk '/migrate/ {sum += $2} END { print sum }')
20774                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20775                 # delta is around total_files/stripe_count
20776                 (( $delta < 200 / (i - 1) + 4 )) ||
20777                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20778         done
20779 }
20780 run_test 230o "dir split"
20781
20782 test_230p() {
20783         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20784         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20785                 skip "Need MDS version at least 2.13.52"
20786
20787         local mdts=$(comma_list $(mdts_nodes))
20788         local timeout=100
20789         local restripe_status
20790         local delta
20791         local c
20792
20793         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20794
20795         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20796
20797         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20798                            mdt.*MDT0000.enable_dir_restripe)
20799         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20800         stack_trap "do_nodes $mdts $LCTL set_param \
20801                     mdt.*.enable_dir_restripe=$restripe_status"
20802
20803         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20804         createmany -m $DIR/$tdir/f 100 ||
20805                 error "create files under remote dir failed"
20806         createmany -d $DIR/$tdir/d 100 ||
20807                 error "create dirs under remote dir failed"
20808
20809         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20810                 local mdt_hash="crush"
20811
20812                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20813                 $LFS setdirstripe -c $c $DIR/$tdir ||
20814                         error "split -c $c $tdir failed"
20815                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20816                         mdt_hash="$mdt_hash,fixed"
20817                 elif [ $c -eq 1 ]; then
20818                         mdt_hash="none"
20819                 fi
20820                 wait_update $HOSTNAME \
20821                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20822                         error "dir merge not finished"
20823                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20824                         awk '/migrate/ {sum += $2} END { print sum }')
20825                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20826                 # delta is around total_files/stripe_count
20827                 (( delta < 200 / c + 4 )) ||
20828                         error "$delta files migrated >= $((200 / c + 4))"
20829         done
20830 }
20831 run_test 230p "dir merge"
20832
20833 test_230q() {
20834         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20835         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20836                 skip "Need MDS version at least 2.13.52"
20837
20838         local mdts=$(comma_list $(mdts_nodes))
20839         local saved_threshold=$(do_facet mds1 \
20840                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20841         local saved_delta=$(do_facet mds1 \
20842                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20843         local threshold=100
20844         local delta=2
20845         local total=0
20846         local stripe_count=0
20847         local stripe_index
20848         local nr_files
20849         local create
20850
20851         # test with fewer files on ZFS
20852         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20853
20854         stack_trap "do_nodes $mdts $LCTL set_param \
20855                     mdt.*.dir_split_count=$saved_threshold"
20856         stack_trap "do_nodes $mdts $LCTL set_param \
20857                     mdt.*.dir_split_delta=$saved_delta"
20858         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20859         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20860         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20861         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20862         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20863         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20864
20865         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20866         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20867
20868         create=$((threshold * 3 / 2))
20869         while [ $stripe_count -lt $MDSCOUNT ]; do
20870                 createmany -m $DIR/$tdir/f $total $create ||
20871                         error "create sub files failed"
20872                 stat $DIR/$tdir > /dev/null
20873                 total=$((total + create))
20874                 stripe_count=$((stripe_count + delta))
20875                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20876
20877                 wait_update $HOSTNAME \
20878                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20879                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20880
20881                 wait_update $HOSTNAME \
20882                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20883                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20884
20885                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20886                 echo "$nr_files/$total files on MDT$stripe_index after split"
20887                 # allow 10% margin of imbalance with crush hash
20888                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20889                         error "$nr_files files on MDT$stripe_index after split"
20890
20891                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20892                 [ $nr_files -eq $total ] ||
20893                         error "total sub files $nr_files != $total"
20894         done
20895
20896         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20897
20898         echo "fixed layout directory won't auto split"
20899         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20900         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20901                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20902         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20903                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20904 }
20905 run_test 230q "dir auto split"
20906
20907 test_230r() {
20908         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20909         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20910         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20911                 skip "Need MDS version at least 2.13.54"
20912
20913         # maximum amount of local locks:
20914         # parent striped dir - 2 locks
20915         # new stripe in parent to migrate to - 1 lock
20916         # source and target - 2 locks
20917         # Total 5 locks for regular file
20918         mkdir -p $DIR/$tdir
20919         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20920         touch $DIR/$tdir/dir1/eee
20921
20922         # create 4 hardlink for 4 more locks
20923         # Total: 9 locks > RS_MAX_LOCKS (8)
20924         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20925         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20926         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20927         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20928         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20929         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20930         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20931         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20932
20933         cancel_lru_locks mdc
20934
20935         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20936                 error "migrate dir fails"
20937
20938         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20939 }
20940 run_test 230r "migrate with too many local locks"
20941
20942 test_230s() {
20943         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20944                 skip "Need MDS version at least 2.14.52"
20945
20946         local mdts=$(comma_list $(mdts_nodes))
20947         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20948                                 mdt.*MDT0000.enable_dir_restripe)
20949
20950         stack_trap "do_nodes $mdts $LCTL set_param \
20951                     mdt.*.enable_dir_restripe=$restripe_status"
20952
20953         local st
20954         for st in 0 1; do
20955                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20956                 test_mkdir $DIR/$tdir
20957                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20958                         error "$LFS mkdir should return EEXIST if target exists"
20959                 rmdir $DIR/$tdir
20960         done
20961 }
20962 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20963
20964 test_230t()
20965 {
20966         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20967         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20968                 skip "Need MDS version at least 2.14.50"
20969
20970         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20971         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20972         $LFS project -p 1 -s $DIR/$tdir ||
20973                 error "set $tdir project id failed"
20974         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20975                 error "set subdir project id failed"
20976         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20977 }
20978 run_test 230t "migrate directory with project ID set"
20979
20980 test_230u()
20981 {
20982         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20983         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20984                 skip "Need MDS version at least 2.14.53"
20985
20986         local count
20987
20988         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20989         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20990         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20991         for i in $(seq 0 $((MDSCOUNT - 1))); do
20992                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20993                 echo "$count dirs migrated to MDT$i"
20994         done
20995         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20996         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20997 }
20998 run_test 230u "migrate directory by QOS"
20999
21000 test_230v()
21001 {
21002         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21003         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21004                 skip "Need MDS version at least 2.14.53"
21005
21006         local count
21007
21008         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21009         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21010         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21011         for i in $(seq 0 $((MDSCOUNT - 1))); do
21012                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21013                 echo "$count subdirs migrated to MDT$i"
21014                 (( i == 3 )) && (( count > 0 )) &&
21015                         error "subdir shouldn't be migrated to MDT3"
21016         done
21017         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21018         (( count == 3 )) || error "dirs migrated to $count MDTs"
21019 }
21020 run_test 230v "subdir migrated to the MDT where its parent is located"
21021
21022 test_230w() {
21023         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21024         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21025                 skip "Need MDS version at least 2.15.0"
21026
21027         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21028         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21029         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21030
21031         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21032                 error "migrate failed"
21033
21034         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21035                 error "$tdir stripe count mismatch"
21036
21037         for i in $(seq 0 9); do
21038                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21039                         error "d$i is striped"
21040         done
21041 }
21042 run_test 230w "non-recursive mode dir migration"
21043
21044 test_230x() {
21045         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21046         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21047                 skip "Need MDS version at least 2.15.0"
21048
21049         mkdir -p $DIR/$tdir || error "mkdir failed"
21050         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21051
21052         local mdt_name=$(mdtname_from_index 0)
21053         local low=$(do_facet mds2 $LCTL get_param -n \
21054                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21055         local high=$(do_facet mds2 $LCTL get_param -n \
21056                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21057         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21058         local maxage=$(do_facet mds2 $LCTL get_param -n \
21059                 osp.*$mdt_name-osp-MDT0001.maxage)
21060
21061         stack_trap "do_facet mds2 $LCTL set_param -n \
21062                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21063                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21064         stack_trap "do_facet mds2 $LCTL set_param -n \
21065                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21066
21067         do_facet mds2 $LCTL set_param -n \
21068                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21069         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21070         sleep 4
21071         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21072                 error "migrate $tdir should fail"
21073
21074         do_facet mds2 $LCTL set_param -n \
21075                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21076         do_facet mds2 $LCTL set_param -n \
21077                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21078         sleep 4
21079         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21080                 error "migrate failed"
21081         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21082                 error "$tdir stripe count mismatch"
21083 }
21084 run_test 230x "dir migration check space"
21085
21086 test_231a()
21087 {
21088         # For simplicity this test assumes that max_pages_per_rpc
21089         # is the same across all OSCs
21090         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21091         local bulk_size=$((max_pages * PAGE_SIZE))
21092         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21093                                        head -n 1)
21094
21095         mkdir -p $DIR/$tdir
21096         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21097                 error "failed to set stripe with -S ${brw_size}M option"
21098
21099         # clear the OSC stats
21100         $LCTL set_param osc.*.stats=0 &>/dev/null
21101         stop_writeback
21102
21103         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21104         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21105                 oflag=direct &>/dev/null || error "dd failed"
21106
21107         sync; sleep 1; sync # just to be safe
21108         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21109         if [ x$nrpcs != "x1" ]; then
21110                 $LCTL get_param osc.*.stats
21111                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21112         fi
21113
21114         start_writeback
21115         # Drop the OSC cache, otherwise we will read from it
21116         cancel_lru_locks osc
21117
21118         # clear the OSC stats
21119         $LCTL set_param osc.*.stats=0 &>/dev/null
21120
21121         # Client reads $bulk_size.
21122         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21123                 iflag=direct &>/dev/null || error "dd failed"
21124
21125         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21126         if [ x$nrpcs != "x1" ]; then
21127                 $LCTL get_param osc.*.stats
21128                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21129         fi
21130 }
21131 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21132
21133 test_231b() {
21134         mkdir -p $DIR/$tdir
21135         local i
21136         for i in {0..1023}; do
21137                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21138                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21139                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21140         done
21141         sync
21142 }
21143 run_test 231b "must not assert on fully utilized OST request buffer"
21144
21145 test_232a() {
21146         mkdir -p $DIR/$tdir
21147         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21148
21149         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21150         do_facet ost1 $LCTL set_param fail_loc=0x31c
21151
21152         # ignore dd failure
21153         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21154
21155         do_facet ost1 $LCTL set_param fail_loc=0
21156         umount_client $MOUNT || error "umount failed"
21157         mount_client $MOUNT || error "mount failed"
21158         stop ost1 || error "cannot stop ost1"
21159         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21160 }
21161 run_test 232a "failed lock should not block umount"
21162
21163 test_232b() {
21164         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21165                 skip "Need MDS version at least 2.10.58"
21166
21167         mkdir -p $DIR/$tdir
21168         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21169         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21170         sync
21171         cancel_lru_locks osc
21172
21173         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21174         do_facet ost1 $LCTL set_param fail_loc=0x31c
21175
21176         # ignore failure
21177         $LFS data_version $DIR/$tdir/$tfile || true
21178
21179         do_facet ost1 $LCTL set_param fail_loc=0
21180         umount_client $MOUNT || error "umount failed"
21181         mount_client $MOUNT || error "mount failed"
21182         stop ost1 || error "cannot stop ost1"
21183         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21184 }
21185 run_test 232b "failed data version lock should not block umount"
21186
21187 test_233a() {
21188         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21189                 skip "Need MDS version at least 2.3.64"
21190         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21191
21192         local fid=$($LFS path2fid $MOUNT)
21193
21194         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21195                 error "cannot access $MOUNT using its FID '$fid'"
21196 }
21197 run_test 233a "checking that OBF of the FS root succeeds"
21198
21199 test_233b() {
21200         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21201                 skip "Need MDS version at least 2.5.90"
21202         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21203
21204         local fid=$($LFS path2fid $MOUNT/.lustre)
21205
21206         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21207                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21208
21209         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21210         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21211                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21212 }
21213 run_test 233b "checking that OBF of the FS .lustre succeeds"
21214
21215 test_234() {
21216         local p="$TMP/sanityN-$TESTNAME.parameters"
21217         save_lustre_params client "llite.*.xattr_cache" > $p
21218         lctl set_param llite.*.xattr_cache 1 ||
21219                 skip_env "xattr cache is not supported"
21220
21221         mkdir -p $DIR/$tdir || error "mkdir failed"
21222         touch $DIR/$tdir/$tfile || error "touch failed"
21223         # OBD_FAIL_LLITE_XATTR_ENOMEM
21224         $LCTL set_param fail_loc=0x1405
21225         getfattr -n user.attr $DIR/$tdir/$tfile &&
21226                 error "getfattr should have failed with ENOMEM"
21227         $LCTL set_param fail_loc=0x0
21228         rm -rf $DIR/$tdir
21229
21230         restore_lustre_params < $p
21231         rm -f $p
21232 }
21233 run_test 234 "xattr cache should not crash on ENOMEM"
21234
21235 test_235() {
21236         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21237                 skip "Need MDS version at least 2.4.52"
21238
21239         flock_deadlock $DIR/$tfile
21240         local RC=$?
21241         case $RC in
21242                 0)
21243                 ;;
21244                 124) error "process hangs on a deadlock"
21245                 ;;
21246                 *) error "error executing flock_deadlock $DIR/$tfile"
21247                 ;;
21248         esac
21249 }
21250 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21251
21252 #LU-2935
21253 test_236() {
21254         check_swap_layouts_support
21255
21256         local ref1=/etc/passwd
21257         local ref2=/etc/group
21258         local file1=$DIR/$tdir/f1
21259         local file2=$DIR/$tdir/f2
21260
21261         test_mkdir -c1 $DIR/$tdir
21262         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21263         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21264         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21265         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21266         local fd=$(free_fd)
21267         local cmd="exec $fd<>$file2"
21268         eval $cmd
21269         rm $file2
21270         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21271                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21272         cmd="exec $fd>&-"
21273         eval $cmd
21274         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21275
21276         #cleanup
21277         rm -rf $DIR/$tdir
21278 }
21279 run_test 236 "Layout swap on open unlinked file"
21280
21281 # LU-4659 linkea consistency
21282 test_238() {
21283         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21284                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21285                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21286                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21287
21288         touch $DIR/$tfile
21289         ln $DIR/$tfile $DIR/$tfile.lnk
21290         touch $DIR/$tfile.new
21291         mv $DIR/$tfile.new $DIR/$tfile
21292         local fid1=$($LFS path2fid $DIR/$tfile)
21293         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21294         local path1=$($LFS fid2path $FSNAME "$fid1")
21295         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21296         local path2=$($LFS fid2path $FSNAME "$fid2")
21297         [ $tfile.lnk == $path2 ] ||
21298                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21299         rm -f $DIR/$tfile*
21300 }
21301 run_test 238 "Verify linkea consistency"
21302
21303 test_239A() { # was test_239
21304         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21305                 skip "Need MDS version at least 2.5.60"
21306
21307         local list=$(comma_list $(mdts_nodes))
21308
21309         mkdir -p $DIR/$tdir
21310         createmany -o $DIR/$tdir/f- 5000
21311         unlinkmany $DIR/$tdir/f- 5000
21312         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21313                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21314         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21315                         osp.*MDT*.sync_in_flight" | calc_sum)
21316         [ "$changes" -eq 0 ] || error "$changes not synced"
21317 }
21318 run_test 239A "osp_sync test"
21319
21320 test_239a() { #LU-5297
21321         remote_mds_nodsh && skip "remote MDS with nodsh"
21322
21323         touch $DIR/$tfile
21324         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21325         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21326         chgrp $RUNAS_GID $DIR/$tfile
21327         wait_delete_completed
21328 }
21329 run_test 239a "process invalid osp sync record correctly"
21330
21331 test_239b() { #LU-5297
21332         remote_mds_nodsh && skip "remote MDS with nodsh"
21333
21334         touch $DIR/$tfile1
21335         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21336         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21337         chgrp $RUNAS_GID $DIR/$tfile1
21338         wait_delete_completed
21339         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21340         touch $DIR/$tfile2
21341         chgrp $RUNAS_GID $DIR/$tfile2
21342         wait_delete_completed
21343 }
21344 run_test 239b "process osp sync record with ENOMEM error correctly"
21345
21346 test_240() {
21347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21348         remote_mds_nodsh && skip "remote MDS with nodsh"
21349
21350         mkdir -p $DIR/$tdir
21351
21352         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21353                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21354         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21355                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21356
21357         umount_client $MOUNT || error "umount failed"
21358         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21359         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21360         mount_client $MOUNT || error "failed to mount client"
21361
21362         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21363         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21364 }
21365 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21366
21367 test_241_bio() {
21368         local count=$1
21369         local bsize=$2
21370
21371         for LOOP in $(seq $count); do
21372                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21373                 cancel_lru_locks $OSC || true
21374         done
21375 }
21376
21377 test_241_dio() {
21378         local count=$1
21379         local bsize=$2
21380
21381         for LOOP in $(seq $1); do
21382                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21383                         2>/dev/null
21384         done
21385 }
21386
21387 test_241a() { # was test_241
21388         local bsize=$PAGE_SIZE
21389
21390         (( bsize < 40960 )) && bsize=40960
21391         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21392         ls -la $DIR/$tfile
21393         cancel_lru_locks $OSC
21394         test_241_bio 1000 $bsize &
21395         PID=$!
21396         test_241_dio 1000 $bsize
21397         wait $PID
21398 }
21399 run_test 241a "bio vs dio"
21400
21401 test_241b() {
21402         local bsize=$PAGE_SIZE
21403
21404         (( bsize < 40960 )) && bsize=40960
21405         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21406         ls -la $DIR/$tfile
21407         test_241_dio 1000 $bsize &
21408         PID=$!
21409         test_241_dio 1000 $bsize
21410         wait $PID
21411 }
21412 run_test 241b "dio vs dio"
21413
21414 test_242() {
21415         remote_mds_nodsh && skip "remote MDS with nodsh"
21416
21417         mkdir_on_mdt0 $DIR/$tdir
21418         touch $DIR/$tdir/$tfile
21419
21420         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21421         do_facet mds1 lctl set_param fail_loc=0x105
21422         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21423
21424         do_facet mds1 lctl set_param fail_loc=0
21425         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21426 }
21427 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21428
21429 test_243()
21430 {
21431         test_mkdir $DIR/$tdir
21432         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21433 }
21434 run_test 243 "various group lock tests"
21435
21436 test_244a()
21437 {
21438         test_mkdir $DIR/$tdir
21439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21440         sendfile_grouplock $DIR/$tdir/$tfile || \
21441                 error "sendfile+grouplock failed"
21442         rm -rf $DIR/$tdir
21443 }
21444 run_test 244a "sendfile with group lock tests"
21445
21446 test_244b()
21447 {
21448         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21449
21450         local threads=50
21451         local size=$((1024*1024))
21452
21453         test_mkdir $DIR/$tdir
21454         for i in $(seq 1 $threads); do
21455                 local file=$DIR/$tdir/file_$((i / 10))
21456                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21457                 local pids[$i]=$!
21458         done
21459         for i in $(seq 1 $threads); do
21460                 wait ${pids[$i]}
21461         done
21462 }
21463 run_test 244b "multi-threaded write with group lock"
21464
21465 test_245a() {
21466         local flagname="multi_mod_rpcs"
21467         local connect_data_name="max_mod_rpcs"
21468         local out
21469
21470         # check if multiple modify RPCs flag is set
21471         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21472                 grep "connect_flags:")
21473         echo "$out"
21474
21475         echo "$out" | grep -qw $flagname
21476         if [ $? -ne 0 ]; then
21477                 echo "connect flag $flagname is not set"
21478                 return
21479         fi
21480
21481         # check if multiple modify RPCs data is set
21482         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21483         echo "$out"
21484
21485         echo "$out" | grep -qw $connect_data_name ||
21486                 error "import should have connect data $connect_data_name"
21487 }
21488 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21489
21490 test_245b() {
21491         local flagname="multi_mod_rpcs"
21492         local connect_data_name="max_mod_rpcs"
21493         local out
21494
21495         remote_mds_nodsh && skip "remote MDS with nodsh"
21496         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21497
21498         # check if multiple modify RPCs flag is set
21499         out=$(do_facet mds1 \
21500               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21501               grep "connect_flags:")
21502         echo "$out"
21503
21504         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21505
21506         # check if multiple modify RPCs data is set
21507         out=$(do_facet mds1 \
21508               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21509
21510         [[ "$out" =~ $connect_data_name ]] ||
21511                 {
21512                         echo "$out"
21513                         error "missing connect data $connect_data_name"
21514                 }
21515 }
21516 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21517
21518 cleanup_247() {
21519         local submount=$1
21520
21521         trap 0
21522         umount_client $submount
21523         rmdir $submount
21524 }
21525
21526 test_247a() {
21527         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21528                 grep -q subtree ||
21529                 skip_env "Fileset feature is not supported"
21530
21531         local submount=${MOUNT}_$tdir
21532
21533         mkdir $MOUNT/$tdir
21534         mkdir -p $submount || error "mkdir $submount failed"
21535         FILESET="$FILESET/$tdir" mount_client $submount ||
21536                 error "mount $submount failed"
21537         trap "cleanup_247 $submount" EXIT
21538         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21539         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21540                 error "read $MOUNT/$tdir/$tfile failed"
21541         cleanup_247 $submount
21542 }
21543 run_test 247a "mount subdir as fileset"
21544
21545 test_247b() {
21546         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21547                 skip_env "Fileset feature is not supported"
21548
21549         local submount=${MOUNT}_$tdir
21550
21551         rm -rf $MOUNT/$tdir
21552         mkdir -p $submount || error "mkdir $submount failed"
21553         SKIP_FILESET=1
21554         FILESET="$FILESET/$tdir" mount_client $submount &&
21555                 error "mount $submount should fail"
21556         rmdir $submount
21557 }
21558 run_test 247b "mount subdir that dose not exist"
21559
21560 test_247c() {
21561         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21562                 skip_env "Fileset feature is not supported"
21563
21564         local submount=${MOUNT}_$tdir
21565
21566         mkdir -p $MOUNT/$tdir/dir1
21567         mkdir -p $submount || error "mkdir $submount failed"
21568         trap "cleanup_247 $submount" EXIT
21569         FILESET="$FILESET/$tdir" mount_client $submount ||
21570                 error "mount $submount failed"
21571         local fid=$($LFS path2fid $MOUNT/)
21572         $LFS fid2path $submount $fid && error "fid2path should fail"
21573         cleanup_247 $submount
21574 }
21575 run_test 247c "running fid2path outside subdirectory root"
21576
21577 test_247d() {
21578         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21579                 skip "Fileset feature is not supported"
21580
21581         local submount=${MOUNT}_$tdir
21582
21583         mkdir -p $MOUNT/$tdir/dir1
21584         mkdir -p $submount || error "mkdir $submount failed"
21585         FILESET="$FILESET/$tdir" mount_client $submount ||
21586                 error "mount $submount failed"
21587         trap "cleanup_247 $submount" EXIT
21588
21589         local td=$submount/dir1
21590         local fid=$($LFS path2fid $td)
21591         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21592
21593         # check that we get the same pathname back
21594         local rootpath
21595         local found
21596         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21597                 echo "$rootpath $fid"
21598                 found=$($LFS fid2path $rootpath "$fid")
21599                 [ -n "$found" ] || error "fid2path should succeed"
21600                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21601         done
21602         # check wrong root path format
21603         rootpath=$submount"_wrong"
21604         found=$($LFS fid2path $rootpath "$fid")
21605         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21606
21607         cleanup_247 $submount
21608 }
21609 run_test 247d "running fid2path inside subdirectory root"
21610
21611 # LU-8037
21612 test_247e() {
21613         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21614                 grep -q subtree ||
21615                 skip "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/.." mount_client $submount &&
21622                 error "mount $submount should fail"
21623         rmdir $submount
21624 }
21625 run_test 247e "mount .. as fileset"
21626
21627 test_247f() {
21628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21629         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21630                 skip "Need at least version 2.13.52"
21631         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21632                 skip "Need at least version 2.14.50"
21633         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21634                 grep -q subtree ||
21635                 skip "Fileset feature is not supported"
21636
21637         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21638         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21639                 error "mkdir remote failed"
21640         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21641                 error "mkdir remote/subdir failed"
21642         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21643                 error "mkdir striped failed"
21644         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21645
21646         local submount=${MOUNT}_$tdir
21647
21648         mkdir -p $submount || error "mkdir $submount failed"
21649         stack_trap "rmdir $submount"
21650
21651         local dir
21652         local stat
21653         local fileset=$FILESET
21654         local mdts=$(comma_list $(mdts_nodes))
21655
21656         stat=$(do_facet mds1 $LCTL get_param -n \
21657                 mdt.*MDT0000.enable_remote_subdir_mount)
21658         stack_trap "do_nodes $mdts $LCTL set_param \
21659                 mdt.*.enable_remote_subdir_mount=$stat"
21660
21661         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21662         stack_trap "umount_client $submount"
21663         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21664                 error "mount remote dir $dir should fail"
21665
21666         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21667                 $tdir/striped/. ; do
21668                 FILESET="$fileset/$dir" mount_client $submount ||
21669                         error "mount $dir failed"
21670                 umount_client $submount
21671         done
21672
21673         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21674         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21675                 error "mount $tdir/remote failed"
21676 }
21677 run_test 247f "mount striped or remote directory as fileset"
21678
21679 test_247g() {
21680         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21681         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21682                 skip "Need at least version 2.14.50"
21683
21684         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21685                 error "mkdir $tdir failed"
21686         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21687
21688         local submount=${MOUNT}_$tdir
21689
21690         mkdir -p $submount || error "mkdir $submount failed"
21691         stack_trap "rmdir $submount"
21692
21693         FILESET="$fileset/$tdir" mount_client $submount ||
21694                 error "mount $dir failed"
21695         stack_trap "umount $submount"
21696
21697         local mdts=$(comma_list $(mdts_nodes))
21698
21699         local nrpcs
21700
21701         stat $submount > /dev/null
21702         cancel_lru_locks $MDC
21703         stat $submount > /dev/null
21704         stat $submount/$tfile > /dev/null
21705         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21706         stat $submount/$tfile > /dev/null
21707         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21708                 awk '/getattr/ {sum += $2} END {print sum}')
21709
21710         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21711 }
21712 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21713
21714 test_248a() {
21715         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21716         [ -z "$fast_read_sav" ] && skip "no fast read support"
21717
21718         # create a large file for fast read verification
21719         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21720
21721         # make sure the file is created correctly
21722         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21723                 { rm -f $DIR/$tfile; skip "file creation error"; }
21724
21725         echo "Test 1: verify that fast read is 4 times faster on cache read"
21726
21727         # small read with fast read enabled
21728         $LCTL set_param -n llite.*.fast_read=1
21729         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21730                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21731                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21732         # small read with fast read disabled
21733         $LCTL set_param -n llite.*.fast_read=0
21734         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21735                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21736                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21737
21738         # verify that fast read is 4 times faster for cache read
21739         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21740                 error_not_in_vm "fast read was not 4 times faster: " \
21741                            "$t_fast vs $t_slow"
21742
21743         echo "Test 2: verify the performance between big and small read"
21744         $LCTL set_param -n llite.*.fast_read=1
21745
21746         # 1k non-cache read
21747         cancel_lru_locks osc
21748         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21749                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21750                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21751
21752         # 1M non-cache read
21753         cancel_lru_locks osc
21754         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21755                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21756                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21757
21758         # verify that big IO is not 4 times faster than small IO
21759         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21760                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21761
21762         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21763         rm -f $DIR/$tfile
21764 }
21765 run_test 248a "fast read verification"
21766
21767 test_248b() {
21768         # Default short_io_bytes=16384, try both smaller and larger sizes.
21769         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21770         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21771         echo "bs=53248 count=113 normal buffered write"
21772         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21773                 error "dd of initial data file failed"
21774         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21775
21776         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21777         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21778                 error "dd with sync normal writes failed"
21779         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21780
21781         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21782         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21783                 error "dd with sync small writes failed"
21784         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21785
21786         cancel_lru_locks osc
21787
21788         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21789         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21790         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21791         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21792                 iflag=direct || error "dd with O_DIRECT small read failed"
21793         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21794         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21795                 error "compare $TMP/$tfile.1 failed"
21796
21797         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21798         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21799
21800         # just to see what the maximum tunable value is, and test parsing
21801         echo "test invalid parameter 2MB"
21802         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21803                 error "too-large short_io_bytes allowed"
21804         echo "test maximum parameter 512KB"
21805         # if we can set a larger short_io_bytes, run test regardless of version
21806         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21807                 # older clients may not allow setting it this large, that's OK
21808                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21809                         skip "Need at least client version 2.13.50"
21810                 error "medium short_io_bytes failed"
21811         fi
21812         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21813         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21814
21815         echo "test large parameter 64KB"
21816         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21817         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21818
21819         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21820         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21821                 error "dd with sync large writes failed"
21822         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21823
21824         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21825         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21826         num=$((113 * 4096 / PAGE_SIZE))
21827         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21828         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21829                 error "dd with O_DIRECT large writes failed"
21830         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21831                 error "compare $DIR/$tfile.3 failed"
21832
21833         cancel_lru_locks osc
21834
21835         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21836         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21837                 error "dd with O_DIRECT large read failed"
21838         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21839                 error "compare $TMP/$tfile.2 failed"
21840
21841         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21842         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21843                 error "dd with O_DIRECT large read failed"
21844         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21845                 error "compare $TMP/$tfile.3 failed"
21846 }
21847 run_test 248b "test short_io read and write for both small and large sizes"
21848
21849 test_249() { # LU-7890
21850         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21851                 skip "Need at least version 2.8.54"
21852
21853         rm -f $DIR/$tfile
21854         $LFS setstripe -c 1 $DIR/$tfile
21855         # Offset 2T == 4k * 512M
21856         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21857                 error "dd to 2T offset failed"
21858 }
21859 run_test 249 "Write above 2T file size"
21860
21861 test_250() {
21862         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21863          && skip "no 16TB file size limit on ZFS"
21864
21865         $LFS setstripe -c 1 $DIR/$tfile
21866         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21867         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21868         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21869         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21870                 conv=notrunc,fsync && error "append succeeded"
21871         return 0
21872 }
21873 run_test 250 "Write above 16T limit"
21874
21875 test_251() {
21876         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21877
21878         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21879         #Skip once - writing the first stripe will succeed
21880         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21881         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21882                 error "short write happened"
21883
21884         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21885         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21886                 error "short read happened"
21887
21888         rm -f $DIR/$tfile
21889 }
21890 run_test 251 "Handling short read and write correctly"
21891
21892 test_252() {
21893         remote_mds_nodsh && skip "remote MDS with nodsh"
21894         remote_ost_nodsh && skip "remote OST with nodsh"
21895         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21896                 skip_env "ldiskfs only test"
21897         fi
21898
21899         local tgt
21900         local dev
21901         local out
21902         local uuid
21903         local num
21904         local gen
21905
21906         # check lr_reader on OST0000
21907         tgt=ost1
21908         dev=$(facet_device $tgt)
21909         out=$(do_facet $tgt $LR_READER $dev)
21910         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21911         echo "$out"
21912         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21913         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21914                 error "Invalid uuid returned by $LR_READER on target $tgt"
21915         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21916
21917         # check lr_reader -c on MDT0000
21918         tgt=mds1
21919         dev=$(facet_device $tgt)
21920         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21921                 skip "$LR_READER does not support additional options"
21922         fi
21923         out=$(do_facet $tgt $LR_READER -c $dev)
21924         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21925         echo "$out"
21926         num=$(echo "$out" | grep -c "mdtlov")
21927         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21928                 error "Invalid number of mdtlov clients returned by $LR_READER"
21929         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21930
21931         # check lr_reader -cr on MDT0000
21932         out=$(do_facet $tgt $LR_READER -cr $dev)
21933         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21934         echo "$out"
21935         echo "$out" | grep -q "^reply_data:$" ||
21936                 error "$LR_READER should have returned 'reply_data' section"
21937         num=$(echo "$out" | grep -c "client_generation")
21938         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21939 }
21940 run_test 252 "check lr_reader tool"
21941
21942 test_253() {
21943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21944         remote_mds_nodsh && skip "remote MDS with nodsh"
21945         remote_mgs_nodsh && skip "remote MGS with nodsh"
21946
21947         local ostidx=0
21948         local rc=0
21949         local ost_name=$(ostname_from_index $ostidx)
21950
21951         # on the mdt's osc
21952         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21953         do_facet $SINGLEMDS $LCTL get_param -n \
21954                 osp.$mdtosc_proc1.reserved_mb_high ||
21955                 skip  "remote MDS does not support reserved_mb_high"
21956
21957         rm -rf $DIR/$tdir
21958         wait_mds_ost_sync
21959         wait_delete_completed
21960         mkdir $DIR/$tdir
21961
21962         pool_add $TESTNAME || error "Pool creation failed"
21963         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21964
21965         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21966                 error "Setstripe failed"
21967
21968         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21969
21970         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21971                     grep "watermarks")
21972         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21973
21974         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21975                         osp.$mdtosc_proc1.prealloc_status)
21976         echo "prealloc_status $oa_status"
21977
21978         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21979                 error "File creation should fail"
21980
21981         #object allocation was stopped, but we still able to append files
21982         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21983                 oflag=append || error "Append failed"
21984
21985         rm -f $DIR/$tdir/$tfile.0
21986
21987         # For this test, we want to delete the files we created to go out of
21988         # space but leave the watermark, so we remain nearly out of space
21989         ost_watermarks_enospc_delete_files $tfile $ostidx
21990
21991         wait_delete_completed
21992
21993         sleep_maxage
21994
21995         for i in $(seq 10 12); do
21996                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21997                         2>/dev/null || error "File creation failed after rm"
21998         done
21999
22000         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22001                         osp.$mdtosc_proc1.prealloc_status)
22002         echo "prealloc_status $oa_status"
22003
22004         if (( oa_status != 0 )); then
22005                 error "Object allocation still disable after rm"
22006         fi
22007 }
22008 run_test 253 "Check object allocation limit"
22009
22010 test_254() {
22011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22012         remote_mds_nodsh && skip "remote MDS with nodsh"
22013
22014         local mdt=$(facet_svc $SINGLEMDS)
22015
22016         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22017                 skip "MDS does not support changelog_size"
22018
22019         local cl_user
22020
22021         changelog_register || error "changelog_register failed"
22022
22023         changelog_clear 0 || error "changelog_clear failed"
22024
22025         local size1=$(do_facet $SINGLEMDS \
22026                       $LCTL get_param -n mdd.$mdt.changelog_size)
22027         echo "Changelog size $size1"
22028
22029         rm -rf $DIR/$tdir
22030         $LFS mkdir -i 0 $DIR/$tdir
22031         # change something
22032         mkdir -p $DIR/$tdir/pics/2008/zachy
22033         touch $DIR/$tdir/pics/2008/zachy/timestamp
22034         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22035         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22036         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22037         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22038         rm $DIR/$tdir/pics/desktop.jpg
22039
22040         local size2=$(do_facet $SINGLEMDS \
22041                       $LCTL get_param -n mdd.$mdt.changelog_size)
22042         echo "Changelog size after work $size2"
22043
22044         (( $size2 > $size1 )) ||
22045                 error "new Changelog size=$size2 less than old size=$size1"
22046 }
22047 run_test 254 "Check changelog size"
22048
22049 ladvise_no_type()
22050 {
22051         local type=$1
22052         local file=$2
22053
22054         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22055                 awk -F: '{print $2}' | grep $type > /dev/null
22056         if [ $? -ne 0 ]; then
22057                 return 0
22058         fi
22059         return 1
22060 }
22061
22062 ladvise_no_ioctl()
22063 {
22064         local file=$1
22065
22066         lfs ladvise -a willread $file > /dev/null 2>&1
22067         if [ $? -eq 0 ]; then
22068                 return 1
22069         fi
22070
22071         lfs ladvise -a willread $file 2>&1 |
22072                 grep "Inappropriate ioctl for device" > /dev/null
22073         if [ $? -eq 0 ]; then
22074                 return 0
22075         fi
22076         return 1
22077 }
22078
22079 percent() {
22080         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22081 }
22082
22083 # run a random read IO workload
22084 # usage: random_read_iops <filename> <filesize> <iosize>
22085 random_read_iops() {
22086         local file=$1
22087         local fsize=$2
22088         local iosize=${3:-4096}
22089
22090         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22091                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22092 }
22093
22094 drop_file_oss_cache() {
22095         local file="$1"
22096         local nodes="$2"
22097
22098         $LFS ladvise -a dontneed $file 2>/dev/null ||
22099                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22100 }
22101
22102 ladvise_willread_performance()
22103 {
22104         local repeat=10
22105         local average_origin=0
22106         local average_cache=0
22107         local average_ladvise=0
22108
22109         for ((i = 1; i <= $repeat; i++)); do
22110                 echo "Iter $i/$repeat: reading without willread hint"
22111                 cancel_lru_locks osc
22112                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22113                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22114                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22115                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22116
22117                 cancel_lru_locks osc
22118                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22119                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22120                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22121
22122                 cancel_lru_locks osc
22123                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22124                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22125                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22126                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22127                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22128         done
22129         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22130         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22131         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22132
22133         speedup_cache=$(percent $average_cache $average_origin)
22134         speedup_ladvise=$(percent $average_ladvise $average_origin)
22135
22136         echo "Average uncached read: $average_origin"
22137         echo "Average speedup with OSS cached read: " \
22138                 "$average_cache = +$speedup_cache%"
22139         echo "Average speedup with ladvise willread: " \
22140                 "$average_ladvise = +$speedup_ladvise%"
22141
22142         local lowest_speedup=20
22143         if (( ${average_cache%.*} < $lowest_speedup )); then
22144                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22145                      " got $average_cache%. Skipping ladvise willread check."
22146                 return 0
22147         fi
22148
22149         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22150         # it is still good to run until then to exercise 'ladvise willread'
22151         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22152                 [ "$ost1_FSTYPE" = "zfs" ] &&
22153                 echo "osd-zfs does not support dontneed or drop_caches" &&
22154                 return 0
22155
22156         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22157         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22158                 error_not_in_vm "Speedup with willread is less than " \
22159                         "$lowest_speedup%, got $average_ladvise%"
22160 }
22161
22162 test_255a() {
22163         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22164                 skip "lustre < 2.8.54 does not support ladvise "
22165         remote_ost_nodsh && skip "remote OST with nodsh"
22166
22167         stack_trap "rm -f $DIR/$tfile"
22168         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22169
22170         ladvise_no_type willread $DIR/$tfile &&
22171                 skip "willread ladvise is not supported"
22172
22173         ladvise_no_ioctl $DIR/$tfile &&
22174                 skip "ladvise ioctl is not supported"
22175
22176         local size_mb=100
22177         local size=$((size_mb * 1048576))
22178         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22179                 error "dd to $DIR/$tfile failed"
22180
22181         lfs ladvise -a willread $DIR/$tfile ||
22182                 error "Ladvise failed with no range argument"
22183
22184         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22185                 error "Ladvise failed with no -l or -e argument"
22186
22187         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22188                 error "Ladvise failed with only -e argument"
22189
22190         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22191                 error "Ladvise failed with only -l argument"
22192
22193         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22194                 error "End offset should not be smaller than start offset"
22195
22196         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22197                 error "End offset should not be equal to start offset"
22198
22199         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22200                 error "Ladvise failed with overflowing -s argument"
22201
22202         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22203                 error "Ladvise failed with overflowing -e argument"
22204
22205         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22206                 error "Ladvise failed with overflowing -l argument"
22207
22208         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22209                 error "Ladvise succeeded with conflicting -l and -e arguments"
22210
22211         echo "Synchronous ladvise should wait"
22212         local delay=4
22213 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22214         do_nodes $(comma_list $(osts_nodes)) \
22215                 $LCTL set_param fail_val=$delay fail_loc=0x237
22216
22217         local start_ts=$SECONDS
22218         lfs ladvise -a willread $DIR/$tfile ||
22219                 error "Ladvise failed with no range argument"
22220         local end_ts=$SECONDS
22221         local inteval_ts=$((end_ts - start_ts))
22222
22223         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22224                 error "Synchronous advice didn't wait reply"
22225         fi
22226
22227         echo "Asynchronous ladvise shouldn't wait"
22228         local start_ts=$SECONDS
22229         lfs ladvise -a willread -b $DIR/$tfile ||
22230                 error "Ladvise failed with no range argument"
22231         local end_ts=$SECONDS
22232         local inteval_ts=$((end_ts - start_ts))
22233
22234         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22235                 error "Asynchronous advice blocked"
22236         fi
22237
22238         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22239         ladvise_willread_performance
22240 }
22241 run_test 255a "check 'lfs ladvise -a willread'"
22242
22243 facet_meminfo() {
22244         local facet=$1
22245         local info=$2
22246
22247         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22248 }
22249
22250 test_255b() {
22251         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22252                 skip "lustre < 2.8.54 does not support ladvise "
22253         remote_ost_nodsh && skip "remote OST with nodsh"
22254
22255         stack_trap "rm -f $DIR/$tfile"
22256         lfs setstripe -c 1 -i 0 $DIR/$tfile
22257
22258         ladvise_no_type dontneed $DIR/$tfile &&
22259                 skip "dontneed ladvise is not supported"
22260
22261         ladvise_no_ioctl $DIR/$tfile &&
22262                 skip "ladvise ioctl is not supported"
22263
22264         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22265                 [ "$ost1_FSTYPE" = "zfs" ] &&
22266                 skip "zfs-osd does not support 'ladvise dontneed'"
22267
22268         local size_mb=100
22269         local size=$((size_mb * 1048576))
22270         # In order to prevent disturbance of other processes, only check 3/4
22271         # of the memory usage
22272         local kibibytes=$((size_mb * 1024 * 3 / 4))
22273
22274         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22275                 error "dd to $DIR/$tfile failed"
22276
22277         #force write to complete before dropping OST cache & checking memory
22278         sync
22279
22280         local total=$(facet_meminfo ost1 MemTotal)
22281         echo "Total memory: $total KiB"
22282
22283         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22284         local before_read=$(facet_meminfo ost1 Cached)
22285         echo "Cache used before read: $before_read KiB"
22286
22287         lfs ladvise -a willread $DIR/$tfile ||
22288                 error "Ladvise willread failed"
22289         local after_read=$(facet_meminfo ost1 Cached)
22290         echo "Cache used after read: $after_read KiB"
22291
22292         lfs ladvise -a dontneed $DIR/$tfile ||
22293                 error "Ladvise dontneed again failed"
22294         local no_read=$(facet_meminfo ost1 Cached)
22295         echo "Cache used after dontneed ladvise: $no_read KiB"
22296
22297         if [ $total -lt $((before_read + kibibytes)) ]; then
22298                 echo "Memory is too small, abort checking"
22299                 return 0
22300         fi
22301
22302         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22303                 error "Ladvise willread should use more memory" \
22304                         "than $kibibytes KiB"
22305         fi
22306
22307         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22308                 error "Ladvise dontneed should release more memory" \
22309                         "than $kibibytes KiB"
22310         fi
22311 }
22312 run_test 255b "check 'lfs ladvise -a dontneed'"
22313
22314 test_255c() {
22315         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22316                 skip "lustre < 2.10.50 does not support lockahead"
22317
22318         local ost1_imp=$(get_osc_import_name client ost1)
22319         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22320                          cut -d'.' -f2)
22321         local count
22322         local new_count
22323         local difference
22324         local i
22325         local rc
22326
22327         test_mkdir -p $DIR/$tdir
22328         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22329
22330         #test 10 returns only success/failure
22331         i=10
22332         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22333         rc=$?
22334         if [ $rc -eq 255 ]; then
22335                 error "Ladvise test${i} failed, ${rc}"
22336         fi
22337
22338         #test 11 counts lock enqueue requests, all others count new locks
22339         i=11
22340         count=$(do_facet ost1 \
22341                 $LCTL get_param -n ost.OSS.ost.stats)
22342         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22343
22344         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22345         rc=$?
22346         if [ $rc -eq 255 ]; then
22347                 error "Ladvise test${i} failed, ${rc}"
22348         fi
22349
22350         new_count=$(do_facet ost1 \
22351                 $LCTL get_param -n ost.OSS.ost.stats)
22352         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22353                    awk '{ print $2 }')
22354
22355         difference="$((new_count - count))"
22356         if [ $difference -ne $rc ]; then
22357                 error "Ladvise test${i}, bad enqueue count, returned " \
22358                       "${rc}, actual ${difference}"
22359         fi
22360
22361         for i in $(seq 12 21); do
22362                 # If we do not do this, we run the risk of having too many
22363                 # locks and starting lock cancellation while we are checking
22364                 # lock counts.
22365                 cancel_lru_locks osc
22366
22367                 count=$($LCTL get_param -n \
22368                        ldlm.namespaces.$imp_name.lock_unused_count)
22369
22370                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22371                 rc=$?
22372                 if [ $rc -eq 255 ]; then
22373                         error "Ladvise test ${i} failed, ${rc}"
22374                 fi
22375
22376                 new_count=$($LCTL get_param -n \
22377                        ldlm.namespaces.$imp_name.lock_unused_count)
22378                 difference="$((new_count - count))"
22379
22380                 # Test 15 output is divided by 100 to map down to valid return
22381                 if [ $i -eq 15 ]; then
22382                         rc="$((rc * 100))"
22383                 fi
22384
22385                 if [ $difference -ne $rc ]; then
22386                         error "Ladvise test ${i}, bad lock count, returned " \
22387                               "${rc}, actual ${difference}"
22388                 fi
22389         done
22390
22391         #test 22 returns only success/failure
22392         i=22
22393         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22394         rc=$?
22395         if [ $rc -eq 255 ]; then
22396                 error "Ladvise test${i} failed, ${rc}"
22397         fi
22398 }
22399 run_test 255c "suite of ladvise lockahead tests"
22400
22401 test_256() {
22402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22403         remote_mds_nodsh && skip "remote MDS with nodsh"
22404         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22405         changelog_users $SINGLEMDS | grep "^cl" &&
22406                 skip "active changelog user"
22407
22408         local cl_user
22409         local cat_sl
22410         local mdt_dev
22411
22412         mdt_dev=$(facet_device $SINGLEMDS)
22413         echo $mdt_dev
22414
22415         changelog_register || error "changelog_register failed"
22416
22417         rm -rf $DIR/$tdir
22418         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22419
22420         changelog_clear 0 || error "changelog_clear failed"
22421
22422         # change something
22423         touch $DIR/$tdir/{1..10}
22424
22425         # stop the MDT
22426         stop $SINGLEMDS || error "Fail to stop MDT"
22427
22428         # remount the MDT
22429         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22430                 error "Fail to start MDT"
22431
22432         #after mount new plainllog is used
22433         touch $DIR/$tdir/{11..19}
22434         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22435         stack_trap "rm -f $tmpfile"
22436         cat_sl=$(do_facet $SINGLEMDS "sync; \
22437                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22438                  llog_reader $tmpfile | grep -c type=1064553b")
22439         do_facet $SINGLEMDS llog_reader $tmpfile
22440
22441         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22442
22443         changelog_clear 0 || error "changelog_clear failed"
22444
22445         cat_sl=$(do_facet $SINGLEMDS "sync; \
22446                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22447                  llog_reader $tmpfile | grep -c type=1064553b")
22448
22449         if (( cat_sl == 2 )); then
22450                 error "Empty plain llog was not deleted from changelog catalog"
22451         elif (( cat_sl != 1 )); then
22452                 error "Active plain llog shouldn't be deleted from catalog"
22453         fi
22454 }
22455 run_test 256 "Check llog delete for empty and not full state"
22456
22457 test_257() {
22458         remote_mds_nodsh && skip "remote MDS with nodsh"
22459         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22460                 skip "Need MDS version at least 2.8.55"
22461
22462         test_mkdir $DIR/$tdir
22463
22464         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22465                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22466         stat $DIR/$tdir
22467
22468 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22469         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22470         local facet=mds$((mdtidx + 1))
22471         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22472         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22473
22474         stop $facet || error "stop MDS failed"
22475         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22476                 error "start MDS fail"
22477         wait_recovery_complete $facet
22478 }
22479 run_test 257 "xattr locks are not lost"
22480
22481 # Verify we take the i_mutex when security requires it
22482 test_258a() {
22483 #define OBD_FAIL_IMUTEX_SEC 0x141c
22484         $LCTL set_param fail_loc=0x141c
22485         touch $DIR/$tfile
22486         chmod u+s $DIR/$tfile
22487         chmod a+rwx $DIR/$tfile
22488         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22489         RC=$?
22490         if [ $RC -ne 0 ]; then
22491                 error "error, failed to take i_mutex, rc=$?"
22492         fi
22493         rm -f $DIR/$tfile
22494 }
22495 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22496
22497 # Verify we do NOT take the i_mutex in the normal case
22498 test_258b() {
22499 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22500         $LCTL set_param fail_loc=0x141d
22501         touch $DIR/$tfile
22502         chmod a+rwx $DIR
22503         chmod a+rw $DIR/$tfile
22504         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22505         RC=$?
22506         if [ $RC -ne 0 ]; then
22507                 error "error, took i_mutex unnecessarily, rc=$?"
22508         fi
22509         rm -f $DIR/$tfile
22510
22511 }
22512 run_test 258b "verify i_mutex security behavior"
22513
22514 test_259() {
22515         local file=$DIR/$tfile
22516         local before
22517         local after
22518
22519         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22520
22521         stack_trap "rm -f $file" EXIT
22522
22523         wait_delete_completed
22524         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22525         echo "before: $before"
22526
22527         $LFS setstripe -i 0 -c 1 $file
22528         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22529         sync_all_data
22530         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22531         echo "after write: $after"
22532
22533 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22534         do_facet ost1 $LCTL set_param fail_loc=0x2301
22535         $TRUNCATE $file 0
22536         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22537         echo "after truncate: $after"
22538
22539         stop ost1
22540         do_facet ost1 $LCTL set_param fail_loc=0
22541         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22542         sleep 2
22543         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22544         echo "after restart: $after"
22545         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22546                 error "missing truncate?"
22547
22548         return 0
22549 }
22550 run_test 259 "crash at delayed truncate"
22551
22552 test_260() {
22553 #define OBD_FAIL_MDC_CLOSE               0x806
22554         $LCTL set_param fail_loc=0x80000806
22555         touch $DIR/$tfile
22556
22557 }
22558 run_test 260 "Check mdc_close fail"
22559
22560 ### Data-on-MDT sanity tests ###
22561 test_270a() {
22562         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22563                 skip "Need MDS version at least 2.10.55 for DoM"
22564
22565         # create DoM file
22566         local dom=$DIR/$tdir/dom_file
22567         local tmp=$DIR/$tdir/tmp_file
22568
22569         mkdir_on_mdt0 $DIR/$tdir
22570
22571         # basic checks for DoM component creation
22572         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22573                 error "Can set MDT layout to non-first entry"
22574
22575         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22576                 error "Can define multiple entries as MDT layout"
22577
22578         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22579
22580         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22581         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22582         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22583
22584         local mdtidx=$($LFS getstripe -m $dom)
22585         local mdtname=MDT$(printf %04x $mdtidx)
22586         local facet=mds$((mdtidx + 1))
22587         local space_check=1
22588
22589         # Skip free space checks with ZFS
22590         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22591
22592         # write
22593         sync
22594         local size_tmp=$((65536 * 3))
22595         local mdtfree1=$(do_facet $facet \
22596                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22597
22598         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22599         # check also direct IO along write
22600         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22601         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22602         sync
22603         cmp $tmp $dom || error "file data is different"
22604         [ $(stat -c%s $dom) == $size_tmp ] ||
22605                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22606         if [ $space_check == 1 ]; then
22607                 local mdtfree2=$(do_facet $facet \
22608                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22609
22610                 # increase in usage from by $size_tmp
22611                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22612                         error "MDT free space wrong after write: " \
22613                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22614         fi
22615
22616         # truncate
22617         local size_dom=10000
22618
22619         $TRUNCATE $dom $size_dom
22620         [ $(stat -c%s $dom) == $size_dom ] ||
22621                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22622         if [ $space_check == 1 ]; then
22623                 mdtfree1=$(do_facet $facet \
22624                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22625                 # decrease in usage from $size_tmp to new $size_dom
22626                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22627                   $(((size_tmp - size_dom) / 1024)) ] ||
22628                         error "MDT free space is wrong after truncate: " \
22629                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22630         fi
22631
22632         # append
22633         cat $tmp >> $dom
22634         sync
22635         size_dom=$((size_dom + size_tmp))
22636         [ $(stat -c%s $dom) == $size_dom ] ||
22637                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22638         if [ $space_check == 1 ]; then
22639                 mdtfree2=$(do_facet $facet \
22640                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22641                 # increase in usage by $size_tmp from previous
22642                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22643                         error "MDT free space is wrong after append: " \
22644                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22645         fi
22646
22647         # delete
22648         rm $dom
22649         if [ $space_check == 1 ]; then
22650                 mdtfree1=$(do_facet $facet \
22651                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22652                 # decrease in usage by $size_dom from previous
22653                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22654                         error "MDT free space is wrong after removal: " \
22655                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22656         fi
22657
22658         # combined striping
22659         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22660                 error "Can't create DoM + OST striping"
22661
22662         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22663         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22664         # check also direct IO along write
22665         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22666         sync
22667         cmp $tmp $dom || error "file data is different"
22668         [ $(stat -c%s $dom) == $size_tmp ] ||
22669                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22670         rm $dom $tmp
22671
22672         return 0
22673 }
22674 run_test 270a "DoM: basic functionality tests"
22675
22676 test_270b() {
22677         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22678                 skip "Need MDS version at least 2.10.55"
22679
22680         local dom=$DIR/$tdir/dom_file
22681         local max_size=1048576
22682
22683         mkdir -p $DIR/$tdir
22684         $LFS setstripe -E $max_size -L mdt $dom
22685
22686         # truncate over the limit
22687         $TRUNCATE $dom $(($max_size + 1)) &&
22688                 error "successful truncate over the maximum size"
22689         # write over the limit
22690         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22691                 error "successful write over the maximum size"
22692         # append over the limit
22693         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22694         echo "12345" >> $dom && error "successful append over the maximum size"
22695         rm $dom
22696
22697         return 0
22698 }
22699 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22700
22701 test_270c() {
22702         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22703                 skip "Need MDS version at least 2.10.55"
22704
22705         mkdir -p $DIR/$tdir
22706         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22707
22708         # check files inherit DoM EA
22709         touch $DIR/$tdir/first
22710         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22711                 error "bad pattern"
22712         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22713                 error "bad stripe count"
22714         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22715                 error "bad stripe size"
22716
22717         # check directory inherits DoM EA and uses it as default
22718         mkdir $DIR/$tdir/subdir
22719         touch $DIR/$tdir/subdir/second
22720         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22721                 error "bad pattern in sub-directory"
22722         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22723                 error "bad stripe count in sub-directory"
22724         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22725                 error "bad stripe size in sub-directory"
22726         return 0
22727 }
22728 run_test 270c "DoM: DoM EA inheritance tests"
22729
22730 test_270d() {
22731         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22732                 skip "Need MDS version at least 2.10.55"
22733
22734         mkdir -p $DIR/$tdir
22735         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22736
22737         # inherit default DoM striping
22738         mkdir $DIR/$tdir/subdir
22739         touch $DIR/$tdir/subdir/f1
22740
22741         # change default directory striping
22742         $LFS setstripe -c 1 $DIR/$tdir/subdir
22743         touch $DIR/$tdir/subdir/f2
22744         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22745                 error "wrong default striping in file 2"
22746         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22747                 error "bad pattern in file 2"
22748         return 0
22749 }
22750 run_test 270d "DoM: change striping from DoM to RAID0"
22751
22752 test_270e() {
22753         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22754                 skip "Need MDS version at least 2.10.55"
22755
22756         mkdir -p $DIR/$tdir/dom
22757         mkdir -p $DIR/$tdir/norm
22758         DOMFILES=20
22759         NORMFILES=10
22760         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22761         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22762
22763         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22764         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22765
22766         # find DoM files by layout
22767         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22768         [ $NUM -eq  $DOMFILES ] ||
22769                 error "lfs find -L: found $NUM, expected $DOMFILES"
22770         echo "Test 1: lfs find 20 DOM files by layout: OK"
22771
22772         # there should be 1 dir with default DOM striping
22773         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22774         [ $NUM -eq  1 ] ||
22775                 error "lfs find -L: found $NUM, expected 1 dir"
22776         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22777
22778         # find DoM files by stripe size
22779         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22780         [ $NUM -eq  $DOMFILES ] ||
22781                 error "lfs find -S: found $NUM, expected $DOMFILES"
22782         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22783
22784         # find files by stripe offset except DoM files
22785         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22786         [ $NUM -eq  $NORMFILES ] ||
22787                 error "lfs find -i: found $NUM, expected $NORMFILES"
22788         echo "Test 5: lfs find no DOM files by stripe index: OK"
22789         return 0
22790 }
22791 run_test 270e "DoM: lfs find with DoM files test"
22792
22793 test_270f() {
22794         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22795                 skip "Need MDS version at least 2.10.55"
22796
22797         local mdtname=${FSNAME}-MDT0000-mdtlov
22798         local dom=$DIR/$tdir/dom_file
22799         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22800                                                 lod.$mdtname.dom_stripesize)
22801         local dom_limit=131072
22802
22803         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22804         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22805                                                 lod.$mdtname.dom_stripesize)
22806         [ ${dom_limit} -eq ${dom_current} ] ||
22807                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22808
22809         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22810         $LFS setstripe -d $DIR/$tdir
22811         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22812                 error "Can't set directory default striping"
22813
22814         # exceed maximum stripe size
22815         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22816                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22817         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22818                 error "Able to create DoM component size more than LOD limit"
22819
22820         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22821         dom_current=$(do_facet mds1 $LCTL get_param -n \
22822                                                 lod.$mdtname.dom_stripesize)
22823         [ 0 -eq ${dom_current} ] ||
22824                 error "Can't set zero DoM stripe limit"
22825         rm $dom
22826
22827         # attempt to create DoM file on server with disabled DoM should
22828         # remove DoM entry from layout and be succeed
22829         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22830                 error "Can't create DoM file (DoM is disabled)"
22831         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22832                 error "File has DoM component while DoM is disabled"
22833         rm $dom
22834
22835         # attempt to create DoM file with only DoM stripe should return error
22836         $LFS setstripe -E $dom_limit -L mdt $dom &&
22837                 error "Able to create DoM-only file while DoM is disabled"
22838
22839         # too low values to be aligned with smallest stripe size 64K
22840         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22841         dom_current=$(do_facet mds1 $LCTL get_param -n \
22842                                                 lod.$mdtname.dom_stripesize)
22843         [ 30000 -eq ${dom_current} ] &&
22844                 error "Can set too small DoM stripe limit"
22845
22846         # 64K is a minimal stripe size in Lustre, expect limit of that size
22847         [ 65536 -eq ${dom_current} ] ||
22848                 error "Limit is not set to 64K but ${dom_current}"
22849
22850         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22851         dom_current=$(do_facet mds1 $LCTL get_param -n \
22852                                                 lod.$mdtname.dom_stripesize)
22853         echo $dom_current
22854         [ 2147483648 -eq ${dom_current} ] &&
22855                 error "Can set too large DoM stripe limit"
22856
22857         do_facet mds1 $LCTL set_param -n \
22858                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22859         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22860                 error "Can't create DoM component size after limit change"
22861         do_facet mds1 $LCTL set_param -n \
22862                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22863         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22864                 error "Can't create DoM file after limit decrease"
22865         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22866                 error "Can create big DoM component after limit decrease"
22867         touch ${dom}_def ||
22868                 error "Can't create file with old default layout"
22869
22870         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22871         return 0
22872 }
22873 run_test 270f "DoM: maximum DoM stripe size checks"
22874
22875 test_270g() {
22876         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22877                 skip "Need MDS version at least 2.13.52"
22878         local dom=$DIR/$tdir/$tfile
22879
22880         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22881         local lodname=${FSNAME}-MDT0000-mdtlov
22882
22883         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22884         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22885         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22886         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22887
22888         local dom_limit=1024
22889         local dom_threshold="50%"
22890
22891         $LFS setstripe -d $DIR/$tdir
22892         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22893                 error "Can't set directory default striping"
22894
22895         do_facet mds1 $LCTL set_param -n \
22896                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22897         # set 0 threshold and create DOM file to change tunable stripesize
22898         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22899         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22900                 error "Failed to create $dom file"
22901         # now tunable dom_cur_stripesize should reach maximum
22902         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22903                                         lod.${lodname}.dom_stripesize_cur_kb)
22904         [[ $dom_current == $dom_limit ]] ||
22905                 error "Current DOM stripesize is not maximum"
22906         rm $dom
22907
22908         # set threshold for further tests
22909         do_facet mds1 $LCTL set_param -n \
22910                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22911         echo "DOM threshold is $dom_threshold free space"
22912         local dom_def
22913         local dom_set
22914         # Spoof bfree to exceed threshold
22915         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22916         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22917         for spfree in 40 20 0 15 30 55; do
22918                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22919                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22920                         error "Failed to create $dom file"
22921                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22922                                         lod.${lodname}.dom_stripesize_cur_kb)
22923                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22924                 [[ $dom_def != $dom_current ]] ||
22925                         error "Default stripe size was not changed"
22926                 if (( spfree > 0 )) ; then
22927                         dom_set=$($LFS getstripe -S $dom)
22928                         (( dom_set == dom_def * 1024 )) ||
22929                                 error "DOM component size is still old"
22930                 else
22931                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22932                                 error "DoM component is set with no free space"
22933                 fi
22934                 rm $dom
22935                 dom_current=$dom_def
22936         done
22937 }
22938 run_test 270g "DoM: default DoM stripe size depends on free space"
22939
22940 test_270h() {
22941         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22942                 skip "Need MDS version at least 2.13.53"
22943
22944         local mdtname=${FSNAME}-MDT0000-mdtlov
22945         local dom=$DIR/$tdir/$tfile
22946         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22947
22948         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22949         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22950
22951         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22952         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22953                 error "can't create OST file"
22954         # mirrored file with DOM entry in the second mirror
22955         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22956                 error "can't create mirror with DoM component"
22957
22958         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22959
22960         # DOM component in the middle and has other enries in the same mirror,
22961         # should succeed but lost DoM component
22962         $LFS setstripe --copy=${dom}_1 $dom ||
22963                 error "Can't create file from OST|DOM mirror layout"
22964         # check new file has no DoM layout after all
22965         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22966                 error "File has DoM component while DoM is disabled"
22967 }
22968 run_test 270h "DoM: DoM stripe removal when disabled on server"
22969
22970 test_270i() {
22971         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22972                 skip "Need MDS version at least 2.14.54"
22973
22974         mkdir $DIR/$tdir
22975         # DoM with plain layout
22976         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22977                 error "default plain layout with DoM must fail"
22978         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
22979                 error "setstripe plain file layout with DoM must fail"
22980         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
22981                 error "default DoM layout with bad striping must fail"
22982         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
22983                 error "setstripe to DoM layout with bad striping must fail"
22984         return 0
22985 }
22986 run_test 270i "DoM: setting invalid DoM striping should fail"
22987
22988 test_271a() {
22989         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22990                 skip "Need MDS version at least 2.10.55"
22991
22992         local dom=$DIR/$tdir/dom
22993
22994         mkdir -p $DIR/$tdir
22995
22996         $LFS setstripe -E 1024K -L mdt $dom
22997
22998         lctl set_param -n mdc.*.stats=clear
22999         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23000         cat $dom > /dev/null
23001         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23002         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23003         ls $dom
23004         rm -f $dom
23005 }
23006 run_test 271a "DoM: data is cached for read after write"
23007
23008 test_271b() {
23009         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23010                 skip "Need MDS version at least 2.10.55"
23011
23012         local dom=$DIR/$tdir/dom
23013
23014         mkdir -p $DIR/$tdir
23015
23016         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23017
23018         lctl set_param -n mdc.*.stats=clear
23019         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23020         cancel_lru_locks mdc
23021         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23022         # second stat to check size is cached on client
23023         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23024         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23025         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23026         rm -f $dom
23027 }
23028 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23029
23030 test_271ba() {
23031         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23032                 skip "Need MDS version at least 2.10.55"
23033
23034         local dom=$DIR/$tdir/dom
23035
23036         mkdir -p $DIR/$tdir
23037
23038         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23039
23040         lctl set_param -n mdc.*.stats=clear
23041         lctl set_param -n osc.*.stats=clear
23042         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23043         cancel_lru_locks mdc
23044         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23045         # second stat to check size is cached on client
23046         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23047         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23048         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23049         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23050         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23051         rm -f $dom
23052 }
23053 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23054
23055
23056 get_mdc_stats() {
23057         local mdtidx=$1
23058         local param=$2
23059         local mdt=MDT$(printf %04x $mdtidx)
23060
23061         if [ -z $param ]; then
23062                 lctl get_param -n mdc.*$mdt*.stats
23063         else
23064                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23065         fi
23066 }
23067
23068 test_271c() {
23069         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23070                 skip "Need MDS version at least 2.10.55"
23071
23072         local dom=$DIR/$tdir/dom
23073
23074         mkdir -p $DIR/$tdir
23075
23076         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23077
23078         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23079         local facet=mds$((mdtidx + 1))
23080
23081         cancel_lru_locks mdc
23082         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23083         createmany -o $dom 1000
23084         lctl set_param -n mdc.*.stats=clear
23085         smalliomany -w $dom 1000 200
23086         get_mdc_stats $mdtidx
23087         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23088         # Each file has 1 open, 1 IO enqueues, total 2000
23089         # but now we have also +1 getxattr for security.capability, total 3000
23090         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23091         unlinkmany $dom 1000
23092
23093         cancel_lru_locks mdc
23094         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23095         createmany -o $dom 1000
23096         lctl set_param -n mdc.*.stats=clear
23097         smalliomany -w $dom 1000 200
23098         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23099         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23100         # for OPEN and IO lock.
23101         [ $((enq - enq_2)) -ge 1000 ] ||
23102                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23103         unlinkmany $dom 1000
23104         return 0
23105 }
23106 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23107
23108 cleanup_271def_tests() {
23109         trap 0
23110         rm -f $1
23111 }
23112
23113 test_271d() {
23114         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23115                 skip "Need MDS version at least 2.10.57"
23116
23117         local dom=$DIR/$tdir/dom
23118         local tmp=$TMP/$tfile
23119         trap "cleanup_271def_tests $tmp" EXIT
23120
23121         mkdir -p $DIR/$tdir
23122
23123         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23124
23125         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23126
23127         cancel_lru_locks mdc
23128         dd if=/dev/urandom of=$tmp bs=1000 count=1
23129         dd if=$tmp of=$dom bs=1000 count=1
23130         cancel_lru_locks mdc
23131
23132         cat /etc/hosts >> $tmp
23133         lctl set_param -n mdc.*.stats=clear
23134
23135         # append data to the same file it should update local page
23136         echo "Append to the same page"
23137         cat /etc/hosts >> $dom
23138         local num=$(get_mdc_stats $mdtidx ost_read)
23139         local ra=$(get_mdc_stats $mdtidx req_active)
23140         local rw=$(get_mdc_stats $mdtidx req_waittime)
23141
23142         [ -z $num ] || error "$num READ RPC occured"
23143         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23144         echo "... DONE"
23145
23146         # compare content
23147         cmp $tmp $dom || error "file miscompare"
23148
23149         cancel_lru_locks mdc
23150         lctl set_param -n mdc.*.stats=clear
23151
23152         echo "Open and read file"
23153         cat $dom > /dev/null
23154         local num=$(get_mdc_stats $mdtidx ost_read)
23155         local ra=$(get_mdc_stats $mdtidx req_active)
23156         local rw=$(get_mdc_stats $mdtidx req_waittime)
23157
23158         [ -z $num ] || error "$num READ RPC occured"
23159         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23160         echo "... DONE"
23161
23162         # compare content
23163         cmp $tmp $dom || error "file miscompare"
23164
23165         return 0
23166 }
23167 run_test 271d "DoM: read on open (1K file in reply buffer)"
23168
23169 test_271f() {
23170         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23171                 skip "Need MDS version at least 2.10.57"
23172
23173         local dom=$DIR/$tdir/dom
23174         local tmp=$TMP/$tfile
23175         trap "cleanup_271def_tests $tmp" EXIT
23176
23177         mkdir -p $DIR/$tdir
23178
23179         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23180
23181         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23182
23183         cancel_lru_locks mdc
23184         dd if=/dev/urandom of=$tmp bs=265000 count=1
23185         dd if=$tmp of=$dom bs=265000 count=1
23186         cancel_lru_locks mdc
23187         cat /etc/hosts >> $tmp
23188         lctl set_param -n mdc.*.stats=clear
23189
23190         echo "Append to the same page"
23191         cat /etc/hosts >> $dom
23192         local num=$(get_mdc_stats $mdtidx ost_read)
23193         local ra=$(get_mdc_stats $mdtidx req_active)
23194         local rw=$(get_mdc_stats $mdtidx req_waittime)
23195
23196         [ -z $num ] || error "$num READ RPC occured"
23197         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23198         echo "... DONE"
23199
23200         # compare content
23201         cmp $tmp $dom || error "file miscompare"
23202
23203         cancel_lru_locks mdc
23204         lctl set_param -n mdc.*.stats=clear
23205
23206         echo "Open and read file"
23207         cat $dom > /dev/null
23208         local num=$(get_mdc_stats $mdtidx ost_read)
23209         local ra=$(get_mdc_stats $mdtidx req_active)
23210         local rw=$(get_mdc_stats $mdtidx req_waittime)
23211
23212         [ -z $num ] && num=0
23213         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23214         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23215         echo "... DONE"
23216
23217         # compare content
23218         cmp $tmp $dom || error "file miscompare"
23219
23220         return 0
23221 }
23222 run_test 271f "DoM: read on open (200K file and read tail)"
23223
23224 test_271g() {
23225         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23226                 skip "Skipping due to old client or server version"
23227
23228         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23229         # to get layout
23230         $CHECKSTAT -t file $DIR1/$tfile
23231
23232         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23233         MULTIOP_PID=$!
23234         sleep 1
23235         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23236         $LCTL set_param fail_loc=0x80000314
23237         rm $DIR1/$tfile || error "Unlink fails"
23238         RC=$?
23239         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23240         [ $RC -eq 0 ] || error "Failed write to stale object"
23241 }
23242 run_test 271g "Discard DoM data vs client flush race"
23243
23244 test_272a() {
23245         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23246                 skip "Need MDS version at least 2.11.50"
23247
23248         local dom=$DIR/$tdir/dom
23249         mkdir -p $DIR/$tdir
23250
23251         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23252         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23253                 error "failed to write data into $dom"
23254         local old_md5=$(md5sum $dom)
23255
23256         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23257                 error "failed to migrate to the same DoM component"
23258
23259         local new_md5=$(md5sum $dom)
23260
23261         [ "$old_md5" == "$new_md5" ] ||
23262                 error "md5sum differ: $old_md5, $new_md5"
23263
23264         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23265                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23266 }
23267 run_test 272a "DoM migration: new layout with the same DOM component"
23268
23269 test_272b() {
23270         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23271                 skip "Need MDS version at least 2.11.50"
23272
23273         local dom=$DIR/$tdir/dom
23274         mkdir -p $DIR/$tdir
23275         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23276
23277         local mdtidx=$($LFS getstripe -m $dom)
23278         local mdtname=MDT$(printf %04x $mdtidx)
23279         local facet=mds$((mdtidx + 1))
23280
23281         local mdtfree1=$(do_facet $facet \
23282                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23283         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23284                 error "failed to write data into $dom"
23285         local old_md5=$(md5sum $dom)
23286         cancel_lru_locks mdc
23287         local mdtfree1=$(do_facet $facet \
23288                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23289
23290         $LFS migrate -c2 $dom ||
23291                 error "failed to migrate to the new composite layout"
23292         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23293                 error "MDT stripe was not removed"
23294
23295         cancel_lru_locks mdc
23296         local new_md5=$(md5sum $dom)
23297         [ "$old_md5" == "$new_md5" ] ||
23298                 error "$old_md5 != $new_md5"
23299
23300         # Skip free space checks with ZFS
23301         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23302                 local mdtfree2=$(do_facet $facet \
23303                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23304                 [ $mdtfree2 -gt $mdtfree1 ] ||
23305                         error "MDT space is not freed after migration"
23306         fi
23307         return 0
23308 }
23309 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23310
23311 test_272c() {
23312         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23313                 skip "Need MDS version at least 2.11.50"
23314
23315         local dom=$DIR/$tdir/$tfile
23316         mkdir -p $DIR/$tdir
23317         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23318
23319         local mdtidx=$($LFS getstripe -m $dom)
23320         local mdtname=MDT$(printf %04x $mdtidx)
23321         local facet=mds$((mdtidx + 1))
23322
23323         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23324                 error "failed to write data into $dom"
23325         local old_md5=$(md5sum $dom)
23326         cancel_lru_locks mdc
23327         local mdtfree1=$(do_facet $facet \
23328                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23329
23330         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23331                 error "failed to migrate to the new composite layout"
23332         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23333                 error "MDT stripe was not removed"
23334
23335         cancel_lru_locks mdc
23336         local new_md5=$(md5sum $dom)
23337         [ "$old_md5" == "$new_md5" ] ||
23338                 error "$old_md5 != $new_md5"
23339
23340         # Skip free space checks with ZFS
23341         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23342                 local mdtfree2=$(do_facet $facet \
23343                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23344                 [ $mdtfree2 -gt $mdtfree1 ] ||
23345                         error "MDS space is not freed after migration"
23346         fi
23347         return 0
23348 }
23349 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23350
23351 test_272d() {
23352         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23353                 skip "Need MDS version at least 2.12.55"
23354
23355         local dom=$DIR/$tdir/$tfile
23356         mkdir -p $DIR/$tdir
23357         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23358
23359         local mdtidx=$($LFS getstripe -m $dom)
23360         local mdtname=MDT$(printf %04x $mdtidx)
23361         local facet=mds$((mdtidx + 1))
23362
23363         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23364                 error "failed to write data into $dom"
23365         local old_md5=$(md5sum $dom)
23366         cancel_lru_locks mdc
23367         local mdtfree1=$(do_facet $facet \
23368                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23369
23370         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23371                 error "failed mirroring to the new composite layout"
23372         $LFS mirror resync $dom ||
23373                 error "failed mirror resync"
23374         $LFS mirror split --mirror-id 1 -d $dom ||
23375                 error "failed mirror split"
23376
23377         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23378                 error "MDT stripe was not removed"
23379
23380         cancel_lru_locks mdc
23381         local new_md5=$(md5sum $dom)
23382         [ "$old_md5" == "$new_md5" ] ||
23383                 error "$old_md5 != $new_md5"
23384
23385         # Skip free space checks with ZFS
23386         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23387                 local mdtfree2=$(do_facet $facet \
23388                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23389                 [ $mdtfree2 -gt $mdtfree1 ] ||
23390                         error "MDS space is not freed after DOM mirror deletion"
23391         fi
23392         return 0
23393 }
23394 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23395
23396 test_272e() {
23397         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23398                 skip "Need MDS version at least 2.12.55"
23399
23400         local dom=$DIR/$tdir/$tfile
23401         mkdir -p $DIR/$tdir
23402         $LFS setstripe -c 2 $dom
23403
23404         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23405                 error "failed to write data into $dom"
23406         local old_md5=$(md5sum $dom)
23407         cancel_lru_locks
23408
23409         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23410                 error "failed mirroring to the DOM layout"
23411         $LFS mirror resync $dom ||
23412                 error "failed mirror resync"
23413         $LFS mirror split --mirror-id 1 -d $dom ||
23414                 error "failed mirror split"
23415
23416         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23417                 error "MDT stripe wasn't set"
23418
23419         cancel_lru_locks
23420         local new_md5=$(md5sum $dom)
23421         [ "$old_md5" == "$new_md5" ] ||
23422                 error "$old_md5 != $new_md5"
23423
23424         return 0
23425 }
23426 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23427
23428 test_272f() {
23429         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23430                 skip "Need MDS version at least 2.12.55"
23431
23432         local dom=$DIR/$tdir/$tfile
23433         mkdir -p $DIR/$tdir
23434         $LFS setstripe -c 2 $dom
23435
23436         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23437                 error "failed to write data into $dom"
23438         local old_md5=$(md5sum $dom)
23439         cancel_lru_locks
23440
23441         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23442                 error "failed migrating to the DOM file"
23443
23444         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23445                 error "MDT stripe wasn't set"
23446
23447         cancel_lru_locks
23448         local new_md5=$(md5sum $dom)
23449         [ "$old_md5" != "$new_md5" ] &&
23450                 error "$old_md5 != $new_md5"
23451
23452         return 0
23453 }
23454 run_test 272f "DoM migration: OST-striped file to DOM file"
23455
23456 test_273a() {
23457         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23458                 skip "Need MDS version at least 2.11.50"
23459
23460         # Layout swap cannot be done if either file has DOM component,
23461         # this will never be supported, migration should be used instead
23462
23463         local dom=$DIR/$tdir/$tfile
23464         mkdir -p $DIR/$tdir
23465
23466         $LFS setstripe -c2 ${dom}_plain
23467         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23468         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23469                 error "can swap layout with DoM component"
23470         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23471                 error "can swap layout with DoM component"
23472
23473         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23474         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23475                 error "can swap layout with DoM component"
23476         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23477                 error "can swap layout with DoM component"
23478         return 0
23479 }
23480 run_test 273a "DoM: layout swapping should fail with DOM"
23481
23482 test_273b() {
23483         mkdir -p $DIR/$tdir
23484         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23485
23486 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23487         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23488
23489         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23490 }
23491 run_test 273b "DoM: race writeback and object destroy"
23492
23493 test_275() {
23494         remote_ost_nodsh && skip "remote OST with nodsh"
23495         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23496                 skip "Need OST version >= 2.10.57"
23497
23498         local file=$DIR/$tfile
23499         local oss
23500
23501         oss=$(comma_list $(osts_nodes))
23502
23503         dd if=/dev/urandom of=$file bs=1M count=2 ||
23504                 error "failed to create a file"
23505         cancel_lru_locks osc
23506
23507         #lock 1
23508         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23509                 error "failed to read a file"
23510
23511 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23512         $LCTL set_param fail_loc=0x8000031f
23513
23514         cancel_lru_locks osc &
23515         sleep 1
23516
23517 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23518         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23519         #IO takes another lock, but matches the PENDING one
23520         #and places it to the IO RPC
23521         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23522                 error "failed to read a file with PENDING lock"
23523 }
23524 run_test 275 "Read on a canceled duplicate lock"
23525
23526 test_276() {
23527         remote_ost_nodsh && skip "remote OST with nodsh"
23528         local pid
23529
23530         do_facet ost1 "(while true; do \
23531                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23532                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23533         pid=$!
23534
23535         for LOOP in $(seq 20); do
23536                 stop ost1
23537                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23538         done
23539         kill -9 $pid
23540         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23541                 rm $TMP/sanity_276_pid"
23542 }
23543 run_test 276 "Race between mount and obd_statfs"
23544
23545 test_277() {
23546         $LCTL set_param ldlm.namespaces.*.lru_size=0
23547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23548         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23549                         grep ^used_mb | awk '{print $2}')
23550         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23551         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23552                 oflag=direct conv=notrunc
23553         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23554                         grep ^used_mb | awk '{print $2}')
23555         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23556 }
23557 run_test 277 "Direct IO shall drop page cache"
23558
23559 test_278() {
23560         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23562         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23563                 skip "needs the same host for mdt1 mdt2" && return
23564
23565         local pid1
23566         local pid2
23567
23568 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23569         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23570         stop mds2 &
23571         pid2=$!
23572
23573         stop mds1
23574
23575         echo "Starting MDTs"
23576         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23577         wait $pid2
23578 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23579 #will return NULL
23580         do_facet mds2 $LCTL set_param fail_loc=0
23581
23582         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23583         wait_recovery_complete mds2
23584 }
23585 run_test 278 "Race starting MDS between MDTs stop/start"
23586
23587 test_280() {
23588         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23589                 skip "Need MGS version at least 2.13.52"
23590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23591         combined_mgs_mds || skip "needs combined MGS/MDT"
23592
23593         umount_client $MOUNT
23594 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23595         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23596
23597         mount_client $MOUNT &
23598         sleep 1
23599         stop mgs || error "stop mgs failed"
23600         #for a race mgs would crash
23601         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23602         # make sure we unmount client before remounting
23603         wait
23604         umount_client $MOUNT
23605         mount_client $MOUNT || error "mount client failed"
23606 }
23607 run_test 280 "Race between MGS umount and client llog processing"
23608
23609 cleanup_test_300() {
23610         trap 0
23611         umask $SAVE_UMASK
23612 }
23613 test_striped_dir() {
23614         local mdt_index=$1
23615         local stripe_count
23616         local stripe_index
23617
23618         mkdir -p $DIR/$tdir
23619
23620         SAVE_UMASK=$(umask)
23621         trap cleanup_test_300 RETURN EXIT
23622
23623         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23624                                                 $DIR/$tdir/striped_dir ||
23625                 error "set striped dir error"
23626
23627         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23628         [ "$mode" = "755" ] || error "expect 755 got $mode"
23629
23630         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23631                 error "getdirstripe failed"
23632         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23633         if [ "$stripe_count" != "2" ]; then
23634                 error "1:stripe_count is $stripe_count, expect 2"
23635         fi
23636         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23637         if [ "$stripe_count" != "2" ]; then
23638                 error "2:stripe_count is $stripe_count, expect 2"
23639         fi
23640
23641         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23642         if [ "$stripe_index" != "$mdt_index" ]; then
23643                 error "stripe_index is $stripe_index, expect $mdt_index"
23644         fi
23645
23646         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23647                 error "nlink error after create striped dir"
23648
23649         mkdir $DIR/$tdir/striped_dir/a
23650         mkdir $DIR/$tdir/striped_dir/b
23651
23652         stat $DIR/$tdir/striped_dir/a ||
23653                 error "create dir under striped dir failed"
23654         stat $DIR/$tdir/striped_dir/b ||
23655                 error "create dir under striped dir failed"
23656
23657         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23658                 error "nlink error after mkdir"
23659
23660         rmdir $DIR/$tdir/striped_dir/a
23661         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23662                 error "nlink error after rmdir"
23663
23664         rmdir $DIR/$tdir/striped_dir/b
23665         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23666                 error "nlink error after rmdir"
23667
23668         chattr +i $DIR/$tdir/striped_dir
23669         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23670                 error "immutable flags not working under striped dir!"
23671         chattr -i $DIR/$tdir/striped_dir
23672
23673         rmdir $DIR/$tdir/striped_dir ||
23674                 error "rmdir striped dir error"
23675
23676         cleanup_test_300
23677
23678         true
23679 }
23680
23681 test_300a() {
23682         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23683                 skip "skipped for lustre < 2.7.0"
23684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23686
23687         test_striped_dir 0 || error "failed on striped dir on MDT0"
23688         test_striped_dir 1 || error "failed on striped dir on MDT0"
23689 }
23690 run_test 300a "basic striped dir sanity test"
23691
23692 test_300b() {
23693         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23694                 skip "skipped for lustre < 2.7.0"
23695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23697
23698         local i
23699         local mtime1
23700         local mtime2
23701         local mtime3
23702
23703         test_mkdir $DIR/$tdir || error "mkdir fail"
23704         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23705                 error "set striped dir error"
23706         for i in {0..9}; do
23707                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23708                 sleep 1
23709                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23710                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23711                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23712                 sleep 1
23713                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23714                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23715                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23716         done
23717         true
23718 }
23719 run_test 300b "check ctime/mtime for striped dir"
23720
23721 test_300c() {
23722         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23723                 skip "skipped for lustre < 2.7.0"
23724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23726
23727         local file_count
23728
23729         mkdir_on_mdt0 $DIR/$tdir
23730         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23731                 error "set striped dir error"
23732
23733         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23734                 error "chown striped dir failed"
23735
23736         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23737                 error "create 5k files failed"
23738
23739         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23740
23741         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23742
23743         rm -rf $DIR/$tdir
23744 }
23745 run_test 300c "chown && check ls under striped directory"
23746
23747 test_300d() {
23748         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23749                 skip "skipped for lustre < 2.7.0"
23750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23751         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23752
23753         local stripe_count
23754         local file
23755
23756         mkdir -p $DIR/$tdir
23757         $LFS setstripe -c 2 $DIR/$tdir
23758
23759         #local striped directory
23760         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23761                 error "set striped dir error"
23762         #look at the directories for debug purposes
23763         ls -l $DIR/$tdir
23764         $LFS getdirstripe $DIR/$tdir
23765         ls -l $DIR/$tdir/striped_dir
23766         $LFS getdirstripe $DIR/$tdir/striped_dir
23767         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23768                 error "create 10 files failed"
23769
23770         #remote striped directory
23771         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23772                 error "set striped dir error"
23773         #look at the directories for debug purposes
23774         ls -l $DIR/$tdir
23775         $LFS getdirstripe $DIR/$tdir
23776         ls -l $DIR/$tdir/remote_striped_dir
23777         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23778         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23779                 error "create 10 files failed"
23780
23781         for file in $(find $DIR/$tdir); do
23782                 stripe_count=$($LFS getstripe -c $file)
23783                 [ $stripe_count -eq 2 ] ||
23784                         error "wrong stripe $stripe_count for $file"
23785         done
23786
23787         rm -rf $DIR/$tdir
23788 }
23789 run_test 300d "check default stripe under striped directory"
23790
23791 test_300e() {
23792         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23793                 skip "Need MDS version at least 2.7.55"
23794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23796
23797         local stripe_count
23798         local file
23799
23800         mkdir -p $DIR/$tdir
23801
23802         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23803                 error "set striped dir error"
23804
23805         touch $DIR/$tdir/striped_dir/a
23806         touch $DIR/$tdir/striped_dir/b
23807         touch $DIR/$tdir/striped_dir/c
23808
23809         mkdir $DIR/$tdir/striped_dir/dir_a
23810         mkdir $DIR/$tdir/striped_dir/dir_b
23811         mkdir $DIR/$tdir/striped_dir/dir_c
23812
23813         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23814                 error "set striped adir under striped dir error"
23815
23816         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23817                 error "set striped bdir under striped dir error"
23818
23819         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23820                 error "set striped cdir under striped dir error"
23821
23822         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23823                 error "rename dir under striped dir fails"
23824
23825         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23826                 error "rename dir under different stripes fails"
23827
23828         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23829                 error "rename file under striped dir should succeed"
23830
23831         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23832                 error "rename dir under striped dir should succeed"
23833
23834         rm -rf $DIR/$tdir
23835 }
23836 run_test 300e "check rename under striped directory"
23837
23838 test_300f() {
23839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23841         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23842                 skip "Need MDS version at least 2.7.55"
23843
23844         local stripe_count
23845         local file
23846
23847         rm -rf $DIR/$tdir
23848         mkdir -p $DIR/$tdir
23849
23850         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23851                 error "set striped dir error"
23852
23853         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23854                 error "set striped dir error"
23855
23856         touch $DIR/$tdir/striped_dir/a
23857         mkdir $DIR/$tdir/striped_dir/dir_a
23858         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23859                 error "create striped dir under striped dir fails"
23860
23861         touch $DIR/$tdir/striped_dir1/b
23862         mkdir $DIR/$tdir/striped_dir1/dir_b
23863         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23864                 error "create striped dir under striped dir fails"
23865
23866         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23867                 error "rename dir under different striped dir should fail"
23868
23869         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23870                 error "rename striped dir under diff striped dir should fail"
23871
23872         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23873                 error "rename file under diff striped dirs fails"
23874
23875         rm -rf $DIR/$tdir
23876 }
23877 run_test 300f "check rename cross striped directory"
23878
23879 test_300_check_default_striped_dir()
23880 {
23881         local dirname=$1
23882         local default_count=$2
23883         local default_index=$3
23884         local stripe_count
23885         local stripe_index
23886         local dir_stripe_index
23887         local dir
23888
23889         echo "checking $dirname $default_count $default_index"
23890         $LFS setdirstripe -D -c $default_count -i $default_index \
23891                                 -H all_char $DIR/$tdir/$dirname ||
23892                 error "set default stripe on striped dir error"
23893         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23894         [ $stripe_count -eq $default_count ] ||
23895                 error "expect $default_count get $stripe_count for $dirname"
23896
23897         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23898         [ $stripe_index -eq $default_index ] ||
23899                 error "expect $default_index get $stripe_index for $dirname"
23900
23901         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23902                                                 error "create dirs failed"
23903
23904         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23905         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23906         for dir in $(find $DIR/$tdir/$dirname/*); do
23907                 stripe_count=$($LFS getdirstripe -c $dir)
23908                 (( $stripe_count == $default_count )) ||
23909                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23910                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23911                 error "stripe count $default_count != $stripe_count for $dir"
23912
23913                 stripe_index=$($LFS getdirstripe -i $dir)
23914                 [ $default_index -eq -1 ] ||
23915                         [ $stripe_index -eq $default_index ] ||
23916                         error "$stripe_index != $default_index for $dir"
23917
23918                 #check default stripe
23919                 stripe_count=$($LFS getdirstripe -D -c $dir)
23920                 [ $stripe_count -eq $default_count ] ||
23921                 error "default count $default_count != $stripe_count for $dir"
23922
23923                 stripe_index=$($LFS getdirstripe -D -i $dir)
23924                 [ $stripe_index -eq $default_index ] ||
23925                 error "default index $default_index != $stripe_index for $dir"
23926         done
23927         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23928 }
23929
23930 test_300g() {
23931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23932         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23933                 skip "Need MDS version at least 2.7.55"
23934
23935         local dir
23936         local stripe_count
23937         local stripe_index
23938
23939         mkdir_on_mdt0 $DIR/$tdir
23940         mkdir $DIR/$tdir/normal_dir
23941
23942         #Checking when client cache stripe index
23943         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23944         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23945                 error "create striped_dir failed"
23946
23947         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23948                 error "create dir0 fails"
23949         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23950         [ $stripe_index -eq 0 ] ||
23951                 error "dir0 expect index 0 got $stripe_index"
23952
23953         mkdir $DIR/$tdir/striped_dir/dir1 ||
23954                 error "create dir1 fails"
23955         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23956         [ $stripe_index -eq 1 ] ||
23957                 error "dir1 expect index 1 got $stripe_index"
23958
23959         #check default stripe count/stripe index
23960         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23961         test_300_check_default_striped_dir normal_dir 1 0
23962         test_300_check_default_striped_dir normal_dir -1 1
23963         test_300_check_default_striped_dir normal_dir 2 -1
23964
23965         #delete default stripe information
23966         echo "delete default stripeEA"
23967         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23968                 error "set default stripe on striped dir error"
23969
23970         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23971         for dir in $(find $DIR/$tdir/normal_dir/*); do
23972                 stripe_count=$($LFS getdirstripe -c $dir)
23973                 [ $stripe_count -eq 0 ] ||
23974                         error "expect 1 get $stripe_count for $dir"
23975         done
23976 }
23977 run_test 300g "check default striped directory for normal directory"
23978
23979 test_300h() {
23980         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23981         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23982                 skip "Need MDS version at least 2.7.55"
23983
23984         local dir
23985         local stripe_count
23986
23987         mkdir $DIR/$tdir
23988         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23989                 error "set striped dir error"
23990
23991         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23992         test_300_check_default_striped_dir striped_dir 1 0
23993         test_300_check_default_striped_dir striped_dir -1 1
23994         test_300_check_default_striped_dir striped_dir 2 -1
23995
23996         #delete default stripe information
23997         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23998                 error "set default stripe on striped dir error"
23999
24000         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24001         for dir in $(find $DIR/$tdir/striped_dir/*); do
24002                 stripe_count=$($LFS getdirstripe -c $dir)
24003                 [ $stripe_count -eq 0 ] ||
24004                         error "expect 1 get $stripe_count for $dir"
24005         done
24006 }
24007 run_test 300h "check default striped directory for striped directory"
24008
24009 test_300i() {
24010         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24011         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24012         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24013                 skip "Need MDS version at least 2.7.55"
24014
24015         local stripe_count
24016         local file
24017
24018         mkdir $DIR/$tdir
24019
24020         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24021                 error "set striped dir error"
24022
24023         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24024                 error "create files under striped dir failed"
24025
24026         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24027                 error "set striped hashdir error"
24028
24029         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24030                 error "create dir0 under hash dir failed"
24031         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24032                 error "create dir1 under hash dir failed"
24033         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24034                 error "create dir2 under hash dir failed"
24035
24036         # unfortunately, we need to umount to clear dir layout cache for now
24037         # once we fully implement dir layout, we can drop this
24038         umount_client $MOUNT || error "umount failed"
24039         mount_client $MOUNT || error "mount failed"
24040
24041         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24042         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24043         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24044
24045         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24046                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24047                         error "create crush2 dir $tdir/hashdir/d3 failed"
24048                 $LFS find -H crush2 $DIR/$tdir/hashdir
24049                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24050                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24051
24052                 # mkdir with an invalid hash type (hash=fail_val) from client
24053                 # should be replaced on MDS with a valid (default) hash type
24054                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24055                 $LCTL set_param fail_loc=0x1901 fail_val=99
24056                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24057
24058                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24059                 local expect=$(do_facet mds1 \
24060                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24061                 [[ $hash == $expect ]] ||
24062                         error "d99 hash '$hash' != expected hash '$expect'"
24063         fi
24064
24065         #set the stripe to be unknown hash type on read
24066         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24067         $LCTL set_param fail_loc=0x1901 fail_val=99
24068         for ((i = 0; i < 10; i++)); do
24069                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24070                         error "stat f-$i failed"
24071                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24072         done
24073
24074         touch $DIR/$tdir/striped_dir/f0 &&
24075                 error "create under striped dir with unknown hash should fail"
24076
24077         $LCTL set_param fail_loc=0
24078
24079         umount_client $MOUNT || error "umount failed"
24080         mount_client $MOUNT || error "mount failed"
24081
24082         return 0
24083 }
24084 run_test 300i "client handle unknown hash type striped directory"
24085
24086 test_300j() {
24087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24089         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24090                 skip "Need MDS version at least 2.7.55"
24091
24092         local stripe_count
24093         local file
24094
24095         mkdir $DIR/$tdir
24096
24097         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24098         $LCTL set_param fail_loc=0x1702
24099         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24100                 error "set striped dir error"
24101
24102         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24103                 error "create files under striped dir failed"
24104
24105         $LCTL set_param fail_loc=0
24106
24107         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24108
24109         return 0
24110 }
24111 run_test 300j "test large update record"
24112
24113 test_300k() {
24114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24116         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24117                 skip "Need MDS version at least 2.7.55"
24118
24119         # this test needs a huge transaction
24120         local kb
24121         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24122              osd*.$FSNAME-MDT0000.kbytestotal")
24123         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24124
24125         local stripe_count
24126         local file
24127
24128         mkdir $DIR/$tdir
24129
24130         #define OBD_FAIL_LARGE_STRIPE   0x1703
24131         $LCTL set_param fail_loc=0x1703
24132         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24133                 error "set striped dir error"
24134         $LCTL set_param fail_loc=0
24135
24136         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24137                 error "getstripeddir fails"
24138         rm -rf $DIR/$tdir/striped_dir ||
24139                 error "unlink striped dir fails"
24140
24141         return 0
24142 }
24143 run_test 300k "test large striped directory"
24144
24145 test_300l() {
24146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24148         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24149                 skip "Need MDS version at least 2.7.55"
24150
24151         local stripe_index
24152
24153         test_mkdir -p $DIR/$tdir/striped_dir
24154         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24155                         error "chown $RUNAS_ID failed"
24156         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24157                 error "set default striped dir failed"
24158
24159         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24160         $LCTL set_param fail_loc=0x80000158
24161         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24162
24163         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24164         [ $stripe_index -eq 1 ] ||
24165                 error "expect 1 get $stripe_index for $dir"
24166 }
24167 run_test 300l "non-root user to create dir under striped dir with stale layout"
24168
24169 test_300m() {
24170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24171         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24172         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24173                 skip "Need MDS version at least 2.7.55"
24174
24175         mkdir -p $DIR/$tdir/striped_dir
24176         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24177                 error "set default stripes dir error"
24178
24179         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24180
24181         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24182         [ $stripe_count -eq 0 ] ||
24183                         error "expect 0 get $stripe_count for a"
24184
24185         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24186                 error "set default stripes dir error"
24187
24188         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24189
24190         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24191         [ $stripe_count -eq 0 ] ||
24192                         error "expect 0 get $stripe_count for b"
24193
24194         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24195                 error "set default stripes dir error"
24196
24197         mkdir $DIR/$tdir/striped_dir/c &&
24198                 error "default stripe_index is invalid, mkdir c should fails"
24199
24200         rm -rf $DIR/$tdir || error "rmdir fails"
24201 }
24202 run_test 300m "setstriped directory on single MDT FS"
24203
24204 cleanup_300n() {
24205         local list=$(comma_list $(mdts_nodes))
24206
24207         trap 0
24208         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24209 }
24210
24211 test_300n() {
24212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24213         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24214         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24215                 skip "Need MDS version at least 2.7.55"
24216         remote_mds_nodsh && skip "remote MDS with nodsh"
24217
24218         local stripe_index
24219         local list=$(comma_list $(mdts_nodes))
24220
24221         trap cleanup_300n RETURN EXIT
24222         mkdir -p $DIR/$tdir
24223         chmod 777 $DIR/$tdir
24224         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24225                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24226                 error "create striped dir succeeds with gid=0"
24227
24228         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24229         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24230                 error "create striped dir fails with gid=-1"
24231
24232         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24233         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24234                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24235                 error "set default striped dir succeeds with gid=0"
24236
24237
24238         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24239         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24240                 error "set default striped dir fails with gid=-1"
24241
24242
24243         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24244         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24245                                         error "create test_dir fails"
24246         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24247                                         error "create test_dir1 fails"
24248         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24249                                         error "create test_dir2 fails"
24250         cleanup_300n
24251 }
24252 run_test 300n "non-root user to create dir under striped dir with default EA"
24253
24254 test_300o() {
24255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24258                 skip "Need MDS version at least 2.7.55"
24259
24260         local numfree1
24261         local numfree2
24262
24263         mkdir -p $DIR/$tdir
24264
24265         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24266         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24267         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24268                 skip "not enough free inodes $numfree1 $numfree2"
24269         fi
24270
24271         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24272         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24273         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24274                 skip "not enough free space $numfree1 $numfree2"
24275         fi
24276
24277         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24278                 error "setdirstripe fails"
24279
24280         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24281                 error "create dirs fails"
24282
24283         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24284         ls $DIR/$tdir/striped_dir > /dev/null ||
24285                 error "ls striped dir fails"
24286         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24287                 error "unlink big striped dir fails"
24288 }
24289 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24290
24291 test_300p() {
24292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24294         remote_mds_nodsh && skip "remote MDS with nodsh"
24295
24296         mkdir_on_mdt0 $DIR/$tdir
24297
24298         #define OBD_FAIL_OUT_ENOSPC     0x1704
24299         do_facet mds2 lctl set_param fail_loc=0x80001704
24300         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24301                  && error "create striped directory should fail"
24302
24303         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24304
24305         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24306         true
24307 }
24308 run_test 300p "create striped directory without space"
24309
24310 test_300q() {
24311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24313
24314         local fd=$(free_fd)
24315         local cmd="exec $fd<$tdir"
24316         cd $DIR
24317         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24318         eval $cmd
24319         cmd="exec $fd<&-"
24320         trap "eval $cmd" EXIT
24321         cd $tdir || error "cd $tdir fails"
24322         rmdir  ../$tdir || error "rmdir $tdir fails"
24323         mkdir local_dir && error "create dir succeeds"
24324         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24325         eval $cmd
24326         return 0
24327 }
24328 run_test 300q "create remote directory under orphan directory"
24329
24330 test_300r() {
24331         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24332                 skip "Need MDS version at least 2.7.55" && return
24333         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24334
24335         mkdir $DIR/$tdir
24336
24337         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24338                 error "set striped dir error"
24339
24340         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24341                 error "getstripeddir fails"
24342
24343         local stripe_count
24344         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24345                       awk '/lmv_stripe_count:/ { print $2 }')
24346
24347         [ $MDSCOUNT -ne $stripe_count ] &&
24348                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24349
24350         rm -rf $DIR/$tdir/striped_dir ||
24351                 error "unlink striped dir fails"
24352 }
24353 run_test 300r "test -1 striped directory"
24354
24355 test_300s_helper() {
24356         local count=$1
24357
24358         local stripe_dir=$DIR/$tdir/striped_dir.$count
24359
24360         $LFS mkdir -c $count $stripe_dir ||
24361                 error "lfs mkdir -c error"
24362
24363         $LFS getdirstripe $stripe_dir ||
24364                 error "lfs getdirstripe fails"
24365
24366         local stripe_count
24367         stripe_count=$($LFS getdirstripe $stripe_dir |
24368                       awk '/lmv_stripe_count:/ { print $2 }')
24369
24370         [ $count -ne $stripe_count ] &&
24371                 error_noexit "bad stripe count $stripe_count expected $count"
24372
24373         local dupe_stripes
24374         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24375                 awk '/0x/ {count[$1] += 1}; END {
24376                         for (idx in count) {
24377                                 if (count[idx]>1) {
24378                                         print "index " idx " count " count[idx]
24379                                 }
24380                         }
24381                 }')
24382
24383         if [[ -n "$dupe_stripes" ]] ; then
24384                 lfs getdirstripe $stripe_dir
24385                 error_noexit "Dupe MDT above: $dupe_stripes "
24386         fi
24387
24388         rm -rf $stripe_dir ||
24389                 error_noexit "unlink $stripe_dir fails"
24390 }
24391
24392 test_300s() {
24393         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24394                 skip "Need MDS version at least 2.7.55" && return
24395         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24396
24397         mkdir $DIR/$tdir
24398         for count in $(seq 2 $MDSCOUNT); do
24399                 test_300s_helper $count
24400         done
24401 }
24402 run_test 300s "test lfs mkdir -c without -i"
24403
24404 test_300t() {
24405         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24406                 skip "need MDS 2.14.55 or later"
24407         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24408
24409         local testdir="$DIR/$tdir/striped_dir"
24410         local dir1=$testdir/dir1
24411         local dir2=$testdir/dir2
24412
24413         mkdir -p $testdir
24414
24415         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24416                 error "failed to set default stripe count for $testdir"
24417
24418         mkdir $dir1
24419         local stripe_count=$($LFS getdirstripe -c $dir1)
24420
24421         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24422
24423         local max_count=$((MDSCOUNT - 1))
24424         local mdts=$(comma_list $(mdts_nodes))
24425
24426         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24427         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24428
24429         mkdir $dir2
24430         stripe_count=$($LFS getdirstripe -c $dir2)
24431
24432         (( $stripe_count == $max_count )) || error "wrong stripe count"
24433 }
24434 run_test 300t "test max_mdt_stripecount"
24435
24436 prepare_remote_file() {
24437         mkdir $DIR/$tdir/src_dir ||
24438                 error "create remote source failed"
24439
24440         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24441                  error "cp to remote source failed"
24442         touch $DIR/$tdir/src_dir/a
24443
24444         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24445                 error "create remote target dir failed"
24446
24447         touch $DIR/$tdir/tgt_dir/b
24448
24449         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24450                 error "rename dir cross MDT failed!"
24451
24452         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24453                 error "src_child still exists after rename"
24454
24455         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24456                 error "missing file(a) after rename"
24457
24458         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24459                 error "diff after rename"
24460 }
24461
24462 test_310a() {
24463         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24465
24466         local remote_file=$DIR/$tdir/tgt_dir/b
24467
24468         mkdir -p $DIR/$tdir
24469
24470         prepare_remote_file || error "prepare remote file failed"
24471
24472         #open-unlink file
24473         $OPENUNLINK $remote_file $remote_file ||
24474                 error "openunlink $remote_file failed"
24475         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24476 }
24477 run_test 310a "open unlink remote file"
24478
24479 test_310b() {
24480         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24482
24483         local remote_file=$DIR/$tdir/tgt_dir/b
24484
24485         mkdir -p $DIR/$tdir
24486
24487         prepare_remote_file || error "prepare remote file failed"
24488
24489         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24490         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24491         $CHECKSTAT -t file $remote_file || error "check file failed"
24492 }
24493 run_test 310b "unlink remote file with multiple links while open"
24494
24495 test_310c() {
24496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24497         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24498
24499         local remote_file=$DIR/$tdir/tgt_dir/b
24500
24501         mkdir -p $DIR/$tdir
24502
24503         prepare_remote_file || error "prepare remote file failed"
24504
24505         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24506         multiop_bg_pause $remote_file O_uc ||
24507                         error "mulitop failed for remote file"
24508         MULTIPID=$!
24509         $MULTIOP $DIR/$tfile Ouc
24510         kill -USR1 $MULTIPID
24511         wait $MULTIPID
24512 }
24513 run_test 310c "open-unlink remote file with multiple links"
24514
24515 #LU-4825
24516 test_311() {
24517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24518         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24519         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24520                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24521         remote_mds_nodsh && skip "remote MDS with nodsh"
24522
24523         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24524         local mdts=$(comma_list $(mdts_nodes))
24525
24526         mkdir -p $DIR/$tdir
24527         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24528         createmany -o $DIR/$tdir/$tfile. 1000
24529
24530         # statfs data is not real time, let's just calculate it
24531         old_iused=$((old_iused + 1000))
24532
24533         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24534                         osp.*OST0000*MDT0000.create_count")
24535         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24536                                 osp.*OST0000*MDT0000.max_create_count")
24537         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24538
24539         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24540         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24541         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24542
24543         unlinkmany $DIR/$tdir/$tfile. 1000
24544
24545         do_nodes $mdts "$LCTL set_param -n \
24546                         osp.*OST0000*.max_create_count=$max_count"
24547         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24548                 do_nodes $mdts "$LCTL set_param -n \
24549                                 osp.*OST0000*.create_count=$count"
24550         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24551                         grep "=0" && error "create_count is zero"
24552
24553         local new_iused
24554         for i in $(seq 120); do
24555                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24556                 # system may be too busy to destroy all objs in time, use
24557                 # a somewhat small value to not fail autotest
24558                 [ $((old_iused - new_iused)) -gt 400 ] && break
24559                 sleep 1
24560         done
24561
24562         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24563         [ $((old_iused - new_iused)) -gt 400 ] ||
24564                 error "objs not destroyed after unlink"
24565 }
24566 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24567
24568 zfs_oid_to_objid()
24569 {
24570         local ost=$1
24571         local objid=$2
24572
24573         local vdevdir=$(dirname $(facet_vdevice $ost))
24574         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24575         local zfs_zapid=$(do_facet $ost $cmd |
24576                           grep -w "/O/0/d$((objid%32))" -C 5 |
24577                           awk '/Object/{getline; print $1}')
24578         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24579                           awk "/$objid = /"'{printf $3}')
24580
24581         echo $zfs_objid
24582 }
24583
24584 zfs_object_blksz() {
24585         local ost=$1
24586         local objid=$2
24587
24588         local vdevdir=$(dirname $(facet_vdevice $ost))
24589         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24590         local blksz=$(do_facet $ost $cmd $objid |
24591                       awk '/dblk/{getline; printf $4}')
24592
24593         case "${blksz: -1}" in
24594                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24595                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24596                 *) ;;
24597         esac
24598
24599         echo $blksz
24600 }
24601
24602 test_312() { # LU-4856
24603         remote_ost_nodsh && skip "remote OST with nodsh"
24604         [ "$ost1_FSTYPE" = "zfs" ] ||
24605                 skip_env "the test only applies to zfs"
24606
24607         local max_blksz=$(do_facet ost1 \
24608                           $ZFS get -p recordsize $(facet_device ost1) |
24609                           awk '!/VALUE/{print $3}')
24610
24611         # to make life a little bit easier
24612         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24613         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24614
24615         local tf=$DIR/$tdir/$tfile
24616         touch $tf
24617         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24618
24619         # Get ZFS object id
24620         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24621         # block size change by sequential overwrite
24622         local bs
24623
24624         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24625                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24626
24627                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24628                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24629         done
24630         rm -f $tf
24631
24632         # block size change by sequential append write
24633         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24634         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24635         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24636         local count
24637
24638         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24639                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24640                         oflag=sync conv=notrunc
24641
24642                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24643                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24644                         error "blksz error, actual $blksz, " \
24645                                 "expected: 2 * $count * $PAGE_SIZE"
24646         done
24647         rm -f $tf
24648
24649         # random write
24650         touch $tf
24651         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24652         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24653
24654         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24655         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24656         [ $blksz -eq $PAGE_SIZE ] ||
24657                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24658
24659         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24660         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24661         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24662
24663         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24664         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24665         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24666 }
24667 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24668
24669 test_313() {
24670         remote_ost_nodsh && skip "remote OST with nodsh"
24671
24672         local file=$DIR/$tfile
24673
24674         rm -f $file
24675         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24676
24677         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24678         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24679         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24680                 error "write should failed"
24681         do_facet ost1 "$LCTL set_param fail_loc=0"
24682         rm -f $file
24683 }
24684 run_test 313 "io should fail after last_rcvd update fail"
24685
24686 test_314() {
24687         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24688
24689         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24690         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24691         rm -f $DIR/$tfile
24692         wait_delete_completed
24693         do_facet ost1 "$LCTL set_param fail_loc=0"
24694 }
24695 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24696
24697 test_315() { # LU-618
24698         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24699
24700         local file=$DIR/$tfile
24701         rm -f $file
24702
24703         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24704                 error "multiop file write failed"
24705         $MULTIOP $file oO_RDONLY:r4063232_c &
24706         PID=$!
24707
24708         sleep 2
24709
24710         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24711         kill -USR1 $PID
24712
24713         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24714         rm -f $file
24715 }
24716 run_test 315 "read should be accounted"
24717
24718 test_316() {
24719         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24720         large_xattr_enabled || skip "ea_inode feature disabled"
24721
24722         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24723         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24724         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24725         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24726
24727         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24728 }
24729 run_test 316 "lfs migrate of file with large_xattr enabled"
24730
24731 test_317() {
24732         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24733                 skip "Need MDS version at least 2.11.53"
24734         if [ "$ost1_FSTYPE" == "zfs" ]; then
24735                 skip "LU-10370: no implementation for ZFS"
24736         fi
24737
24738         local trunc_sz
24739         local grant_blk_size
24740
24741         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24742                         awk '/grant_block_size:/ { print $2; exit; }')
24743         #
24744         # Create File of size 5M. Truncate it to below size's and verify
24745         # blocks count.
24746         #
24747         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24748                 error "Create file $DIR/$tfile failed"
24749         stack_trap "rm -f $DIR/$tfile" EXIT
24750
24751         for trunc_sz in 2097152 4097 4000 509 0; do
24752                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24753                         error "truncate $tfile to $trunc_sz failed"
24754                 local sz=$(stat --format=%s $DIR/$tfile)
24755                 local blk=$(stat --format=%b $DIR/$tfile)
24756                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24757                                      grant_blk_size) * 8))
24758
24759                 if [[ $blk -ne $trunc_blk ]]; then
24760                         $(which stat) $DIR/$tfile
24761                         error "Expected Block $trunc_blk got $blk for $tfile"
24762                 fi
24763
24764                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24765                         error "Expected Size $trunc_sz got $sz for $tfile"
24766         done
24767
24768         #
24769         # sparse file test
24770         # Create file with a hole and write actual 65536 bytes which aligned
24771         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24772         #
24773         local bs=65536
24774         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24775                 error "Create file : $DIR/$tfile"
24776
24777         #
24778         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24779         # blocks. The block count must drop to 8.
24780         #
24781         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24782                 ((bs - grant_blk_size) + 1)))
24783         $TRUNCATE $DIR/$tfile $trunc_sz ||
24784                 error "truncate $tfile to $trunc_sz failed"
24785
24786         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24787         sz=$(stat --format=%s $DIR/$tfile)
24788         blk=$(stat --format=%b $DIR/$tfile)
24789
24790         if [[ $blk -ne $trunc_bsz ]]; then
24791                 $(which stat) $DIR/$tfile
24792                 error "Expected Block $trunc_bsz got $blk for $tfile"
24793         fi
24794
24795         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24796                 error "Expected Size $trunc_sz got $sz for $tfile"
24797 }
24798 run_test 317 "Verify blocks get correctly update after truncate"
24799
24800 test_318() {
24801         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24802         local old_max_active=$($LCTL get_param -n \
24803                             ${llite_name}.max_read_ahead_async_active \
24804                             2>/dev/null)
24805
24806         $LCTL set_param llite.*.max_read_ahead_async_active=256
24807         local max_active=$($LCTL get_param -n \
24808                            ${llite_name}.max_read_ahead_async_active \
24809                            2>/dev/null)
24810         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24811
24812         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24813                 error "set max_read_ahead_async_active should succeed"
24814
24815         $LCTL set_param llite.*.max_read_ahead_async_active=512
24816         max_active=$($LCTL get_param -n \
24817                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24818         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24819
24820         # restore @max_active
24821         [ $old_max_active -ne 0 ] && $LCTL set_param \
24822                 llite.*.max_read_ahead_async_active=$old_max_active
24823
24824         local old_threshold=$($LCTL get_param -n \
24825                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24826         local max_per_file_mb=$($LCTL get_param -n \
24827                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24828
24829         local invalid=$(($max_per_file_mb + 1))
24830         $LCTL set_param \
24831                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24832                         && error "set $invalid should fail"
24833
24834         local valid=$(($invalid - 1))
24835         $LCTL set_param \
24836                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24837                         error "set $valid should succeed"
24838         local threshold=$($LCTL get_param -n \
24839                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24840         [ $threshold -eq $valid ] || error \
24841                 "expect threshold $valid got $threshold"
24842         $LCTL set_param \
24843                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24844 }
24845 run_test 318 "Verify async readahead tunables"
24846
24847 test_319() {
24848         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24849
24850         local before=$(date +%s)
24851         local evict
24852         local mdir=$DIR/$tdir
24853         local file=$mdir/xxx
24854
24855         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24856         touch $file
24857
24858 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24859         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24860         $LFS migrate -m1 $mdir &
24861
24862         sleep 1
24863         dd if=$file of=/dev/null
24864         wait
24865         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24866           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24867
24868         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24869 }
24870 run_test 319 "lost lease lock on migrate error"
24871
24872 test_398a() { # LU-4198
24873         local ost1_imp=$(get_osc_import_name client ost1)
24874         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24875                          cut -d'.' -f2)
24876
24877         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24878         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24879
24880         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24881         # request a new lock on client
24882         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24883
24884         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24885         #local lock_count=$($LCTL get_param -n \
24886         #                  ldlm.namespaces.$imp_name.lru_size)
24887         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24888
24889         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24890
24891         # no lock cached, should use lockless DIO and not enqueue new lock
24892         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24893                 conv=notrunc ||
24894                 error "dio write failed"
24895         lock_count=$($LCTL get_param -n \
24896                      ldlm.namespaces.$imp_name.lru_size)
24897         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24898
24899         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24900
24901         # no lock cached, should use locked DIO append
24902         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24903                 conv=notrunc || error "DIO append failed"
24904         lock_count=$($LCTL get_param -n \
24905                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24906         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24907 }
24908 run_test 398a "direct IO should cancel lock otherwise lockless"
24909
24910 test_398b() { # LU-4198
24911         which fio || skip_env "no fio installed"
24912         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24913
24914         local size=48
24915         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24916
24917         local njobs=4
24918         # Single page, multiple pages, stripe size, 4*stripe size
24919         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24920                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24921                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24922                         --numjobs=$njobs --fallocate=none \
24923                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24924                         --filename=$DIR/$tfile &
24925                 bg_pid=$!
24926
24927                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24928                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24929                         --numjobs=$njobs --fallocate=none \
24930                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24931                         --filename=$DIR/$tfile || true
24932                 wait $bg_pid
24933         done
24934
24935         evict=$(do_facet client $LCTL get_param \
24936                 osc.$FSNAME-OST*-osc-*/state |
24937             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24938
24939         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24940                 (do_facet client $LCTL get_param \
24941                         osc.$FSNAME-OST*-osc-*/state;
24942                     error "eviction happened: $evict before:$before")
24943
24944         rm -f $DIR/$tfile
24945 }
24946 run_test 398b "DIO and buffer IO race"
24947
24948 test_398c() { # LU-4198
24949         local ost1_imp=$(get_osc_import_name client ost1)
24950         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24951                          cut -d'.' -f2)
24952
24953         which fio || skip_env "no fio installed"
24954
24955         saved_debug=$($LCTL get_param -n debug)
24956         $LCTL set_param debug=0
24957
24958         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24959         ((size /= 1024)) # by megabytes
24960         ((size /= 2)) # write half of the OST at most
24961         [ $size -gt 40 ] && size=40 #reduce test time anyway
24962
24963         $LFS setstripe -c 1 $DIR/$tfile
24964
24965         # it seems like ldiskfs reserves more space than necessary if the
24966         # writing blocks are not mapped, so it extends the file firstly
24967         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24968         cancel_lru_locks osc
24969
24970         # clear and verify rpc_stats later
24971         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24972
24973         local njobs=4
24974         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24975         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24976                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24977                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24978                 --filename=$DIR/$tfile
24979         [ $? -eq 0 ] || error "fio write error"
24980
24981         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24982                 error "Locks were requested while doing AIO"
24983
24984         # get the percentage of 1-page I/O
24985         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24986                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24987                 awk '{print $7}')
24988         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24989
24990         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24991         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24992                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24993                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24994                 --filename=$DIR/$tfile
24995         [ $? -eq 0 ] || error "fio mixed read write error"
24996
24997         echo "AIO with large block size ${size}M"
24998         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24999                 --numjobs=1 --fallocate=none --ioengine=libaio \
25000                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25001                 --filename=$DIR/$tfile
25002         [ $? -eq 0 ] || error "fio large block size failed"
25003
25004         rm -f $DIR/$tfile
25005         $LCTL set_param debug="$saved_debug"
25006 }
25007 run_test 398c "run fio to test AIO"
25008
25009 test_398d() { #  LU-13846
25010         which aiocp || skip_env "no aiocp installed"
25011         local aio_file=$DIR/$tfile.aio
25012
25013         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25014
25015         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25016         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25017         stack_trap "rm -f $DIR/$tfile $aio_file"
25018
25019         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25020
25021         # make sure we don't crash and fail properly
25022         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25023                 error "aio not aligned with PAGE SIZE should fail"
25024
25025         rm -f $DIR/$tfile $aio_file
25026 }
25027 run_test 398d "run aiocp to verify block size > stripe size"
25028
25029 test_398e() {
25030         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25031         touch $DIR/$tfile.new
25032         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25033 }
25034 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25035
25036 test_398f() { #  LU-14687
25037         which aiocp || skip_env "no aiocp installed"
25038         local aio_file=$DIR/$tfile.aio
25039
25040         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25041
25042         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25043         stack_trap "rm -f $DIR/$tfile $aio_file"
25044
25045         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25046         $LCTL set_param fail_loc=0x1418
25047         # make sure we don't crash and fail properly
25048         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25049                 error "aio with page allocation failure succeeded"
25050         $LCTL set_param fail_loc=0
25051         diff $DIR/$tfile $aio_file
25052         [[ $? != 0 ]] || error "no diff after failed aiocp"
25053 }
25054 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25055
25056 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25057 # stripe and i/o size must be > stripe size
25058 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25059 # single RPC in flight.  This test shows async DIO submission is working by
25060 # showing multiple RPCs in flight.
25061 test_398g() { #  LU-13798
25062         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25063
25064         # We need to do some i/o first to acquire enough grant to put our RPCs
25065         # in flight; otherwise a new connection may not have enough grant
25066         # available
25067         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25068                 error "parallel dio failed"
25069         stack_trap "rm -f $DIR/$tfile"
25070
25071         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25072         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25073         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25074         stack_trap "$LCTL set_param -n $pages_per_rpc"
25075
25076         # Recreate file so it's empty
25077         rm -f $DIR/$tfile
25078         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25079         #Pause rpc completion to guarantee we see multiple rpcs in flight
25080         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25081         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25082         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25083
25084         # Clear rpc stats
25085         $LCTL set_param osc.*.rpc_stats=c
25086
25087         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25088                 error "parallel dio failed"
25089         stack_trap "rm -f $DIR/$tfile"
25090
25091         $LCTL get_param osc.*-OST0000-*.rpc_stats
25092         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25093                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25094                 grep "8:" | awk '{print $8}')
25095         # We look at the "8 rpcs in flight" field, and verify A) it is present
25096         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25097         # as expected for an 8M DIO to a file with 1M stripes.
25098         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25099
25100         # Verify turning off parallel dio works as expected
25101         # Clear rpc stats
25102         $LCTL set_param osc.*.rpc_stats=c
25103         $LCTL set_param llite.*.parallel_dio=0
25104         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25105
25106         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25107                 error "dio with parallel dio disabled failed"
25108
25109         # Ideally, we would see only one RPC in flight here, but there is an
25110         # unavoidable race between i/o completion and RPC in flight counting,
25111         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25112         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25113         # So instead we just verify it's always < 8.
25114         $LCTL get_param osc.*-OST0000-*.rpc_stats
25115         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25116                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25117                 grep '^$' -B1 | grep . | awk '{print $1}')
25118         [ $ret != "8:" ] ||
25119                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25120 }
25121 run_test 398g "verify parallel dio async RPC submission"
25122
25123 test_398h() { #  LU-13798
25124         local dio_file=$DIR/$tfile.dio
25125
25126         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25127
25128         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25129         stack_trap "rm -f $DIR/$tfile $dio_file"
25130
25131         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25132                 error "parallel dio failed"
25133         diff $DIR/$tfile $dio_file
25134         [[ $? == 0 ]] || error "file diff after aiocp"
25135 }
25136 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25137
25138 test_398i() { #  LU-13798
25139         local dio_file=$DIR/$tfile.dio
25140
25141         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25142
25143         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25144         stack_trap "rm -f $DIR/$tfile $dio_file"
25145
25146         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25147         $LCTL set_param fail_loc=0x1418
25148         # make sure we don't crash and fail properly
25149         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25150                 error "parallel dio page allocation failure succeeded"
25151         diff $DIR/$tfile $dio_file
25152         [[ $? != 0 ]] || error "no diff after failed aiocp"
25153 }
25154 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25155
25156 test_398j() { #  LU-13798
25157         # Stripe size > RPC size but less than i/o size tests split across
25158         # stripes and RPCs for individual i/o op
25159         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25160
25161         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25162         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25163         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25164         stack_trap "$LCTL set_param -n $pages_per_rpc"
25165
25166         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25167                 error "parallel dio write failed"
25168         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25169
25170         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25171                 error "parallel dio read failed"
25172         diff $DIR/$tfile $DIR/$tfile.2
25173         [[ $? == 0 ]] || error "file diff after parallel dio read"
25174 }
25175 run_test 398j "test parallel dio where stripe size > rpc_size"
25176
25177 test_398k() { #  LU-13798
25178         wait_delete_completed
25179         wait_mds_ost_sync
25180
25181         # 4 stripe file; we will cause out of space on OST0
25182         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25183
25184         # Fill OST0 (if it's not too large)
25185         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25186                    head -n1)
25187         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25188                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25189         fi
25190         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25191         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25192                 error "dd should fill OST0"
25193         stack_trap "rm -f $DIR/$tfile.1"
25194
25195         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25196         err=$?
25197
25198         ls -la $DIR/$tfile
25199         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25200                 error "file is not 0 bytes in size"
25201
25202         # dd above should not succeed, but don't error until here so we can
25203         # get debug info above
25204         [[ $err != 0 ]] ||
25205                 error "parallel dio write with enospc succeeded"
25206         stack_trap "rm -f $DIR/$tfile"
25207 }
25208 run_test 398k "test enospc on first stripe"
25209
25210 test_398l() { #  LU-13798
25211         wait_delete_completed
25212         wait_mds_ost_sync
25213
25214         # 4 stripe file; we will cause out of space on OST0
25215         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25216         # happens on the second i/o chunk we issue
25217         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25218
25219         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25220         stack_trap "rm -f $DIR/$tfile"
25221
25222         # Fill OST0 (if it's not too large)
25223         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25224                    head -n1)
25225         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25226                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25227         fi
25228         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25229         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25230                 error "dd should fill OST0"
25231         stack_trap "rm -f $DIR/$tfile.1"
25232
25233         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25234         err=$?
25235         stack_trap "rm -f $DIR/$tfile.2"
25236
25237         # Check that short write completed as expected
25238         ls -la $DIR/$tfile.2
25239         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25240                 error "file is not 1M in size"
25241
25242         # dd above should not succeed, but don't error until here so we can
25243         # get debug info above
25244         [[ $err != 0 ]] ||
25245                 error "parallel dio write with enospc succeeded"
25246
25247         # Truncate source file to same length as output file and diff them
25248         $TRUNCATE $DIR/$tfile 1048576
25249         diff $DIR/$tfile $DIR/$tfile.2
25250         [[ $? == 0 ]] || error "data incorrect after short write"
25251 }
25252 run_test 398l "test enospc on intermediate stripe/RPC"
25253
25254 test_398m() { #  LU-13798
25255         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25256
25257         # Set up failure on OST0, the first stripe:
25258         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25259         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25260         # So this fail_val specifies OST0
25261         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25262         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25263
25264         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25265                 error "parallel dio write with failure on first stripe succeeded"
25266         stack_trap "rm -f $DIR/$tfile"
25267         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25268
25269         # Place data in file for read
25270         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25271                 error "parallel dio write failed"
25272
25273         # Fail read on OST0, first stripe
25274         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25275         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25276         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25277                 error "parallel dio read with error on first stripe succeeded"
25278         rm -f $DIR/$tfile.2
25279         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25280
25281         # Switch to testing on OST1, second stripe
25282         # Clear file contents, maintain striping
25283         echo > $DIR/$tfile
25284         # Set up failure on OST1, second stripe:
25285         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
25286         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25287
25288         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25289                 error "parallel dio write with failure on first stripe succeeded"
25290         stack_trap "rm -f $DIR/$tfile"
25291         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25292
25293         # Place data in file for read
25294         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25295                 error "parallel dio write failed"
25296
25297         # Fail read on OST1, second stripe
25298         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25299         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25300         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25301                 error "parallel dio read with error on first stripe succeeded"
25302         rm -f $DIR/$tfile.2
25303         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25304 }
25305 run_test 398m "test RPC failures with parallel dio"
25306
25307 # Parallel submission of DIO should not cause problems for append, but it's
25308 # important to verify.
25309 test_398n() { #  LU-13798
25310         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25311
25312         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25313                 error "dd to create source file failed"
25314         stack_trap "rm -f $DIR/$tfile"
25315
25316         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25317                 error "parallel dio write with failure on second stripe succeeded"
25318         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25319         diff $DIR/$tfile $DIR/$tfile.1
25320         [[ $? == 0 ]] || error "data incorrect after append"
25321
25322 }
25323 run_test 398n "test append with parallel DIO"
25324
25325 test_398o() {
25326         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25327 }
25328 run_test 398o "right kms with DIO"
25329
25330 test_fake_rw() {
25331         local read_write=$1
25332         if [ "$read_write" = "write" ]; then
25333                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25334         elif [ "$read_write" = "read" ]; then
25335                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25336         else
25337                 error "argument error"
25338         fi
25339
25340         # turn off debug for performance testing
25341         local saved_debug=$($LCTL get_param -n debug)
25342         $LCTL set_param debug=0
25343
25344         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25345
25346         # get ost1 size - $FSNAME-OST0000
25347         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25348         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25349         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25350
25351         if [ "$read_write" = "read" ]; then
25352                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25353         fi
25354
25355         local start_time=$(date +%s.%N)
25356         $dd_cmd bs=1M count=$blocks oflag=sync ||
25357                 error "real dd $read_write error"
25358         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25359
25360         if [ "$read_write" = "write" ]; then
25361                 rm -f $DIR/$tfile
25362         fi
25363
25364         # define OBD_FAIL_OST_FAKE_RW           0x238
25365         do_facet ost1 $LCTL set_param fail_loc=0x238
25366
25367         local start_time=$(date +%s.%N)
25368         $dd_cmd bs=1M count=$blocks oflag=sync ||
25369                 error "fake dd $read_write error"
25370         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25371
25372         if [ "$read_write" = "write" ]; then
25373                 # verify file size
25374                 cancel_lru_locks osc
25375                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25376                         error "$tfile size not $blocks MB"
25377         fi
25378         do_facet ost1 $LCTL set_param fail_loc=0
25379
25380         echo "fake $read_write $duration_fake vs. normal $read_write" \
25381                 "$duration in seconds"
25382         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25383                 error_not_in_vm "fake write is slower"
25384
25385         $LCTL set_param -n debug="$saved_debug"
25386         rm -f $DIR/$tfile
25387 }
25388 test_399a() { # LU-7655 for OST fake write
25389         remote_ost_nodsh && skip "remote OST with nodsh"
25390
25391         test_fake_rw write
25392 }
25393 run_test 399a "fake write should not be slower than normal write"
25394
25395 test_399b() { # LU-8726 for OST fake read
25396         remote_ost_nodsh && skip "remote OST with nodsh"
25397         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25398                 skip_env "ldiskfs only test"
25399         fi
25400
25401         test_fake_rw read
25402 }
25403 run_test 399b "fake read should not be slower than normal read"
25404
25405 test_400a() { # LU-1606, was conf-sanity test_74
25406         if ! which $CC > /dev/null 2>&1; then
25407                 skip_env "$CC is not installed"
25408         fi
25409
25410         local extra_flags=''
25411         local out=$TMP/$tfile
25412         local prefix=/usr/include/lustre
25413         local prog
25414
25415         # Oleg removes c files in his test rig so test if any c files exist
25416         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25417                 skip_env "Needed c test files are missing"
25418
25419         if ! [[ -d $prefix ]]; then
25420                 # Assume we're running in tree and fixup the include path.
25421                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25422                 extra_flags+=" -L$LUSTRE/utils/.lib"
25423         fi
25424
25425         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25426                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25427                         error "client api broken"
25428         done
25429         rm -f $out
25430 }
25431 run_test 400a "Lustre client api program can compile and link"
25432
25433 test_400b() { # LU-1606, LU-5011
25434         local header
25435         local out=$TMP/$tfile
25436         local prefix=/usr/include/linux/lustre
25437
25438         # We use a hard coded prefix so that this test will not fail
25439         # when run in tree. There are headers in lustre/include/lustre/
25440         # that are not packaged (like lustre_idl.h) and have more
25441         # complicated include dependencies (like config.h and lnet/types.h).
25442         # Since this test about correct packaging we just skip them when
25443         # they don't exist (see below) rather than try to fixup cppflags.
25444
25445         if ! which $CC > /dev/null 2>&1; then
25446                 skip_env "$CC is not installed"
25447         fi
25448
25449         for header in $prefix/*.h; do
25450                 if ! [[ -f "$header" ]]; then
25451                         continue
25452                 fi
25453
25454                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25455                         continue # lustre_ioctl.h is internal header
25456                 fi
25457
25458                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25459                         error "cannot compile '$header'"
25460         done
25461         rm -f $out
25462 }
25463 run_test 400b "packaged headers can be compiled"
25464
25465 test_401a() { #LU-7437
25466         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25467         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25468
25469         #count the number of parameters by "list_param -R"
25470         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25471         #count the number of parameters by listing proc files
25472         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25473         echo "proc_dirs='$proc_dirs'"
25474         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25475         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25476                       sort -u | wc -l)
25477
25478         [ $params -eq $procs ] ||
25479                 error "found $params parameters vs. $procs proc files"
25480
25481         # test the list_param -D option only returns directories
25482         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25483         #count the number of parameters by listing proc directories
25484         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25485                 sort -u | wc -l)
25486
25487         [ $params -eq $procs ] ||
25488                 error "found $params parameters vs. $procs proc files"
25489 }
25490 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25491
25492 test_401b() {
25493         # jobid_var may not allow arbitrary values, so use jobid_name
25494         # if available
25495         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25496                 local testname=jobid_name tmp='testing%p'
25497         else
25498                 local testname=jobid_var tmp=testing
25499         fi
25500
25501         local save=$($LCTL get_param -n $testname)
25502
25503         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25504                 error "no error returned when setting bad parameters"
25505
25506         local jobid_new=$($LCTL get_param -n foe $testname baz)
25507         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25508
25509         $LCTL set_param -n fog=bam $testname=$save bat=fog
25510         local jobid_old=$($LCTL get_param -n foe $testname bag)
25511         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25512 }
25513 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25514
25515 test_401c() {
25516         # jobid_var may not allow arbitrary values, so use jobid_name
25517         # if available
25518         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25519                 local testname=jobid_name
25520         else
25521                 local testname=jobid_var
25522         fi
25523
25524         local jobid_var_old=$($LCTL get_param -n $testname)
25525         local jobid_var_new
25526
25527         $LCTL set_param $testname= &&
25528                 error "no error returned for 'set_param a='"
25529
25530         jobid_var_new=$($LCTL get_param -n $testname)
25531         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25532                 error "$testname was changed by setting without value"
25533
25534         $LCTL set_param $testname &&
25535                 error "no error returned for 'set_param a'"
25536
25537         jobid_var_new=$($LCTL get_param -n $testname)
25538         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25539                 error "$testname was changed by setting without value"
25540 }
25541 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25542
25543 test_401d() {
25544         # jobid_var may not allow arbitrary values, so use jobid_name
25545         # if available
25546         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25547                 local testname=jobid_name new_value='foo=bar%p'
25548         else
25549                 local testname=jobid_var new_valuie=foo=bar
25550         fi
25551
25552         local jobid_var_old=$($LCTL get_param -n $testname)
25553         local jobid_var_new
25554
25555         $LCTL set_param $testname=$new_value ||
25556                 error "'set_param a=b' did not accept a value containing '='"
25557
25558         jobid_var_new=$($LCTL get_param -n $testname)
25559         [[ "$jobid_var_new" == "$new_value" ]] ||
25560                 error "'set_param a=b' failed on a value containing '='"
25561
25562         # Reset the $testname to test the other format
25563         $LCTL set_param $testname=$jobid_var_old
25564         jobid_var_new=$($LCTL get_param -n $testname)
25565         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25566                 error "failed to reset $testname"
25567
25568         $LCTL set_param $testname $new_value ||
25569                 error "'set_param a b' did not accept a value containing '='"
25570
25571         jobid_var_new=$($LCTL get_param -n $testname)
25572         [[ "$jobid_var_new" == "$new_value" ]] ||
25573                 error "'set_param a b' failed on a value containing '='"
25574
25575         $LCTL set_param $testname $jobid_var_old
25576         jobid_var_new=$($LCTL get_param -n $testname)
25577         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25578                 error "failed to reset $testname"
25579 }
25580 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25581
25582 test_401e() { # LU-14779
25583         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25584                 error "lctl list_param MGC* failed"
25585         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25586         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25587                 error "lctl get_param lru_size failed"
25588 }
25589 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25590
25591 test_402() {
25592         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25593         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25594                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25595         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25596                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25597                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25598         remote_mds_nodsh && skip "remote MDS with nodsh"
25599
25600         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25601 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25602         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25603         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25604                 echo "Touch failed - OK"
25605 }
25606 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25607
25608 test_403() {
25609         local file1=$DIR/$tfile.1
25610         local file2=$DIR/$tfile.2
25611         local tfile=$TMP/$tfile
25612
25613         rm -f $file1 $file2 $tfile
25614
25615         touch $file1
25616         ln $file1 $file2
25617
25618         # 30 sec OBD_TIMEOUT in ll_getattr()
25619         # right before populating st_nlink
25620         $LCTL set_param fail_loc=0x80001409
25621         stat -c %h $file1 > $tfile &
25622
25623         # create an alias, drop all locks and reclaim the dentry
25624         < $file2
25625         cancel_lru_locks mdc
25626         cancel_lru_locks osc
25627         sysctl -w vm.drop_caches=2
25628
25629         wait
25630
25631         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25632
25633         rm -f $tfile $file1 $file2
25634 }
25635 run_test 403 "i_nlink should not drop to zero due to aliasing"
25636
25637 test_404() { # LU-6601
25638         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25639                 skip "Need server version newer than 2.8.52"
25640         remote_mds_nodsh && skip "remote MDS with nodsh"
25641
25642         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25643                 awk '/osp .*-osc-MDT/ { print $4}')
25644
25645         local osp
25646         for osp in $mosps; do
25647                 echo "Deactivate: " $osp
25648                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25649                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25650                         awk -vp=$osp '$4 == p { print $2 }')
25651                 [ $stat = IN ] || {
25652                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25653                         error "deactivate error"
25654                 }
25655                 echo "Activate: " $osp
25656                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25657                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25658                         awk -vp=$osp '$4 == p { print $2 }')
25659                 [ $stat = UP ] || {
25660                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25661                         error "activate error"
25662                 }
25663         done
25664 }
25665 run_test 404 "validate manual {de}activated works properly for OSPs"
25666
25667 test_405() {
25668         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25669         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25670                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25671                         skip "Layout swap lock is not supported"
25672
25673         check_swap_layouts_support
25674         check_swap_layout_no_dom $DIR
25675
25676         test_mkdir $DIR/$tdir
25677         swap_lock_test -d $DIR/$tdir ||
25678                 error "One layout swap locked test failed"
25679 }
25680 run_test 405 "Various layout swap lock tests"
25681
25682 test_406() {
25683         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25684         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25685         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25687         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25688                 skip "Need MDS version at least 2.8.50"
25689
25690         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25691         local test_pool=$TESTNAME
25692
25693         pool_add $test_pool || error "pool_add failed"
25694         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25695                 error "pool_add_targets failed"
25696
25697         save_layout_restore_at_exit $MOUNT
25698
25699         # parent set default stripe count only, child will stripe from both
25700         # parent and fs default
25701         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25702                 error "setstripe $MOUNT failed"
25703         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25704         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25705         for i in $(seq 10); do
25706                 local f=$DIR/$tdir/$tfile.$i
25707                 touch $f || error "touch failed"
25708                 local count=$($LFS getstripe -c $f)
25709                 [ $count -eq $OSTCOUNT ] ||
25710                         error "$f stripe count $count != $OSTCOUNT"
25711                 local offset=$($LFS getstripe -i $f)
25712                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25713                 local size=$($LFS getstripe -S $f)
25714                 [ $size -eq $((def_stripe_size * 2)) ] ||
25715                         error "$f stripe size $size != $((def_stripe_size * 2))"
25716                 local pool=$($LFS getstripe -p $f)
25717                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25718         done
25719
25720         # change fs default striping, delete parent default striping, now child
25721         # will stripe from new fs default striping only
25722         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25723                 error "change $MOUNT default stripe failed"
25724         $LFS setstripe -c 0 $DIR/$tdir ||
25725                 error "delete $tdir default stripe failed"
25726         for i in $(seq 11 20); do
25727                 local f=$DIR/$tdir/$tfile.$i
25728                 touch $f || error "touch $f failed"
25729                 local count=$($LFS getstripe -c $f)
25730                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25731                 local offset=$($LFS getstripe -i $f)
25732                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25733                 local size=$($LFS getstripe -S $f)
25734                 [ $size -eq $def_stripe_size ] ||
25735                         error "$f stripe size $size != $def_stripe_size"
25736                 local pool=$($LFS getstripe -p $f)
25737                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25738         done
25739
25740         unlinkmany $DIR/$tdir/$tfile. 1 20
25741
25742         local f=$DIR/$tdir/$tfile
25743         pool_remove_all_targets $test_pool $f
25744         pool_remove $test_pool $f
25745 }
25746 run_test 406 "DNE support fs default striping"
25747
25748 test_407() {
25749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25750         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25751                 skip "Need MDS version at least 2.8.55"
25752         remote_mds_nodsh && skip "remote MDS with nodsh"
25753
25754         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25755                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25756         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25757                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25758         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25759
25760         #define OBD_FAIL_DT_TXN_STOP    0x2019
25761         for idx in $(seq $MDSCOUNT); do
25762                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25763         done
25764         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25765         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25766                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25767         true
25768 }
25769 run_test 407 "transaction fail should cause operation fail"
25770
25771 test_408() {
25772         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25773
25774         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25775         lctl set_param fail_loc=0x8000040a
25776         # let ll_prepare_partial_page() fail
25777         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25778
25779         rm -f $DIR/$tfile
25780
25781         # create at least 100 unused inodes so that
25782         # shrink_icache_memory(0) should not return 0
25783         touch $DIR/$tfile-{0..100}
25784         rm -f $DIR/$tfile-{0..100}
25785         sync
25786
25787         echo 2 > /proc/sys/vm/drop_caches
25788 }
25789 run_test 408 "drop_caches should not hang due to page leaks"
25790
25791 test_409()
25792 {
25793         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25794
25795         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25796         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25797         touch $DIR/$tdir/guard || error "(2) Fail to create"
25798
25799         local PREFIX=$(str_repeat 'A' 128)
25800         echo "Create 1K hard links start at $(date)"
25801         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25802                 error "(3) Fail to hard link"
25803
25804         echo "Links count should be right although linkEA overflow"
25805         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25806         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25807         [ $linkcount -eq 1001 ] ||
25808                 error "(5) Unexpected hard links count: $linkcount"
25809
25810         echo "List all links start at $(date)"
25811         ls -l $DIR/$tdir/foo > /dev/null ||
25812                 error "(6) Fail to list $DIR/$tdir/foo"
25813
25814         echo "Unlink hard links start at $(date)"
25815         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25816                 error "(7) Fail to unlink"
25817         echo "Unlink hard links finished at $(date)"
25818 }
25819 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25820
25821 test_410()
25822 {
25823         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25824                 skip "Need client version at least 2.9.59"
25825         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25826                 skip "Need MODULES build"
25827
25828         # Create a file, and stat it from the kernel
25829         local testfile=$DIR/$tfile
25830         touch $testfile
25831
25832         local run_id=$RANDOM
25833         local my_ino=$(stat --format "%i" $testfile)
25834
25835         # Try to insert the module. This will always fail as the
25836         # module is designed to not be inserted.
25837         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25838             &> /dev/null
25839
25840         # Anything but success is a test failure
25841         dmesg | grep -q \
25842             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25843             error "no inode match"
25844 }
25845 run_test 410 "Test inode number returned from kernel thread"
25846
25847 cleanup_test411_cgroup() {
25848         trap 0
25849         rmdir "$1"
25850 }
25851
25852 test_411() {
25853         local cg_basedir=/sys/fs/cgroup/memory
25854         # LU-9966
25855         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25856                 skip "no setup for cgroup"
25857
25858         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25859                 error "test file creation failed"
25860         cancel_lru_locks osc
25861
25862         # Create a very small memory cgroup to force a slab allocation error
25863         local cgdir=$cg_basedir/osc_slab_alloc
25864         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25865         trap "cleanup_test411_cgroup $cgdir" EXIT
25866         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25867         echo 1M > $cgdir/memory.limit_in_bytes
25868
25869         # Should not LBUG, just be killed by oom-killer
25870         # dd will return 0 even allocation failure in some environment.
25871         # So don't check return value
25872         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25873         cleanup_test411_cgroup $cgdir
25874
25875         return 0
25876 }
25877 run_test 411 "Slab allocation error with cgroup does not LBUG"
25878
25879 test_412() {
25880         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25881         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25882                 skip "Need server version at least 2.10.55"
25883
25884         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25885                 error "mkdir failed"
25886         $LFS getdirstripe $DIR/$tdir
25887         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25888         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25889                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25890         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25891         [ $stripe_count -eq 2 ] ||
25892                 error "expect 2 get $stripe_count"
25893
25894         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25895
25896         local index
25897         local index2
25898
25899         # subdirs should be on the same MDT as parent
25900         for i in $(seq 0 $((MDSCOUNT - 1))); do
25901                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25902                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25903                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25904                 (( index == i )) || error "mdt$i/sub on MDT$index"
25905         done
25906
25907         # stripe offset -1, ditto
25908         for i in {1..10}; do
25909                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25910                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25911                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25912                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25913                 (( index == index2 )) ||
25914                         error "qos$i on MDT$index, sub on MDT$index2"
25915         done
25916
25917         local testdir=$DIR/$tdir/inherit
25918
25919         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25920         # inherit 2 levels
25921         for i in 1 2; do
25922                 testdir=$testdir/s$i
25923                 mkdir $testdir || error "mkdir $testdir failed"
25924                 index=$($LFS getstripe -m $testdir)
25925                 (( index == 1 )) ||
25926                         error "$testdir on MDT$index"
25927         done
25928
25929         # not inherit any more
25930         testdir=$testdir/s3
25931         mkdir $testdir || error "mkdir $testdir failed"
25932         getfattr -d -m dmv $testdir | grep dmv &&
25933                 error "default LMV set on $testdir" || true
25934 }
25935 run_test 412 "mkdir on specific MDTs"
25936
25937 TEST413_COUNT=${TEST413_COUNT:-200}
25938 generate_uneven_mdts() {
25939         local threshold=$1
25940         local lmv_qos_maxage
25941         local lod_qos_maxage
25942         local ffree
25943         local bavail
25944         local max
25945         local min
25946         local max_index
25947         local min_index
25948         local tmp
25949         local i
25950
25951         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25952         $LCTL set_param lmv.*.qos_maxage=1
25953         stack_trap "$LCTL set_param \
25954                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25955         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25956                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25957         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25958                 lod.*.mdt_qos_maxage=1
25959         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25960                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25961
25962         echo
25963         echo "Check for uneven MDTs: "
25964
25965         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25966         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25967         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25968
25969         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25970         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25971         max_index=0
25972         min_index=0
25973         for ((i = 1; i < ${#ffree[@]}; i++)); do
25974                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25975                 if [ $tmp -gt $max ]; then
25976                         max=$tmp
25977                         max_index=$i
25978                 fi
25979                 if [ $tmp -lt $min ]; then
25980                         min=$tmp
25981                         min_index=$i
25982                 fi
25983         done
25984
25985         (( ${ffree[min_index]} > 0 )) ||
25986                 skip "no free files in MDT$min_index"
25987         (( ${ffree[min_index]} < 10000000 )) ||
25988                 skip "too many free files in MDT$min_index"
25989
25990         # Check if we need to generate uneven MDTs
25991         local diff=$(((max - min) * 100 / min))
25992         local testdir=$DIR/$tdir-fillmdt
25993         local start
25994
25995         i=0
25996         while (( diff < threshold )); do
25997                 mkdir -p $testdir
25998                 # generate uneven MDTs, create till $threshold% diff
25999                 echo -n "weight diff=$diff% must be > $threshold% ..."
26000                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26001                 testdir=$DIR/$tdir-fillmdt/$i
26002                 [ -d $testdir ] && continue
26003                 $LFS mkdir -i $min_index $testdir ||
26004                         error "mkdir $testdir failed"
26005                 $LFS setstripe -E 1M -L mdt $testdir ||
26006                         error "setstripe $testdir failed"
26007                 start=$SECONDS
26008                 for ((F=0; F < TEST413_COUNT; F++)); do
26009                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26010                                 /dev/null 2>&1 || error "dd $F failed"
26011                 done
26012                 sync; sleep 1; sync
26013
26014                 # wait for QOS to update
26015                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26016
26017                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26018                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26019                 max=$(((${ffree[max_index]} >> 8) *
26020                         (${bavail[max_index]} * bsize >> 16)))
26021                 min=$(((${ffree[min_index]} >> 8) *
26022                         (${bavail[min_index]} * bsize >> 16)))
26023                 diff=$(((max - min) * 100 / min))
26024                 i=$((i + 1))
26025         done
26026
26027         echo "MDT filesfree available: ${ffree[*]}"
26028         echo "MDT blocks available: ${bavail[*]}"
26029         echo "weight diff=$diff%"
26030 }
26031
26032 test_qos_mkdir() {
26033         local mkdir_cmd=$1
26034         local stripe_count=$2
26035         local mdts=$(comma_list $(mdts_nodes))
26036
26037         local testdir
26038         local lmv_qos_prio_free
26039         local lmv_qos_threshold_rr
26040         local lmv_qos_maxage
26041         local lod_qos_prio_free
26042         local lod_qos_threshold_rr
26043         local lod_qos_maxage
26044         local count
26045         local i
26046
26047         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26048         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26049         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26050                 head -n1)
26051         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26052         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26053         stack_trap "$LCTL set_param \
26054                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26055         stack_trap "$LCTL set_param \
26056                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26057         stack_trap "$LCTL set_param \
26058                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26059
26060         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26061                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26062         lod_qos_prio_free=${lod_qos_prio_free%%%}
26063         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26064                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26065         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26066         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26067                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26068         stack_trap "do_nodes $mdts $LCTL set_param \
26069                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26070         stack_trap "do_nodes $mdts $LCTL set_param \
26071                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26072         stack_trap "do_nodes $mdts $LCTL set_param \
26073                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26074
26075         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26076         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26077
26078         testdir=$DIR/$tdir-s$stripe_count/rr
26079
26080         local stripe_index=$($LFS getstripe -m $testdir)
26081         local test_mkdir_rr=true
26082
26083         getfattr -d -m dmv -e hex $testdir | grep dmv
26084         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26085                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26086                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26087                         test_mkdir_rr=false
26088         fi
26089
26090         echo
26091         $test_mkdir_rr &&
26092                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26093                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26094
26095         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26096         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26097                 eval $mkdir_cmd $testdir/subdir$i ||
26098                         error "$mkdir_cmd subdir$i failed"
26099         done
26100
26101         for (( i = 0; i < $MDSCOUNT; i++ )); do
26102                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26103                 echo "$count directories created on MDT$i"
26104                 if $test_mkdir_rr; then
26105                         (( $count == 100 )) ||
26106                                 error "subdirs are not evenly distributed"
26107                 elif (( $i == $stripe_index )); then
26108                         (( $count == 100 * MDSCOUNT )) ||
26109                                 error "$count subdirs created on MDT$i"
26110                 else
26111                         (( $count == 0 )) ||
26112                                 error "$count subdirs created on MDT$i"
26113                 fi
26114
26115                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26116                         count=$($LFS getdirstripe $testdir/* |
26117                                 grep -c -P "^\s+$i\t")
26118                         echo "$count stripes created on MDT$i"
26119                         # deviation should < 5% of average
26120                         (( $count >= 95 * stripe_count &&
26121                            $count <= 105 * stripe_count)) ||
26122                                 error "stripes are not evenly distributed"
26123                 fi
26124         done
26125
26126         echo
26127         echo "Check for uneven MDTs: "
26128
26129         local ffree
26130         local bavail
26131         local max
26132         local min
26133         local max_index
26134         local min_index
26135         local tmp
26136
26137         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26138         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26139         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26140
26141         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26142         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26143         max_index=0
26144         min_index=0
26145         for ((i = 1; i < ${#ffree[@]}; i++)); do
26146                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26147                 if [ $tmp -gt $max ]; then
26148                         max=$tmp
26149                         max_index=$i
26150                 fi
26151                 if [ $tmp -lt $min ]; then
26152                         min=$tmp
26153                         min_index=$i
26154                 fi
26155         done
26156
26157         (( ${ffree[min_index]} > 0 )) ||
26158                 skip "no free files in MDT$min_index"
26159         (( ${ffree[min_index]} < 10000000 )) ||
26160                 skip "too many free files in MDT$min_index"
26161
26162         echo "MDT filesfree available: ${ffree[*]}"
26163         echo "MDT blocks available: ${bavail[*]}"
26164         echo "weight diff=$(((max - min) * 100 / min))%"
26165         echo
26166         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26167
26168         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26169         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26170         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26171         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26172         # decrease statfs age, so that it can be updated in time
26173         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26174         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26175
26176         sleep 1
26177
26178         testdir=$DIR/$tdir-s$stripe_count/qos
26179         local num=200
26180
26181         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26182         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26183                 eval $mkdir_cmd $testdir/subdir$i ||
26184                         error "$mkdir_cmd subdir$i failed"
26185         done
26186
26187         max=0
26188         for (( i = 0; i < $MDSCOUNT; i++ )); do
26189                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26190                 (( count > max )) && max=$count
26191                 echo "$count directories created on MDT$i"
26192         done
26193
26194         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26195
26196         # D-value should > 10% of averge
26197         (( max - min > num / 10 )) ||
26198                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26199
26200         # ditto for stripes
26201         if (( stripe_count > 1 )); then
26202                 max=0
26203                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26204                         count=$($LFS getdirstripe $testdir/* |
26205                                 grep -c -P "^\s+$i\t")
26206                         (( count > max )) && max=$count
26207                         echo "$count stripes created on MDT$i"
26208                 done
26209
26210                 min=$($LFS getdirstripe $testdir/* |
26211                         grep -c -P "^\s+$min_index\t")
26212                 (( max - min > num * stripe_count / 10 )) ||
26213                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26214         fi
26215 }
26216
26217 most_full_mdt() {
26218         local ffree
26219         local bavail
26220         local bsize
26221         local min
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         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26230         min_index=0
26231         for ((i = 1; i < ${#ffree[@]}; i++)); do
26232                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26233                 (( tmp < min )) && min=$tmp && min_index=$i
26234         done
26235
26236         echo -n $min_index
26237 }
26238
26239 test_413a() {
26240         [ $MDSCOUNT -lt 2 ] &&
26241                 skip "We need at least 2 MDTs for this test"
26242
26243         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26244                 skip "Need server version at least 2.12.52"
26245
26246         local stripe_count
26247
26248         generate_uneven_mdts 100
26249         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26250                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26251                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26252                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26253                         error "mkdir failed"
26254                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26255         done
26256 }
26257 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26258
26259 test_413b() {
26260         [ $MDSCOUNT -lt 2 ] &&
26261                 skip "We need at least 2 MDTs for this test"
26262
26263         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26264                 skip "Need server version at least 2.12.52"
26265
26266         local testdir
26267         local stripe_count
26268
26269         generate_uneven_mdts 100
26270         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26271                 testdir=$DIR/$tdir-s$stripe_count
26272                 mkdir $testdir || error "mkdir $testdir failed"
26273                 mkdir $testdir/rr || error "mkdir rr failed"
26274                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26275                         error "mkdir qos failed"
26276                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26277                         $testdir/rr || error "setdirstripe rr failed"
26278                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26279                         error "setdirstripe failed"
26280                 test_qos_mkdir "mkdir" $stripe_count
26281         done
26282 }
26283 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26284
26285 test_413c() {
26286         (( $MDSCOUNT >= 2 )) ||
26287                 skip "We need at least 2 MDTs for this test"
26288
26289         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26290                 skip "Need server version at least 2.14.51"
26291
26292         local testdir
26293         local inherit
26294         local inherit_rr
26295
26296         testdir=$DIR/${tdir}-s1
26297         mkdir $testdir || error "mkdir $testdir failed"
26298         mkdir $testdir/rr || error "mkdir rr failed"
26299         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26300         # default max_inherit is -1, default max_inherit_rr is 0
26301         $LFS setdirstripe -D -c 1 $testdir/rr ||
26302                 error "setdirstripe rr failed"
26303         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26304                 error "setdirstripe qos failed"
26305         test_qos_mkdir "mkdir" 1
26306
26307         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26308         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26309         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26310         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26311         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26312
26313         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26314         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26315         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26316         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26317         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26318         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26319         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26320                 error "level2 shouldn't have default LMV" || true
26321 }
26322 run_test 413c "mkdir with default LMV max inherit rr"
26323
26324 test_413d() {
26325         (( MDSCOUNT >= 2 )) ||
26326                 skip "We need at least 2 MDTs for this test"
26327
26328         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26329                 skip "Need server version at least 2.14.51"
26330
26331         local lmv_qos_threshold_rr
26332
26333         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26334                 head -n1)
26335         stack_trap "$LCTL set_param \
26336                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26337
26338         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26339         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26340         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26341                 error "$tdir shouldn't have default LMV"
26342         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26343                 error "mkdir sub failed"
26344
26345         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26346
26347         (( count == 100 )) || error "$count subdirs on MDT0"
26348 }
26349 run_test 413d "inherit ROOT default LMV"
26350
26351 test_413e() {
26352         (( MDSCOUNT >= 2 )) ||
26353                 skip "We need at least 2 MDTs for this test"
26354         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26355                 skip "Need server version at least 2.14.55"
26356
26357         local testdir=$DIR/$tdir
26358         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26359         local max_inherit
26360         local sub_max_inherit
26361
26362         mkdir -p $testdir || error "failed to create $testdir"
26363
26364         # set default max-inherit to -1 if stripe count is 0 or 1
26365         $LFS setdirstripe -D -c 1 $testdir ||
26366                 error "failed to set default LMV"
26367         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26368         (( max_inherit == -1 )) ||
26369                 error "wrong max_inherit value $max_inherit"
26370
26371         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26372         $LFS setdirstripe -D -c -1 $testdir ||
26373                 error "failed to set default LMV"
26374         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26375         (( max_inherit > 0 )) ||
26376                 error "wrong max_inherit value $max_inherit"
26377
26378         # and the subdir will decrease the max_inherit by 1
26379         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26380         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26381         (( sub_max_inherit == max_inherit - 1)) ||
26382                 error "wrong max-inherit of subdir $sub_max_inherit"
26383
26384         # check specified --max-inherit and warning message
26385         stack_trap "rm -f $tmpfile"
26386         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26387                 error "failed to set default LMV"
26388         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26389         (( max_inherit == -1 )) ||
26390                 error "wrong max_inherit value $max_inherit"
26391
26392         # check the warning messages
26393         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26394                 error "failed to detect warning string"
26395         fi
26396 }
26397 run_test 413e "check default max-inherit value"
26398
26399 test_fs_dmv_inherit()
26400 {
26401         local testdir=$DIR/$tdir
26402
26403         local count
26404         local inherit
26405         local inherit_rr
26406
26407         for i in 1 2 3; do
26408                 mkdir $testdir || error "mkdir $testdir failed"
26409                 count=$($LFS getdirstripe -D -c $testdir)
26410                 (( count == 1 )) ||
26411                         error "$testdir default LMV count mismatch $count != 1"
26412                 inherit=$($LFS getdirstripe -D -X $testdir)
26413                 (( inherit == 3 - i )) ||
26414                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26415                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26416                 (( inherit_rr == 3 - i )) ||
26417                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26418                 testdir=$testdir/sub
26419         done
26420
26421         mkdir $testdir || error "mkdir $testdir failed"
26422         count=$($LFS getdirstripe -D -c $testdir)
26423         (( count == 0 )) ||
26424                 error "$testdir default LMV count not zero: $count"
26425 }
26426
26427 test_413f() {
26428         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26429
26430         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26431                 skip "Need server version at least 2.14.55"
26432
26433         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26434                 error "dump $DIR default LMV failed"
26435         stack_trap "setfattr --restore=$TMP/dmv.ea"
26436
26437         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26438                 error "set $DIR default LMV failed"
26439
26440         test_fs_dmv_inherit
26441 }
26442 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26443
26444 test_413g() {
26445         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26446
26447         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26448         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26449                 error "dump $DIR default LMV failed"
26450         stack_trap "setfattr --restore=$TMP/dmv.ea"
26451
26452         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26453                 error "set $DIR default LMV failed"
26454
26455         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26456                 error "mount $MOUNT2 failed"
26457         stack_trap "umount_client $MOUNT2"
26458
26459         local saved_DIR=$DIR
26460
26461         export DIR=$MOUNT2
26462
26463         stack_trap "export DIR=$saved_DIR"
26464
26465         # first check filesystem-wide default LMV inheritance
26466         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26467
26468         # then check subdirs are spread to all MDTs
26469         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26470
26471         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26472
26473         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26474 }
26475 run_test 413g "enforce ROOT default LMV on subdir mount"
26476
26477 test_413h() {
26478         (( MDSCOUNT >= 2 )) ||
26479                 skip "We need at least 2 MDTs for this test"
26480
26481         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26482                 skip "Need server version at least 2.15.50.6"
26483
26484         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26485
26486         stack_trap "$LCTL set_param \
26487                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26488         $LCTL set_param lmv.*.qos_maxage=1
26489
26490         local depth=5
26491         local rr_depth=4
26492         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26493         local count=$((MDSCOUNT * 20))
26494
26495         generate_uneven_mdts 50
26496
26497         mkdir -p $dir || error "mkdir $dir failed"
26498         stack_trap "rm -rf $dir"
26499         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26500                 --max-inherit-rr=$rr_depth $dir
26501
26502         for ((d=0; d < depth + 2; d++)); do
26503                 log "dir=$dir:"
26504                 for ((sub=0; sub < count; sub++)); do
26505                         mkdir $dir/d$sub
26506                 done
26507                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26508                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26509                 # subdirs within $rr_depth should be created round-robin
26510                 if (( d < rr_depth )); then
26511                         (( ${num[0]} != count )) ||
26512                                 error "all objects created on MDT ${num[1]}"
26513                 fi
26514
26515                 dir=$dir/d0
26516         done
26517 }
26518 run_test 413h "don't stick to parent for round-robin dirs"
26519
26520 test_413z() {
26521         local pids=""
26522         local subdir
26523         local pid
26524
26525         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26526                 unlinkmany $subdir/f. $TEST413_COUNT &
26527                 pids="$pids $!"
26528         done
26529
26530         for pid in $pids; do
26531                 wait $pid
26532         done
26533 }
26534 run_test 413z "413 test cleanup"
26535
26536 test_414() {
26537 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26538         $LCTL set_param fail_loc=0x80000521
26539         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26540         rm -f $DIR/$tfile
26541 }
26542 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26543
26544 test_415() {
26545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26546         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26547                 skip "Need server version at least 2.11.52"
26548
26549         # LU-11102
26550         local total
26551         local setattr_pid
26552         local start_time
26553         local end_time
26554         local duration
26555
26556         total=500
26557         # this test may be slow on ZFS
26558         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26559
26560         # though this test is designed for striped directory, let's test normal
26561         # directory too since lock is always saved as CoS lock.
26562         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26563         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26564
26565         (
26566                 while true; do
26567                         touch $DIR/$tdir
26568                 done
26569         ) &
26570         setattr_pid=$!
26571
26572         start_time=$(date +%s)
26573         for i in $(seq $total); do
26574                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26575                         > /dev/null
26576         done
26577         end_time=$(date +%s)
26578         duration=$((end_time - start_time))
26579
26580         kill -9 $setattr_pid
26581
26582         echo "rename $total files took $duration sec"
26583         [ $duration -lt 100 ] || error "rename took $duration sec"
26584 }
26585 run_test 415 "lock revoke is not missing"
26586
26587 test_416() {
26588         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26589                 skip "Need server version at least 2.11.55"
26590
26591         # define OBD_FAIL_OSD_TXN_START    0x19a
26592         do_facet mds1 lctl set_param fail_loc=0x19a
26593
26594         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26595
26596         true
26597 }
26598 run_test 416 "transaction start failure won't cause system hung"
26599
26600 cleanup_417() {
26601         trap 0
26602         do_nodes $(comma_list $(mdts_nodes)) \
26603                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26604         do_nodes $(comma_list $(mdts_nodes)) \
26605                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26606         do_nodes $(comma_list $(mdts_nodes)) \
26607                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26608 }
26609
26610 test_417() {
26611         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26612         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26613                 skip "Need MDS version at least 2.11.56"
26614
26615         trap cleanup_417 RETURN EXIT
26616
26617         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26618         do_nodes $(comma_list $(mdts_nodes)) \
26619                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26620         $LFS migrate -m 0 $DIR/$tdir.1 &&
26621                 error "migrate dir $tdir.1 should fail"
26622
26623         do_nodes $(comma_list $(mdts_nodes)) \
26624                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26625         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26626                 error "create remote dir $tdir.2 should fail"
26627
26628         do_nodes $(comma_list $(mdts_nodes)) \
26629                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26630         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26631                 error "create striped dir $tdir.3 should fail"
26632         true
26633 }
26634 run_test 417 "disable remote dir, striped dir and dir migration"
26635
26636 # Checks that the outputs of df [-i] and lfs df [-i] match
26637 #
26638 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26639 check_lfs_df() {
26640         local dir=$2
26641         local inodes
26642         local df_out
26643         local lfs_df_out
26644         local count
26645         local passed=false
26646
26647         # blocks or inodes
26648         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26649
26650         for count in {1..100}; do
26651                 do_nodes "$CLIENTS" \
26652                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26653                 sync; sleep 0.2
26654
26655                 # read the lines of interest
26656                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26657                         error "df $inodes $dir | tail -n +2 failed"
26658                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26659                         error "lfs df $inodes $dir | grep summary: failed"
26660
26661                 # skip first substrings of each output as they are different
26662                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26663                 # compare the two outputs
26664                 passed=true
26665                 #  skip "available" on MDT until LU-13997 is fixed.
26666                 #for i in {1..5}; do
26667                 for i in 1 2 4 5; do
26668                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26669                 done
26670                 $passed && break
26671         done
26672
26673         if ! $passed; then
26674                 df -P $inodes $dir
26675                 echo
26676                 lfs df $inodes $dir
26677                 error "df and lfs df $1 output mismatch: "      \
26678                       "df ${inodes}: ${df_out[*]}, "            \
26679                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26680         fi
26681 }
26682
26683 test_418() {
26684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26685
26686         local dir=$DIR/$tdir
26687         local numfiles=$((RANDOM % 4096 + 2))
26688         local numblocks=$((RANDOM % 256 + 1))
26689
26690         wait_delete_completed
26691         test_mkdir $dir
26692
26693         # check block output
26694         check_lfs_df blocks $dir
26695         # check inode output
26696         check_lfs_df inodes $dir
26697
26698         # create a single file and retest
26699         echo "Creating a single file and testing"
26700         createmany -o $dir/$tfile- 1 &>/dev/null ||
26701                 error "creating 1 file in $dir failed"
26702         check_lfs_df blocks $dir
26703         check_lfs_df inodes $dir
26704
26705         # create a random number of files
26706         echo "Creating $((numfiles - 1)) files and testing"
26707         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26708                 error "creating $((numfiles - 1)) files in $dir failed"
26709
26710         # write a random number of blocks to the first test file
26711         echo "Writing $numblocks 4K blocks and testing"
26712         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26713                 count=$numblocks &>/dev/null ||
26714                 error "dd to $dir/${tfile}-0 failed"
26715
26716         # retest
26717         check_lfs_df blocks $dir
26718         check_lfs_df inodes $dir
26719
26720         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26721                 error "unlinking $numfiles files in $dir failed"
26722 }
26723 run_test 418 "df and lfs df outputs match"
26724
26725 test_419()
26726 {
26727         local dir=$DIR/$tdir
26728
26729         mkdir -p $dir
26730         touch $dir/file
26731
26732         cancel_lru_locks mdc
26733
26734         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26735         $LCTL set_param fail_loc=0x1410
26736         cat $dir/file
26737         $LCTL set_param fail_loc=0
26738         rm -rf $dir
26739 }
26740 run_test 419 "Verify open file by name doesn't crash kernel"
26741
26742 test_420()
26743 {
26744         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26745                 skip "Need MDS version at least 2.12.53"
26746
26747         local SAVE_UMASK=$(umask)
26748         local dir=$DIR/$tdir
26749         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26750
26751         mkdir -p $dir
26752         umask 0000
26753         mkdir -m03777 $dir/testdir
26754         ls -dn $dir/testdir
26755         # Need to remove trailing '.' when SELinux is enabled
26756         local dirperms=$(ls -dn $dir/testdir |
26757                          awk '{ sub(/\.$/, "", $1); print $1}')
26758         [ $dirperms == "drwxrwsrwt" ] ||
26759                 error "incorrect perms on $dir/testdir"
26760
26761         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26762                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26763         ls -n $dir/testdir/testfile
26764         local fileperms=$(ls -n $dir/testdir/testfile |
26765                           awk '{ sub(/\.$/, "", $1); print $1}')
26766         [ $fileperms == "-rwxr-xr-x" ] ||
26767                 error "incorrect perms on $dir/testdir/testfile"
26768
26769         umask $SAVE_UMASK
26770 }
26771 run_test 420 "clear SGID bit on non-directories for non-members"
26772
26773 test_421a() {
26774         local cnt
26775         local fid1
26776         local fid2
26777
26778         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26779                 skip "Need MDS version at least 2.12.54"
26780
26781         test_mkdir $DIR/$tdir
26782         createmany -o $DIR/$tdir/f 3
26783         cnt=$(ls -1 $DIR/$tdir | wc -l)
26784         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26785
26786         fid1=$(lfs path2fid $DIR/$tdir/f1)
26787         fid2=$(lfs path2fid $DIR/$tdir/f2)
26788         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26789
26790         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26791         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26792
26793         cnt=$(ls -1 $DIR/$tdir | wc -l)
26794         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26795
26796         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26797         createmany -o $DIR/$tdir/f 3
26798         cnt=$(ls -1 $DIR/$tdir | wc -l)
26799         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26800
26801         fid1=$(lfs path2fid $DIR/$tdir/f1)
26802         fid2=$(lfs path2fid $DIR/$tdir/f2)
26803         echo "remove using fsname $FSNAME"
26804         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26805
26806         cnt=$(ls -1 $DIR/$tdir | wc -l)
26807         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26808 }
26809 run_test 421a "simple rm by fid"
26810
26811 test_421b() {
26812         local cnt
26813         local FID1
26814         local FID2
26815
26816         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26817                 skip "Need MDS version at least 2.12.54"
26818
26819         test_mkdir $DIR/$tdir
26820         createmany -o $DIR/$tdir/f 3
26821         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26822         MULTIPID=$!
26823
26824         FID1=$(lfs path2fid $DIR/$tdir/f1)
26825         FID2=$(lfs path2fid $DIR/$tdir/f2)
26826         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26827
26828         kill -USR1 $MULTIPID
26829         wait
26830
26831         cnt=$(ls $DIR/$tdir | wc -l)
26832         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26833 }
26834 run_test 421b "rm by fid on open file"
26835
26836 test_421c() {
26837         local cnt
26838         local FIDS
26839
26840         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26841                 skip "Need MDS version at least 2.12.54"
26842
26843         test_mkdir $DIR/$tdir
26844         createmany -o $DIR/$tdir/f 3
26845         touch $DIR/$tdir/$tfile
26846         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26847         cnt=$(ls -1 $DIR/$tdir | wc -l)
26848         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26849
26850         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26851         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26852
26853         cnt=$(ls $DIR/$tdir | wc -l)
26854         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26855 }
26856 run_test 421c "rm by fid against hardlinked files"
26857
26858 test_421d() {
26859         local cnt
26860         local FIDS
26861
26862         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26863                 skip "Need MDS version at least 2.12.54"
26864
26865         test_mkdir $DIR/$tdir
26866         createmany -o $DIR/$tdir/f 4097
26867         cnt=$(ls -1 $DIR/$tdir | wc -l)
26868         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26869
26870         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26871         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26872
26873         cnt=$(ls $DIR/$tdir | wc -l)
26874         rm -rf $DIR/$tdir
26875         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26876 }
26877 run_test 421d "rmfid en masse"
26878
26879 test_421e() {
26880         local cnt
26881         local FID
26882
26883         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26884         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26885                 skip "Need MDS version at least 2.12.54"
26886
26887         mkdir -p $DIR/$tdir
26888         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26889         createmany -o $DIR/$tdir/striped_dir/f 512
26890         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26891         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26892
26893         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26894                 sed "s/[/][^:]*://g")
26895         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26896
26897         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26898         rm -rf $DIR/$tdir
26899         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26900 }
26901 run_test 421e "rmfid in DNE"
26902
26903 test_421f() {
26904         local cnt
26905         local FID
26906
26907         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26908                 skip "Need MDS version at least 2.12.54"
26909
26910         test_mkdir $DIR/$tdir
26911         touch $DIR/$tdir/f
26912         cnt=$(ls -1 $DIR/$tdir | wc -l)
26913         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26914
26915         FID=$(lfs path2fid $DIR/$tdir/f)
26916         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26917         # rmfid should fail
26918         cnt=$(ls -1 $DIR/$tdir | wc -l)
26919         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26920
26921         chmod a+rw $DIR/$tdir
26922         ls -la $DIR/$tdir
26923         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26924         # rmfid should fail
26925         cnt=$(ls -1 $DIR/$tdir | wc -l)
26926         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26927
26928         rm -f $DIR/$tdir/f
26929         $RUNAS touch $DIR/$tdir/f
26930         FID=$(lfs path2fid $DIR/$tdir/f)
26931         echo "rmfid as root"
26932         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26933         cnt=$(ls -1 $DIR/$tdir | wc -l)
26934         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26935
26936         rm -f $DIR/$tdir/f
26937         $RUNAS touch $DIR/$tdir/f
26938         cnt=$(ls -1 $DIR/$tdir | wc -l)
26939         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26940         FID=$(lfs path2fid $DIR/$tdir/f)
26941         # rmfid w/o user_fid2path mount option should fail
26942         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26943         cnt=$(ls -1 $DIR/$tdir | wc -l)
26944         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26945
26946         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26947         stack_trap "rmdir $tmpdir"
26948         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26949                 error "failed to mount client'"
26950         stack_trap "umount_client $tmpdir"
26951
26952         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26953         # rmfid should succeed
26954         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26955         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26956
26957         # rmfid shouldn't allow to remove files due to dir's permission
26958         chmod a+rwx $tmpdir/$tdir
26959         touch $tmpdir/$tdir/f
26960         ls -la $tmpdir/$tdir
26961         FID=$(lfs path2fid $tmpdir/$tdir/f)
26962         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26963         return 0
26964 }
26965 run_test 421f "rmfid checks permissions"
26966
26967 test_421g() {
26968         local cnt
26969         local FIDS
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
26984         rm -f $DIR/$tdir/striped_dir/f1*
26985         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26986         removed=$((512 - cnt))
26987
26988         # few files have been just removed, so we expect
26989         # rmfid to fail on their fids
26990         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26991         [ $removed != $errors ] && error "$errors != $removed"
26992
26993         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26994         rm -rf $DIR/$tdir
26995         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26996 }
26997 run_test 421g "rmfid to return errors properly"
26998
26999 test_422() {
27000         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27001         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27002         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27003         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27004         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27005
27006         local amc=$(at_max_get client)
27007         local amo=$(at_max_get mds1)
27008         local timeout=`lctl get_param -n timeout`
27009
27010         at_max_set 0 client
27011         at_max_set 0 mds1
27012
27013 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27014         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27015                         fail_val=$(((2*timeout + 10)*1000))
27016         touch $DIR/$tdir/d3/file &
27017         sleep 2
27018 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27019         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27020                         fail_val=$((2*timeout + 5))
27021         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27022         local pid=$!
27023         sleep 1
27024         kill -9 $pid
27025         sleep $((2 * timeout))
27026         echo kill $pid
27027         kill -9 $pid
27028         lctl mark touch
27029         touch $DIR/$tdir/d2/file3
27030         touch $DIR/$tdir/d2/file4
27031         touch $DIR/$tdir/d2/file5
27032
27033         wait
27034         at_max_set $amc client
27035         at_max_set $amo mds1
27036
27037         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27038         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27039                 error "Watchdog is always throttled"
27040 }
27041 run_test 422 "kill a process with RPC in progress"
27042
27043 stat_test() {
27044     df -h $MOUNT &
27045     df -h $MOUNT &
27046     df -h $MOUNT &
27047     df -h $MOUNT &
27048     df -h $MOUNT &
27049     df -h $MOUNT &
27050 }
27051
27052 test_423() {
27053     local _stats
27054     # ensure statfs cache is expired
27055     sleep 2;
27056
27057     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27058     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27059
27060     return 0
27061 }
27062 run_test 423 "statfs should return a right data"
27063
27064 test_424() {
27065 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27066         $LCTL set_param fail_loc=0x80000522
27067         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27068         rm -f $DIR/$tfile
27069 }
27070 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27071
27072 test_425() {
27073         test_mkdir -c -1 $DIR/$tdir
27074         $LFS setstripe -c -1 $DIR/$tdir
27075
27076         lru_resize_disable "" 100
27077         stack_trap "lru_resize_enable" EXIT
27078
27079         sleep 5
27080
27081         for i in $(seq $((MDSCOUNT * 125))); do
27082                 local t=$DIR/$tdir/$tfile_$i
27083
27084                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27085                         error_noexit "Create file $t"
27086         done
27087         stack_trap "rm -rf $DIR/$tdir" EXIT
27088
27089         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27090                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27091                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27092
27093                 [ $lock_count -le $lru_size ] ||
27094                         error "osc lock count $lock_count > lru size $lru_size"
27095         done
27096
27097         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27098                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27099                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27100
27101                 [ $lock_count -le $lru_size ] ||
27102                         error "mdc lock count $lock_count > lru size $lru_size"
27103         done
27104 }
27105 run_test 425 "lock count should not exceed lru size"
27106
27107 test_426() {
27108         splice-test -r $DIR/$tfile
27109         splice-test -rd $DIR/$tfile
27110         splice-test $DIR/$tfile
27111         splice-test -d $DIR/$tfile
27112 }
27113 run_test 426 "splice test on Lustre"
27114
27115 test_427() {
27116         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27117         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27118                 skip "Need MDS version at least 2.12.4"
27119         local log
27120
27121         mkdir $DIR/$tdir
27122         mkdir $DIR/$tdir/1
27123         mkdir $DIR/$tdir/2
27124         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27125         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27126
27127         $LFS getdirstripe $DIR/$tdir/1/dir
27128
27129         #first setfattr for creating updatelog
27130         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27131
27132 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27133         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27134         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27135         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27136
27137         sleep 2
27138         fail mds2
27139         wait_recovery_complete mds2 $((2*TIMEOUT))
27140
27141         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27142         echo $log | grep "get update log failed" &&
27143                 error "update log corruption is detected" || true
27144 }
27145 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27146
27147 test_428() {
27148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27149         local cache_limit=$CACHE_MAX
27150
27151         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27152         $LCTL set_param -n llite.*.max_cached_mb=64
27153
27154         mkdir $DIR/$tdir
27155         $LFS setstripe -c 1 $DIR/$tdir
27156         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27157         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27158         #test write
27159         for f in $(seq 4); do
27160                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27161         done
27162         wait
27163
27164         cancel_lru_locks osc
27165         # Test read
27166         for f in $(seq 4); do
27167                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27168         done
27169         wait
27170 }
27171 run_test 428 "large block size IO should not hang"
27172
27173 test_429() { # LU-7915 / LU-10948
27174         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27175         local testfile=$DIR/$tfile
27176         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27177         local new_flag=1
27178         local first_rpc
27179         local second_rpc
27180         local third_rpc
27181
27182         $LCTL get_param $ll_opencache_threshold_count ||
27183                 skip "client does not have opencache parameter"
27184
27185         set_opencache $new_flag
27186         stack_trap "restore_opencache"
27187         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27188                 error "enable opencache failed"
27189         touch $testfile
27190         # drop MDC DLM locks
27191         cancel_lru_locks mdc
27192         # clear MDC RPC stats counters
27193         $LCTL set_param $mdc_rpcstats=clear
27194
27195         # According to the current implementation, we need to run 3 times
27196         # open & close file to verify if opencache is enabled correctly.
27197         # 1st, RPCs are sent for lookup/open and open handle is released on
27198         #      close finally.
27199         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27200         #      so open handle won't be released thereafter.
27201         # 3rd, No RPC is sent out.
27202         $MULTIOP $testfile oc || error "multiop failed"
27203         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27204         echo "1st: $first_rpc RPCs in flight"
27205
27206         $MULTIOP $testfile oc || error "multiop failed"
27207         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27208         echo "2nd: $second_rpc RPCs in flight"
27209
27210         $MULTIOP $testfile oc || error "multiop failed"
27211         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27212         echo "3rd: $third_rpc RPCs in flight"
27213
27214         #verify no MDC RPC is sent
27215         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27216 }
27217 run_test 429 "verify if opencache flag on client side does work"
27218
27219 lseek_test_430() {
27220         local offset
27221         local file=$1
27222
27223         # data at [200K, 400K)
27224         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27225                 error "256K->512K dd fails"
27226         # data at [2M, 3M)
27227         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27228                 error "2M->3M dd fails"
27229         # data at [4M, 5M)
27230         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27231                 error "4M->5M dd fails"
27232         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27233         # start at first component hole #1
27234         printf "Seeking hole from 1000 ... "
27235         offset=$(lseek_test -l 1000 $file)
27236         echo $offset
27237         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27238         printf "Seeking data from 1000 ... "
27239         offset=$(lseek_test -d 1000 $file)
27240         echo $offset
27241         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27242
27243         # start at first component data block
27244         printf "Seeking hole from 300000 ... "
27245         offset=$(lseek_test -l 300000 $file)
27246         echo $offset
27247         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27248         printf "Seeking data from 300000 ... "
27249         offset=$(lseek_test -d 300000 $file)
27250         echo $offset
27251         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27252
27253         # start at the first component but beyond end of object size
27254         printf "Seeking hole from 1000000 ... "
27255         offset=$(lseek_test -l 1000000 $file)
27256         echo $offset
27257         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27258         printf "Seeking data from 1000000 ... "
27259         offset=$(lseek_test -d 1000000 $file)
27260         echo $offset
27261         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27262
27263         # start at second component stripe 2 (empty file)
27264         printf "Seeking hole from 1500000 ... "
27265         offset=$(lseek_test -l 1500000 $file)
27266         echo $offset
27267         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27268         printf "Seeking data from 1500000 ... "
27269         offset=$(lseek_test -d 1500000 $file)
27270         echo $offset
27271         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27272
27273         # start at second component stripe 1 (all data)
27274         printf "Seeking hole from 3000000 ... "
27275         offset=$(lseek_test -l 3000000 $file)
27276         echo $offset
27277         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27278         printf "Seeking data from 3000000 ... "
27279         offset=$(lseek_test -d 3000000 $file)
27280         echo $offset
27281         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27282
27283         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27284                 error "2nd dd fails"
27285         echo "Add data block at 640K...1280K"
27286
27287         # start at before new data block, in hole
27288         printf "Seeking hole from 600000 ... "
27289         offset=$(lseek_test -l 600000 $file)
27290         echo $offset
27291         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27292         printf "Seeking data from 600000 ... "
27293         offset=$(lseek_test -d 600000 $file)
27294         echo $offset
27295         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27296
27297         # start at the first component new data block
27298         printf "Seeking hole from 1000000 ... "
27299         offset=$(lseek_test -l 1000000 $file)
27300         echo $offset
27301         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27302         printf "Seeking data from 1000000 ... "
27303         offset=$(lseek_test -d 1000000 $file)
27304         echo $offset
27305         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27306
27307         # start at second component stripe 2, new data
27308         printf "Seeking hole from 1200000 ... "
27309         offset=$(lseek_test -l 1200000 $file)
27310         echo $offset
27311         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27312         printf "Seeking data from 1200000 ... "
27313         offset=$(lseek_test -d 1200000 $file)
27314         echo $offset
27315         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27316
27317         # start beyond file end
27318         printf "Using offset > filesize ... "
27319         lseek_test -l 4000000 $file && error "lseek should fail"
27320         printf "Using offset > filesize ... "
27321         lseek_test -d 4000000 $file && error "lseek should fail"
27322
27323         printf "Done\n\n"
27324 }
27325
27326 test_430a() {
27327         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27328                 skip "MDT does not support SEEK_HOLE"
27329
27330         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27331                 skip "OST does not support SEEK_HOLE"
27332
27333         local file=$DIR/$tdir/$tfile
27334
27335         mkdir -p $DIR/$tdir
27336
27337         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27338         # OST stripe #1 will have continuous data at [1M, 3M)
27339         # OST stripe #2 is empty
27340         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27341         lseek_test_430 $file
27342         rm $file
27343         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27344         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27345         lseek_test_430 $file
27346         rm $file
27347         $LFS setstripe -c2 -S 512K $file
27348         echo "Two stripes, stripe size 512K"
27349         lseek_test_430 $file
27350         rm $file
27351         # FLR with stale mirror
27352         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27353                        -N -c2 -S 1M $file
27354         echo "Mirrored file:"
27355         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27356         echo "Plain 2 stripes 1M"
27357         lseek_test_430 $file
27358         rm $file
27359 }
27360 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27361
27362 test_430b() {
27363         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27364                 skip "OST does not support SEEK_HOLE"
27365
27366         local offset
27367         local file=$DIR/$tdir/$tfile
27368
27369         mkdir -p $DIR/$tdir
27370         # Empty layout lseek should fail
27371         $MCREATE $file
27372         # seek from 0
27373         printf "Seeking hole from 0 ... "
27374         lseek_test -l 0 $file && error "lseek should fail"
27375         printf "Seeking data from 0 ... "
27376         lseek_test -d 0 $file && error "lseek should fail"
27377         rm $file
27378
27379         # 1M-hole file
27380         $LFS setstripe -E 1M -c2 -E eof $file
27381         $TRUNCATE $file 1048576
27382         printf "Seeking hole from 1000000 ... "
27383         offset=$(lseek_test -l 1000000 $file)
27384         echo $offset
27385         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27386         printf "Seeking data from 1000000 ... "
27387         lseek_test -d 1000000 $file && error "lseek should fail"
27388         rm $file
27389
27390         # full component followed by non-inited one
27391         $LFS setstripe -E 1M -c2 -E eof $file
27392         dd if=/dev/urandom of=$file bs=1M count=1
27393         printf "Seeking hole from 1000000 ... "
27394         offset=$(lseek_test -l 1000000 $file)
27395         echo $offset
27396         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27397         printf "Seeking hole from 1048576 ... "
27398         lseek_test -l 1048576 $file && error "lseek should fail"
27399         # init second component and truncate back
27400         echo "123" >> $file
27401         $TRUNCATE $file 1048576
27402         printf "Seeking hole from 1000000 ... "
27403         offset=$(lseek_test -l 1000000 $file)
27404         echo $offset
27405         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27406         printf "Seeking hole from 1048576 ... "
27407         lseek_test -l 1048576 $file && error "lseek should fail"
27408         # boundary checks for big values
27409         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27410         offset=$(lseek_test -d 0 $file.10g)
27411         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27412         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27413         offset=$(lseek_test -d 0 $file.100g)
27414         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27415         return 0
27416 }
27417 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27418
27419 test_430c() {
27420         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27421                 skip "OST does not support SEEK_HOLE"
27422
27423         local file=$DIR/$tdir/$tfile
27424         local start
27425
27426         mkdir -p $DIR/$tdir
27427         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27428
27429         # cp version 8.33+ prefers lseek over fiemap
27430         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27431                 start=$SECONDS
27432                 time cp $file /dev/null
27433                 (( SECONDS - start < 5 )) ||
27434                         error "cp: too long runtime $((SECONDS - start))"
27435
27436         fi
27437         # tar version 1.29+ supports SEEK_HOLE/DATA
27438         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27439                 start=$SECONDS
27440                 time tar cS $file - | cat > /dev/null
27441                 (( SECONDS - start < 5 )) ||
27442                         error "tar: too long runtime $((SECONDS - start))"
27443         fi
27444 }
27445 run_test 430c "lseek: external tools check"
27446
27447 test_431() { # LU-14187
27448         local file=$DIR/$tdir/$tfile
27449
27450         mkdir -p $DIR/$tdir
27451         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27452         dd if=/dev/urandom of=$file bs=4k count=1
27453         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27454         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27455         #define OBD_FAIL_OST_RESTART_IO 0x251
27456         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27457         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27458         cp $file $file.0
27459         cancel_lru_locks
27460         sync_all_data
27461         echo 3 > /proc/sys/vm/drop_caches
27462         diff  $file $file.0 || error "data diff"
27463 }
27464 run_test 431 "Restart transaction for IO"
27465
27466 cleanup_test_432() {
27467         do_facet mgs $LCTL nodemap_activate 0
27468         wait_nm_sync active
27469 }
27470
27471 test_432() {
27472         local tmpdir=$TMP/dir432
27473
27474         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27475                 skip "Need MDS version at least 2.14.52"
27476
27477         stack_trap cleanup_test_432 EXIT
27478         mkdir $DIR/$tdir
27479         mkdir $tmpdir
27480
27481         do_facet mgs $LCTL nodemap_activate 1
27482         wait_nm_sync active
27483         do_facet mgs $LCTL nodemap_modify --name default \
27484                 --property admin --value 1
27485         do_facet mgs $LCTL nodemap_modify --name default \
27486                 --property trusted --value 1
27487         cancel_lru_locks mdc
27488         wait_nm_sync default admin_nodemap
27489         wait_nm_sync default trusted_nodemap
27490
27491         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27492                grep -ci "Operation not permitted") -ne 0 ]; then
27493                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27494         fi
27495 }
27496 run_test 432 "mv dir from outside Lustre"
27497
27498 test_433() {
27499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27500
27501         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27502                 skip "inode cache not supported"
27503
27504         $LCTL set_param llite.*.inode_cache=0
27505         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27506
27507         local count=256
27508         local before
27509         local after
27510
27511         cancel_lru_locks mdc
27512         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27513         createmany -m $DIR/$tdir/f $count
27514         createmany -d $DIR/$tdir/d $count
27515         ls -l $DIR/$tdir > /dev/null
27516         stack_trap "rm -rf $DIR/$tdir"
27517
27518         before=$(num_objects)
27519         cancel_lru_locks mdc
27520         after=$(num_objects)
27521
27522         # sometimes even @before is less than 2 * count
27523         while (( before - after < count )); do
27524                 sleep 1
27525                 after=$(num_objects)
27526                 wait=$((wait + 1))
27527                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27528                 if (( wait > 60 )); then
27529                         error "inode slab grew from $before to $after"
27530                 fi
27531         done
27532
27533         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27534 }
27535 run_test 433 "ldlm lock cancel releases dentries and inodes"
27536
27537 prep_801() {
27538         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27539         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27540                 skip "Need server version at least 2.9.55"
27541
27542         start_full_debug_logging
27543 }
27544
27545 post_801() {
27546         stop_full_debug_logging
27547 }
27548
27549 barrier_stat() {
27550         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27551                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27552                            awk '/The barrier for/ { print $7 }')
27553                 echo $st
27554         else
27555                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27556                 echo \'$st\'
27557         fi
27558 }
27559
27560 barrier_expired() {
27561         local expired
27562
27563         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27564                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27565                           awk '/will be expired/ { print $7 }')
27566         else
27567                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27568         fi
27569
27570         echo $expired
27571 }
27572
27573 test_801a() {
27574         prep_801
27575
27576         echo "Start barrier_freeze at: $(date)"
27577         #define OBD_FAIL_BARRIER_DELAY          0x2202
27578         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27579         # Do not reduce barrier time - See LU-11873
27580         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27581
27582         sleep 2
27583         local b_status=$(barrier_stat)
27584         echo "Got barrier status at: $(date)"
27585         [ "$b_status" = "'freezing_p1'" ] ||
27586                 error "(1) unexpected barrier status $b_status"
27587
27588         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27589         wait
27590         b_status=$(barrier_stat)
27591         [ "$b_status" = "'frozen'" ] ||
27592                 error "(2) unexpected barrier status $b_status"
27593
27594         local expired=$(barrier_expired)
27595         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27596         sleep $((expired + 3))
27597
27598         b_status=$(barrier_stat)
27599         [ "$b_status" = "'expired'" ] ||
27600                 error "(3) unexpected barrier status $b_status"
27601
27602         # Do not reduce barrier time - See LU-11873
27603         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27604                 error "(4) fail to freeze barrier"
27605
27606         b_status=$(barrier_stat)
27607         [ "$b_status" = "'frozen'" ] ||
27608                 error "(5) unexpected barrier status $b_status"
27609
27610         echo "Start barrier_thaw at: $(date)"
27611         #define OBD_FAIL_BARRIER_DELAY          0x2202
27612         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27613         do_facet mgs $LCTL barrier_thaw $FSNAME &
27614
27615         sleep 2
27616         b_status=$(barrier_stat)
27617         echo "Got barrier status at: $(date)"
27618         [ "$b_status" = "'thawing'" ] ||
27619                 error "(6) unexpected barrier status $b_status"
27620
27621         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27622         wait
27623         b_status=$(barrier_stat)
27624         [ "$b_status" = "'thawed'" ] ||
27625                 error "(7) unexpected barrier status $b_status"
27626
27627         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27628         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27629         do_facet mgs $LCTL barrier_freeze $FSNAME
27630
27631         b_status=$(barrier_stat)
27632         [ "$b_status" = "'failed'" ] ||
27633                 error "(8) unexpected barrier status $b_status"
27634
27635         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27636         do_facet mgs $LCTL barrier_thaw $FSNAME
27637
27638         post_801
27639 }
27640 run_test 801a "write barrier user interfaces and stat machine"
27641
27642 test_801b() {
27643         prep_801
27644
27645         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27646         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27647         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27648         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27649         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27650
27651         cancel_lru_locks mdc
27652
27653         # 180 seconds should be long enough
27654         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27655
27656         local b_status=$(barrier_stat)
27657         [ "$b_status" = "'frozen'" ] ||
27658                 error "(6) unexpected barrier status $b_status"
27659
27660         mkdir $DIR/$tdir/d0/d10 &
27661         mkdir_pid=$!
27662
27663         touch $DIR/$tdir/d1/f13 &
27664         touch_pid=$!
27665
27666         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27667         ln_pid=$!
27668
27669         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27670         mv_pid=$!
27671
27672         rm -f $DIR/$tdir/d4/f12 &
27673         rm_pid=$!
27674
27675         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27676
27677         # To guarantee taht the 'stat' is not blocked
27678         b_status=$(barrier_stat)
27679         [ "$b_status" = "'frozen'" ] ||
27680                 error "(8) unexpected barrier status $b_status"
27681
27682         # let above commands to run at background
27683         sleep 5
27684
27685         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27686         ps -p $touch_pid || error "(10) touch should be blocked"
27687         ps -p $ln_pid || error "(11) link should be blocked"
27688         ps -p $mv_pid || error "(12) rename should be blocked"
27689         ps -p $rm_pid || error "(13) unlink should be blocked"
27690
27691         b_status=$(barrier_stat)
27692         [ "$b_status" = "'frozen'" ] ||
27693                 error "(14) unexpected barrier status $b_status"
27694
27695         do_facet mgs $LCTL barrier_thaw $FSNAME
27696         b_status=$(barrier_stat)
27697         [ "$b_status" = "'thawed'" ] ||
27698                 error "(15) unexpected barrier status $b_status"
27699
27700         wait $mkdir_pid || error "(16) mkdir should succeed"
27701         wait $touch_pid || error "(17) touch should succeed"
27702         wait $ln_pid || error "(18) link should succeed"
27703         wait $mv_pid || error "(19) rename should succeed"
27704         wait $rm_pid || error "(20) unlink should succeed"
27705
27706         post_801
27707 }
27708 run_test 801b "modification will be blocked by write barrier"
27709
27710 test_801c() {
27711         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27712
27713         prep_801
27714
27715         stop mds2 || error "(1) Fail to stop mds2"
27716
27717         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27718
27719         local b_status=$(barrier_stat)
27720         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27721                 do_facet mgs $LCTL barrier_thaw $FSNAME
27722                 error "(2) unexpected barrier status $b_status"
27723         }
27724
27725         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27726                 error "(3) Fail to rescan barrier bitmap"
27727
27728         # Do not reduce barrier time - See LU-11873
27729         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27730
27731         b_status=$(barrier_stat)
27732         [ "$b_status" = "'frozen'" ] ||
27733                 error "(4) unexpected barrier status $b_status"
27734
27735         do_facet mgs $LCTL barrier_thaw $FSNAME
27736         b_status=$(barrier_stat)
27737         [ "$b_status" = "'thawed'" ] ||
27738                 error "(5) unexpected barrier status $b_status"
27739
27740         local devname=$(mdsdevname 2)
27741
27742         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27743
27744         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27745                 error "(7) Fail to rescan barrier bitmap"
27746
27747         post_801
27748 }
27749 run_test 801c "rescan barrier bitmap"
27750
27751 test_802b() {
27752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27753         remote_mds_nodsh && skip "remote MDS with nodsh"
27754
27755         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27756                 skip "readonly option not available"
27757
27758         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27759
27760         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27761                 error "(2) Fail to copy"
27762
27763         # write back all cached data before setting MDT to readonly
27764         cancel_lru_locks
27765         sync_all_data
27766
27767         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27768         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27769
27770         echo "Modify should be refused"
27771         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27772
27773         echo "Read should be allowed"
27774         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27775                 error "(7) Read should succeed under ro mode"
27776
27777         # disable readonly
27778         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27779 }
27780 run_test 802b "be able to set MDTs to readonly"
27781
27782 test_803a() {
27783         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27784         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27785                 skip "MDS needs to be newer than 2.10.54"
27786
27787         mkdir_on_mdt0 $DIR/$tdir
27788         # Create some objects on all MDTs to trigger related logs objects
27789         for idx in $(seq $MDSCOUNT); do
27790                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27791                         $DIR/$tdir/dir${idx} ||
27792                         error "Fail to create $DIR/$tdir/dir${idx}"
27793         done
27794
27795         wait_delete_completed # ensure old test cleanups are finished
27796         sleep 3
27797         echo "before create:"
27798         $LFS df -i $MOUNT
27799         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27800
27801         for i in {1..10}; do
27802                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27803                         error "Fail to create $DIR/$tdir/foo$i"
27804         done
27805
27806         # sync ZFS-on-MDS to refresh statfs data
27807         wait_zfs_commit mds1
27808         sleep 3
27809         echo "after create:"
27810         $LFS df -i $MOUNT
27811         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27812
27813         # allow for an llog to be cleaned up during the test
27814         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27815                 error "before ($before_used) + 10 > after ($after_used)"
27816
27817         for i in {1..10}; do
27818                 rm -rf $DIR/$tdir/foo$i ||
27819                         error "Fail to remove $DIR/$tdir/foo$i"
27820         done
27821
27822         # sync ZFS-on-MDS to refresh statfs data
27823         wait_zfs_commit mds1
27824         wait_delete_completed
27825         sleep 3 # avoid MDT return cached statfs
27826         echo "after unlink:"
27827         $LFS df -i $MOUNT
27828         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27829
27830         # allow for an llog to be created during the test
27831         [ $after_used -le $((before_used + 1)) ] ||
27832                 error "after ($after_used) > before ($before_used) + 1"
27833 }
27834 run_test 803a "verify agent object for remote object"
27835
27836 test_803b() {
27837         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27838         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27839                 skip "MDS needs to be newer than 2.13.56"
27840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27841
27842         for i in $(seq 0 $((MDSCOUNT - 1))); do
27843                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27844         done
27845
27846         local before=0
27847         local after=0
27848
27849         local tmp
27850
27851         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27852         for i in $(seq 0 $((MDSCOUNT - 1))); do
27853                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27854                         awk '/getattr/ { print $2 }')
27855                 before=$((before + tmp))
27856         done
27857         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27858         for i in $(seq 0 $((MDSCOUNT - 1))); do
27859                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27860                         awk '/getattr/ { print $2 }')
27861                 after=$((after + tmp))
27862         done
27863
27864         [ $before -eq $after ] || error "getattr count $before != $after"
27865 }
27866 run_test 803b "remote object can getattr from cache"
27867
27868 test_804() {
27869         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27870         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27871                 skip "MDS needs to be newer than 2.10.54"
27872         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27873
27874         mkdir -p $DIR/$tdir
27875         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27876                 error "Fail to create $DIR/$tdir/dir0"
27877
27878         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27879         local dev=$(mdsdevname 2)
27880
27881         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27882                 grep ${fid} || error "NOT found agent entry for dir0"
27883
27884         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27885                 error "Fail to create $DIR/$tdir/dir1"
27886
27887         touch $DIR/$tdir/dir1/foo0 ||
27888                 error "Fail to create $DIR/$tdir/dir1/foo0"
27889         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27890         local rc=0
27891
27892         for idx in $(seq $MDSCOUNT); do
27893                 dev=$(mdsdevname $idx)
27894                 do_facet mds${idx} \
27895                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27896                         grep ${fid} && rc=$idx
27897         done
27898
27899         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27900                 error "Fail to rename foo0 to foo1"
27901         if [ $rc -eq 0 ]; then
27902                 for idx in $(seq $MDSCOUNT); do
27903                         dev=$(mdsdevname $idx)
27904                         do_facet mds${idx} \
27905                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27906                         grep ${fid} && rc=$idx
27907                 done
27908         fi
27909
27910         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27911                 error "Fail to rename foo1 to foo2"
27912         if [ $rc -eq 0 ]; then
27913                 for idx in $(seq $MDSCOUNT); do
27914                         dev=$(mdsdevname $idx)
27915                         do_facet mds${idx} \
27916                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27917                         grep ${fid} && rc=$idx
27918                 done
27919         fi
27920
27921         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27922
27923         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27924                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27925         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27926                 error "Fail to rename foo2 to foo0"
27927         unlink $DIR/$tdir/dir1/foo0 ||
27928                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27929         rm -rf $DIR/$tdir/dir0 ||
27930                 error "Fail to rm $DIR/$tdir/dir0"
27931
27932         for idx in $(seq $MDSCOUNT); do
27933                 rc=0
27934
27935                 stop mds${idx}
27936                 dev=$(mdsdevname $idx)
27937                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27938                         rc=$?
27939                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27940                         error "mount mds$idx failed"
27941                 df $MOUNT > /dev/null 2>&1
27942
27943                 # e2fsck should not return error
27944                 [ $rc -eq 0 ] ||
27945                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27946         done
27947 }
27948 run_test 804 "verify agent entry for remote entry"
27949
27950 cleanup_805() {
27951         do_facet $SINGLEMDS zfs set quota=$old $fsset
27952         unlinkmany $DIR/$tdir/f- 1000000
27953         trap 0
27954 }
27955
27956 test_805() {
27957         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27958         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27959         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27960                 skip "netfree not implemented before 0.7"
27961         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27962                 skip "Need MDS version at least 2.10.57"
27963
27964         local fsset
27965         local freekb
27966         local usedkb
27967         local old
27968         local quota
27969         local pref="osd-zfs.$FSNAME-MDT0000."
27970
27971         # limit available space on MDS dataset to meet nospace issue
27972         # quickly. then ZFS 0.7.2 can use reserved space if asked
27973         # properly (using netfree flag in osd_declare_destroy()
27974         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27975         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27976                 gawk '{print $3}')
27977         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27978         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27979         let "usedkb=usedkb-freekb"
27980         let "freekb=freekb/2"
27981         if let "freekb > 5000"; then
27982                 let "freekb=5000"
27983         fi
27984         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27985         trap cleanup_805 EXIT
27986         mkdir_on_mdt0 $DIR/$tdir
27987         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27988                 error "Can't set PFL layout"
27989         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27990         rm -rf $DIR/$tdir || error "not able to remove"
27991         do_facet $SINGLEMDS zfs set quota=$old $fsset
27992         trap 0
27993 }
27994 run_test 805 "ZFS can remove from full fs"
27995
27996 # Size-on-MDS test
27997 check_lsom_data()
27998 {
27999         local file=$1
28000         local expect=$(stat -c %s $file)
28001
28002         check_lsom_size $1 $expect
28003
28004         local blocks=$($LFS getsom -b $file)
28005         expect=$(stat -c %b $file)
28006         [[ $blocks == $expect ]] ||
28007                 error "$file expected blocks: $expect, got: $blocks"
28008 }
28009
28010 check_lsom_size()
28011 {
28012         local size
28013         local expect=$2
28014
28015         cancel_lru_locks mdc
28016
28017         size=$($LFS getsom -s $1)
28018         [[ $size == $expect ]] ||
28019                 error "$file expected size: $expect, got: $size"
28020 }
28021
28022 test_806() {
28023         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28024                 skip "Need MDS version at least 2.11.52"
28025
28026         local bs=1048576
28027
28028         touch $DIR/$tfile || error "touch $tfile failed"
28029
28030         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28031         save_lustre_params client "llite.*.xattr_cache" > $save
28032         lctl set_param llite.*.xattr_cache=0
28033         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28034
28035         # single-threaded write
28036         echo "Test SOM for single-threaded write"
28037         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28038                 error "write $tfile failed"
28039         check_lsom_size $DIR/$tfile $bs
28040
28041         local num=32
28042         local size=$(($num * $bs))
28043         local offset=0
28044         local i
28045
28046         echo "Test SOM for single client multi-threaded($num) write"
28047         $TRUNCATE $DIR/$tfile 0
28048         for ((i = 0; i < $num; i++)); do
28049                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28050                 local pids[$i]=$!
28051                 offset=$((offset + $bs))
28052         done
28053         for (( i=0; i < $num; i++ )); do
28054                 wait ${pids[$i]}
28055         done
28056         check_lsom_size $DIR/$tfile $size
28057
28058         $TRUNCATE $DIR/$tfile 0
28059         for ((i = 0; i < $num; i++)); do
28060                 offset=$((offset - $bs))
28061                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28062                 local pids[$i]=$!
28063         done
28064         for (( i=0; i < $num; i++ )); do
28065                 wait ${pids[$i]}
28066         done
28067         check_lsom_size $DIR/$tfile $size
28068
28069         # multi-client writes
28070         num=$(get_node_count ${CLIENTS//,/ })
28071         size=$(($num * $bs))
28072         offset=0
28073         i=0
28074
28075         echo "Test SOM for multi-client ($num) writes"
28076         $TRUNCATE $DIR/$tfile 0
28077         for client in ${CLIENTS//,/ }; do
28078                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28079                 local pids[$i]=$!
28080                 i=$((i + 1))
28081                 offset=$((offset + $bs))
28082         done
28083         for (( i=0; i < $num; i++ )); do
28084                 wait ${pids[$i]}
28085         done
28086         check_lsom_size $DIR/$tfile $offset
28087
28088         i=0
28089         $TRUNCATE $DIR/$tfile 0
28090         for client in ${CLIENTS//,/ }; do
28091                 offset=$((offset - $bs))
28092                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28093                 local pids[$i]=$!
28094                 i=$((i + 1))
28095         done
28096         for (( i=0; i < $num; i++ )); do
28097                 wait ${pids[$i]}
28098         done
28099         check_lsom_size $DIR/$tfile $size
28100
28101         # verify truncate
28102         echo "Test SOM for truncate"
28103         $TRUNCATE $DIR/$tfile 1048576
28104         check_lsom_size $DIR/$tfile 1048576
28105         $TRUNCATE $DIR/$tfile 1234
28106         check_lsom_size $DIR/$tfile 1234
28107
28108         # verify SOM blocks count
28109         echo "Verify SOM block count"
28110         $TRUNCATE $DIR/$tfile 0
28111         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28112                 error "failed to write file $tfile"
28113         check_lsom_data $DIR/$tfile
28114 }
28115 run_test 806 "Verify Lazy Size on MDS"
28116
28117 test_807() {
28118         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28119         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28120                 skip "Need MDS version at least 2.11.52"
28121
28122         # Registration step
28123         changelog_register || error "changelog_register failed"
28124         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28125         changelog_users $SINGLEMDS | grep -q $cl_user ||
28126                 error "User $cl_user not found in changelog_users"
28127
28128         rm -rf $DIR/$tdir || error "rm $tdir failed"
28129         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28130         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28131         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28132         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28133                 error "truncate $tdir/trunc failed"
28134
28135         local bs=1048576
28136         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28137                 error "write $tfile failed"
28138
28139         # multi-client wirtes
28140         local num=$(get_node_count ${CLIENTS//,/ })
28141         local offset=0
28142         local i=0
28143
28144         echo "Test SOM for multi-client ($num) writes"
28145         touch $DIR/$tfile || error "touch $tfile failed"
28146         $TRUNCATE $DIR/$tfile 0
28147         for client in ${CLIENTS//,/ }; do
28148                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28149                 local pids[$i]=$!
28150                 i=$((i + 1))
28151                 offset=$((offset + $bs))
28152         done
28153         for (( i=0; i < $num; i++ )); do
28154                 wait ${pids[$i]}
28155         done
28156
28157         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28158         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28159         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28160         check_lsom_data $DIR/$tdir/trunc
28161         check_lsom_data $DIR/$tdir/single_dd
28162         check_lsom_data $DIR/$tfile
28163
28164         rm -rf $DIR/$tdir
28165         # Deregistration step
28166         changelog_deregister || error "changelog_deregister failed"
28167 }
28168 run_test 807 "verify LSOM syncing tool"
28169
28170 check_som_nologged()
28171 {
28172         local lines=$($LFS changelog $FSNAME-MDT0000 |
28173                 grep 'x=trusted.som' | wc -l)
28174         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28175 }
28176
28177 test_808() {
28178         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28179                 skip "Need MDS version at least 2.11.55"
28180
28181         # Registration step
28182         changelog_register || error "changelog_register failed"
28183
28184         touch $DIR/$tfile || error "touch $tfile failed"
28185         check_som_nologged
28186
28187         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28188                 error "write $tfile failed"
28189         check_som_nologged
28190
28191         $TRUNCATE $DIR/$tfile 1234
28192         check_som_nologged
28193
28194         $TRUNCATE $DIR/$tfile 1048576
28195         check_som_nologged
28196
28197         # Deregistration step
28198         changelog_deregister || error "changelog_deregister failed"
28199 }
28200 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28201
28202 check_som_nodata()
28203 {
28204         $LFS getsom $1
28205         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28206 }
28207
28208 test_809() {
28209         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28210                 skip "Need MDS version at least 2.11.56"
28211
28212         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28213                 error "failed to create DoM-only file $DIR/$tfile"
28214         touch $DIR/$tfile || error "touch $tfile failed"
28215         check_som_nodata $DIR/$tfile
28216
28217         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28218                 error "write $tfile failed"
28219         check_som_nodata $DIR/$tfile
28220
28221         $TRUNCATE $DIR/$tfile 1234
28222         check_som_nodata $DIR/$tfile
28223
28224         $TRUNCATE $DIR/$tfile 4097
28225         check_som_nodata $DIR/$file
28226 }
28227 run_test 809 "Verify no SOM xattr store for DoM-only files"
28228
28229 test_810() {
28230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28231         $GSS && skip_env "could not run with gss"
28232         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28233                 skip "OST < 2.12.58 doesn't align checksum"
28234
28235         set_checksums 1
28236         stack_trap "set_checksums $ORIG_CSUM" EXIT
28237         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28238
28239         local csum
28240         local before
28241         local after
28242         for csum in $CKSUM_TYPES; do
28243                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28244                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28245                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28246                         eval set -- $i
28247                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28248                         before=$(md5sum $DIR/$tfile)
28249                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28250                         after=$(md5sum $DIR/$tfile)
28251                         [ "$before" == "$after" ] ||
28252                                 error "$csum: $before != $after bs=$1 seek=$2"
28253                 done
28254         done
28255 }
28256 run_test 810 "partial page writes on ZFS (LU-11663)"
28257
28258 test_812a() {
28259         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28260                 skip "OST < 2.12.51 doesn't support this fail_loc"
28261
28262         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28263         # ensure ost1 is connected
28264         stat $DIR/$tfile >/dev/null || error "can't stat"
28265         wait_osc_import_state client ost1 FULL
28266         # no locks, no reqs to let the connection idle
28267         cancel_lru_locks osc
28268
28269         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28270 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28271         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28272         wait_osc_import_state client ost1 CONNECTING
28273         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28274
28275         stat $DIR/$tfile >/dev/null || error "can't stat file"
28276 }
28277 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28278
28279 test_812b() { # LU-12378
28280         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28281                 skip "OST < 2.12.51 doesn't support this fail_loc"
28282
28283         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28284         # ensure ost1 is connected
28285         stat $DIR/$tfile >/dev/null || error "can't stat"
28286         wait_osc_import_state client ost1 FULL
28287         # no locks, no reqs to let the connection idle
28288         cancel_lru_locks osc
28289
28290         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28291 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28292         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28293         wait_osc_import_state client ost1 CONNECTING
28294         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28295
28296         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28297         wait_osc_import_state client ost1 IDLE
28298 }
28299 run_test 812b "do not drop no resend request for idle connect"
28300
28301 test_812c() {
28302         local old
28303
28304         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28305
28306         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28307         $LFS getstripe $DIR/$tfile
28308         $LCTL set_param osc.*.idle_timeout=10
28309         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28310         # ensure ost1 is connected
28311         stat $DIR/$tfile >/dev/null || error "can't stat"
28312         wait_osc_import_state client ost1 FULL
28313         # no locks, no reqs to let the connection idle
28314         cancel_lru_locks osc
28315
28316 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28317         $LCTL set_param fail_loc=0x80000533
28318         sleep 15
28319         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28320 }
28321 run_test 812c "idle import vs lock enqueue race"
28322
28323 test_813() {
28324         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28325         [ -z "$file_heat_sav" ] && skip "no file heat support"
28326
28327         local readsample
28328         local writesample
28329         local readbyte
28330         local writebyte
28331         local readsample1
28332         local writesample1
28333         local readbyte1
28334         local writebyte1
28335
28336         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28337         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28338
28339         $LCTL set_param -n llite.*.file_heat=1
28340         echo "Turn on file heat"
28341         echo "Period second: $period_second, Decay percentage: $decay_pct"
28342
28343         echo "QQQQ" > $DIR/$tfile
28344         echo "QQQQ" > $DIR/$tfile
28345         echo "QQQQ" > $DIR/$tfile
28346         cat $DIR/$tfile > /dev/null
28347         cat $DIR/$tfile > /dev/null
28348         cat $DIR/$tfile > /dev/null
28349         cat $DIR/$tfile > /dev/null
28350
28351         local out=$($LFS heat_get $DIR/$tfile)
28352
28353         $LFS heat_get $DIR/$tfile
28354         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28355         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28356         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28357         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28358
28359         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28360         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28361         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28362         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28363
28364         sleep $((period_second + 3))
28365         echo "Sleep $((period_second + 3)) seconds..."
28366         # The recursion formula to calculate the heat of the file f is as
28367         # follow:
28368         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28369         # Where Hi is the heat value in the period between time points i*I and
28370         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28371         # to the weight of Ci.
28372         out=$($LFS heat_get $DIR/$tfile)
28373         $LFS heat_get $DIR/$tfile
28374         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28375         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28376         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28377         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28378
28379         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28380                 error "read sample ($readsample) is wrong"
28381         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28382                 error "write sample ($writesample) is wrong"
28383         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28384                 error "read bytes ($readbyte) is wrong"
28385         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28386                 error "write bytes ($writebyte) is wrong"
28387
28388         echo "QQQQ" > $DIR/$tfile
28389         echo "QQQQ" > $DIR/$tfile
28390         echo "QQQQ" > $DIR/$tfile
28391         cat $DIR/$tfile > /dev/null
28392         cat $DIR/$tfile > /dev/null
28393         cat $DIR/$tfile > /dev/null
28394         cat $DIR/$tfile > /dev/null
28395
28396         sleep $((period_second + 3))
28397         echo "Sleep $((period_second + 3)) seconds..."
28398
28399         out=$($LFS heat_get $DIR/$tfile)
28400         $LFS heat_get $DIR/$tfile
28401         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28402         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28403         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28404         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28405
28406         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28407                 4 * $decay_pct) / 100") -eq 1 ] ||
28408                 error "read sample ($readsample1) is wrong"
28409         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28410                 3 * $decay_pct) / 100") -eq 1 ] ||
28411                 error "write sample ($writesample1) is wrong"
28412         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28413                 20 * $decay_pct) / 100") -eq 1 ] ||
28414                 error "read bytes ($readbyte1) is wrong"
28415         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28416                 15 * $decay_pct) / 100") -eq 1 ] ||
28417                 error "write bytes ($writebyte1) is wrong"
28418
28419         echo "Turn off file heat for the file $DIR/$tfile"
28420         $LFS heat_set -o $DIR/$tfile
28421
28422         echo "QQQQ" > $DIR/$tfile
28423         echo "QQQQ" > $DIR/$tfile
28424         echo "QQQQ" > $DIR/$tfile
28425         cat $DIR/$tfile > /dev/null
28426         cat $DIR/$tfile > /dev/null
28427         cat $DIR/$tfile > /dev/null
28428         cat $DIR/$tfile > /dev/null
28429
28430         out=$($LFS heat_get $DIR/$tfile)
28431         $LFS heat_get $DIR/$tfile
28432         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28433         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28434         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28435         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28436
28437         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28438         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28439         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28440         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28441
28442         echo "Trun on file heat for the file $DIR/$tfile"
28443         $LFS heat_set -O $DIR/$tfile
28444
28445         echo "QQQQ" > $DIR/$tfile
28446         echo "QQQQ" > $DIR/$tfile
28447         echo "QQQQ" > $DIR/$tfile
28448         cat $DIR/$tfile > /dev/null
28449         cat $DIR/$tfile > /dev/null
28450         cat $DIR/$tfile > /dev/null
28451         cat $DIR/$tfile > /dev/null
28452
28453         out=$($LFS heat_get $DIR/$tfile)
28454         $LFS heat_get $DIR/$tfile
28455         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28456         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28457         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28458         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28459
28460         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28461         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28462         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28463         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28464
28465         $LFS heat_set -c $DIR/$tfile
28466         $LCTL set_param -n llite.*.file_heat=0
28467         echo "Turn off file heat support for the Lustre filesystem"
28468
28469         echo "QQQQ" > $DIR/$tfile
28470         echo "QQQQ" > $DIR/$tfile
28471         echo "QQQQ" > $DIR/$tfile
28472         cat $DIR/$tfile > /dev/null
28473         cat $DIR/$tfile > /dev/null
28474         cat $DIR/$tfile > /dev/null
28475         cat $DIR/$tfile > /dev/null
28476
28477         out=$($LFS heat_get $DIR/$tfile)
28478         $LFS heat_get $DIR/$tfile
28479         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28480         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28481         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28482         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28483
28484         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28485         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28486         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28487         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28488
28489         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28490         rm -f $DIR/$tfile
28491 }
28492 run_test 813 "File heat verfication"
28493
28494 test_814()
28495 {
28496         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28497         echo -n y >> $DIR/$tfile
28498         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28499         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28500 }
28501 run_test 814 "sparse cp works as expected (LU-12361)"
28502
28503 test_815()
28504 {
28505         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28506         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28507 }
28508 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28509
28510 test_816() {
28511         local ost1_imp=$(get_osc_import_name client ost1)
28512         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28513                          cut -d'.' -f2)
28514
28515         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28516         # ensure ost1 is connected
28517
28518         stat $DIR/$tfile >/dev/null || error "can't stat"
28519         wait_osc_import_state client ost1 FULL
28520         # no locks, no reqs to let the connection idle
28521         cancel_lru_locks osc
28522         lru_resize_disable osc
28523         local before
28524         local now
28525         before=$($LCTL get_param -n \
28526                  ldlm.namespaces.$imp_name.lru_size)
28527
28528         wait_osc_import_state client ost1 IDLE
28529         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28530         now=$($LCTL get_param -n \
28531               ldlm.namespaces.$imp_name.lru_size)
28532         [ $before == $now ] || error "lru_size changed $before != $now"
28533 }
28534 run_test 816 "do not reset lru_resize on idle reconnect"
28535
28536 cleanup_817() {
28537         umount $tmpdir
28538         exportfs -u localhost:$DIR/nfsexp
28539         rm -rf $DIR/nfsexp
28540 }
28541
28542 test_817() {
28543         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28544
28545         mkdir -p $DIR/nfsexp
28546         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28547                 error "failed to export nfs"
28548
28549         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28550         stack_trap cleanup_817 EXIT
28551
28552         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28553                 error "failed to mount nfs to $tmpdir"
28554
28555         cp /bin/true $tmpdir
28556         $DIR/nfsexp/true || error "failed to execute 'true' command"
28557 }
28558 run_test 817 "nfsd won't cache write lock for exec file"
28559
28560 test_818() {
28561         test_mkdir -i0 -c1 $DIR/$tdir
28562         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28563         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28564         stop $SINGLEMDS
28565
28566         # restore osp-syn threads
28567         stack_trap "fail $SINGLEMDS"
28568
28569         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28570         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28571         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28572                 error "start $SINGLEMDS failed"
28573         rm -rf $DIR/$tdir
28574
28575         local testid=$(echo $TESTNAME | tr '_' ' ')
28576
28577         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28578                 grep "run LFSCK" || error "run LFSCK is not suggested"
28579 }
28580 run_test 818 "unlink with failed llog"
28581
28582 test_819a() {
28583         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28584         cancel_lru_locks osc
28585         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28586         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28587         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28588         rm -f $TDIR/$tfile
28589 }
28590 run_test 819a "too big niobuf in read"
28591
28592 test_819b() {
28593         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28594         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28595         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28596         cancel_lru_locks osc
28597         sleep 1
28598         rm -f $TDIR/$tfile
28599 }
28600 run_test 819b "too big niobuf in write"
28601
28602
28603 function test_820_start_ost() {
28604         sleep 5
28605
28606         for num in $(seq $OSTCOUNT); do
28607                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28608         done
28609 }
28610
28611 test_820() {
28612         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28613
28614         mkdir $DIR/$tdir
28615         umount_client $MOUNT || error "umount failed"
28616         for num in $(seq $OSTCOUNT); do
28617                 stop ost$num
28618         done
28619
28620         # mount client with no active OSTs
28621         # so that the client can't initialize max LOV EA size
28622         # from OSC notifications
28623         mount_client $MOUNT || error "mount failed"
28624         # delay OST starting to keep this 0 max EA size for a while
28625         test_820_start_ost &
28626
28627         # create a directory on MDS2
28628         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28629                 error "Failed to create directory"
28630         # open intent should update default EA size
28631         # see mdc_update_max_ea_from_body()
28632         # notice this is the very first RPC to MDS2
28633         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28634         ret=$?
28635         echo $out
28636         # With SSK, this situation can lead to -EPERM being returned.
28637         # In that case, simply retry.
28638         if [ $ret -ne 0 ] && $SHARED_KEY; then
28639                 if echo "$out" | grep -q "not permitted"; then
28640                         cp /etc/services $DIR/$tdir/mds2
28641                         ret=$?
28642                 fi
28643         fi
28644         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28645 }
28646 run_test 820 "update max EA from open intent"
28647
28648 test_823() {
28649         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28650         local OST_MAX_PRECREATE=20000
28651
28652         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28653                 skip "Need MDS version at least 2.14.56"
28654
28655         save_lustre_params mds1 \
28656                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28657         do_facet $SINGLEMDS "$LCTL set_param -n \
28658                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28659         do_facet $SINGLEMDS "$LCTL set_param -n \
28660                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28661
28662         stack_trap "restore_lustre_params < $p; rm $p"
28663
28664         do_facet $SINGLEMDS "$LCTL set_param -n \
28665                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28666
28667         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28668                       osp.$FSNAME-OST0000*MDT0000.create_count")
28669         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28670                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28671         local expect_count=$(((($max/2)/256) * 256))
28672
28673         log "setting create_count to 100200:"
28674         log " -result- count: $count with max: $max, expecting: $expect_count"
28675
28676         [[ $count -eq expect_count ]] ||
28677                 error "Create count not set to max precreate."
28678 }
28679 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28680
28681 test_831() {
28682         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28683                 skip "Need MDS version 2.14.56"
28684
28685         local sync_changes=$(do_facet $SINGLEMDS \
28686                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28687
28688         [ "$sync_changes" -gt 100 ] &&
28689                 skip "Sync changes $sync_changes > 100 already"
28690
28691         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28692
28693         $LFS mkdir -i 0 $DIR/$tdir
28694         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28695
28696         save_lustre_params mds1 \
28697                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28698         save_lustre_params mds1 \
28699                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28700
28701         do_facet mds1 "$LCTL set_param -n \
28702                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28703                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28704         stack_trap "restore_lustre_params < $p" EXIT
28705
28706         createmany -o $DIR/$tdir/f- 1000
28707         unlinkmany $DIR/$tdir/f- 1000 &
28708         local UNLINK_PID=$!
28709
28710         while sleep 1; do
28711                 sync_changes=$(do_facet mds1 \
28712                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28713                 # the check in the code is racy, fail the test
28714                 # if the value above the limit by 10.
28715                 [ $sync_changes -gt 110 ] && {
28716                         kill -2 $UNLINK_PID
28717                         wait
28718                         error "osp changes throttling failed, $sync_changes>110"
28719                 }
28720                 kill -0 $UNLINK_PID 2> /dev/null || break
28721         done
28722         wait
28723 }
28724 run_test 831 "throttling unlink/setattr queuing on OSP"
28725
28726 #
28727 # tests that do cleanup/setup should be run at the end
28728 #
28729
28730 test_900() {
28731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28732         local ls
28733
28734         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28735         $LCTL set_param fail_loc=0x903
28736
28737         cancel_lru_locks MGC
28738
28739         FAIL_ON_ERROR=true cleanup
28740         FAIL_ON_ERROR=true setup
28741 }
28742 run_test 900 "umount should not race with any mgc requeue thread"
28743
28744 # LUS-6253/LU-11185
28745 test_901() {
28746         local old
28747         local count
28748         local oldc
28749         local newc
28750         local olds
28751         local news
28752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28753
28754         # some get_param have a bug to handle dot in param name
28755         cancel_lru_locks MGC
28756         old=$(mount -t lustre | wc -l)
28757         # 1 config+sptlrpc
28758         # 2 params
28759         # 3 nodemap
28760         # 4 IR
28761         old=$((old * 4))
28762         oldc=0
28763         count=0
28764         while [ $old -ne $oldc ]; do
28765                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28766                 sleep 1
28767                 ((count++))
28768                 if [ $count -ge $TIMEOUT ]; then
28769                         error "too large timeout"
28770                 fi
28771         done
28772         umount_client $MOUNT || error "umount failed"
28773         mount_client $MOUNT || error "mount failed"
28774         cancel_lru_locks MGC
28775         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28776
28777         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28778
28779         return 0
28780 }
28781 run_test 901 "don't leak a mgc lock on client umount"
28782
28783 # LU-13377
28784 test_902() {
28785         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28786                 skip "client does not have LU-13377 fix"
28787         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28788         $LCTL set_param fail_loc=0x1415
28789         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28790         cancel_lru_locks osc
28791         rm -f $DIR/$tfile
28792 }
28793 run_test 902 "test short write doesn't hang lustre"
28794
28795 # LU-14711
28796 test_903() {
28797         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28798         echo "blah" > $DIR/${tfile}-2
28799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28800         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28801         $LCTL set_param fail_loc=0x417 fail_val=20
28802
28803         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28804         sleep 1 # To start the destroy
28805         wait_destroy_complete 150 || error "Destroy taking too long"
28806         cat $DIR/$tfile > /dev/null || error "Evicted"
28807 }
28808 run_test 903 "Test long page discard does not cause evictions"
28809
28810 test_904() {
28811         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28812         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28813                 grep -q project || skip "skip project quota not supported"
28814
28815         local testfile="$DIR/$tdir/$tfile"
28816         local xattr="trusted.projid"
28817         local projid
28818         local mdts=$(comma_list $(mdts_nodes))
28819         local saved=$(do_facet mds1 $LCTL get_param -n \
28820                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28821
28822         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28823         stack_trap "do_nodes $mdts $LCTL set_param \
28824                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28825
28826         mkdir -p $DIR/$tdir
28827         touch $testfile
28828         #hide projid xattr on server
28829         $LFS project -p 1 $testfile ||
28830                 error "set $testfile project id failed"
28831         getfattr -m - $testfile | grep $xattr &&
28832                 error "do not show trusted.projid when disabled on server"
28833         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28834         #should be hidden when projid is 0
28835         $LFS project -p 0 $testfile ||
28836                 error "set $testfile project id failed"
28837         getfattr -m - $testfile | grep $xattr &&
28838                 error "do not show trusted.projid with project ID 0"
28839
28840         #still can getxattr explicitly
28841         projid=$(getfattr -n $xattr $testfile |
28842                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28843         [ $projid == "0" ] ||
28844                 error "projid expected 0 not $projid"
28845
28846         #set the projid via setxattr
28847         setfattr -n $xattr -v "1000" $testfile ||
28848                 error "setattr failed with $?"
28849         projid=($($LFS project $testfile))
28850         [ ${projid[0]} == "1000" ] ||
28851                 error "projid expected 1000 not $projid"
28852
28853         #check the new projid via getxattr
28854         $LFS project -p 1001 $testfile ||
28855                 error "set $testfile project id failed"
28856         getfattr -m - $testfile | grep $xattr ||
28857                 error "should show trusted.projid when project ID != 0"
28858         projid=$(getfattr -n $xattr $testfile |
28859                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28860         [ $projid == "1001" ] ||
28861                 error "projid expected 1001 not $projid"
28862
28863         #try to set invalid projid
28864         setfattr -n $xattr -v "4294967295" $testfile &&
28865                 error "set invalid projid should fail"
28866
28867         #remove the xattr means setting projid to 0
28868         setfattr -x $xattr $testfile ||
28869                 error "setfattr failed with $?"
28870         projid=($($LFS project $testfile))
28871         [ ${projid[0]} == "0" ] ||
28872                 error "projid expected 0 not $projid"
28873
28874         #should be hidden when parent has inherit flag and same projid
28875         $LFS project -srp 1002 $DIR/$tdir ||
28876                 error "set $tdir project id failed"
28877         getfattr -m - $testfile | grep $xattr &&
28878                 error "do not show trusted.projid with inherit flag"
28879
28880         #still can getxattr explicitly
28881         projid=$(getfattr -n $xattr $testfile |
28882                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28883         [ $projid == "1002" ] ||
28884                 error "projid expected 1002 not $projid"
28885 }
28886 run_test 904 "virtual project ID xattr"
28887
28888 # LU-8582
28889 test_905() {
28890         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28891                 skip "lustre < 2.8.54 does not support ladvise"
28892
28893         remote_ost_nodsh && skip "remote OST with nodsh"
28894         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28895
28896         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28897
28898         #define OBD_FAIL_OST_OPCODE 0x253
28899         # OST_LADVISE = 21
28900         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28901         $LFS ladvise -a willread $DIR/$tfile &&
28902                 error "unexpected success of ladvise with fault injection"
28903         $LFS ladvise -a willread $DIR/$tfile |&
28904                 grep -q "Operation not supported"
28905         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28906 }
28907 run_test 905 "bad or new opcode should not stuck client"
28908
28909 test_906() {
28910         grep -q io_uring_setup /proc/kallsyms ||
28911                 skip "Client OS does not support io_uring I/O engine"
28912         io_uring_probe || skip "kernel does not support io_uring fully"
28913         which fio || skip_env "no fio installed"
28914         fio --enghelp | grep -q io_uring ||
28915                 skip_env "fio does not support io_uring I/O engine"
28916
28917         local file=$DIR/$tfile
28918         local ioengine="io_uring"
28919         local numjobs=2
28920         local size=50M
28921
28922         fio --name=seqwrite --ioengine=$ioengine        \
28923                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28924                 --iodepth=64 --size=$size --filename=$file --rw=write ||
28925                 error "fio seqwrite $file failed"
28926
28927         fio --name=seqread --ioengine=$ioengine \
28928                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
28929                 --iodepth=64 --size=$size --filename=$file --rw=read ||
28930                 error "fio seqread $file failed"
28931
28932         rm -f $file || error "rm -f $file failed"
28933 }
28934 run_test 906 "Simple test for io_uring I/O engine via fio"
28935
28936 complete $SECONDS
28937 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28938 check_and_cleanup_lustre
28939 if [ "$I_MOUNTED" != "yes" ]; then
28940         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28941 fi
28942 exit_status