Whamcloud - gitweb
LU-14067 tests: re-enable gcc compile test for PPC + ARM
[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 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
67 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
68         always_except LU-15259 103a 125 154a
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
73
74 if [ "$mds1_FSTYPE" = "zfs" ]; then
75         #                                               13    (min)"
76         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [ "$ost1_FSTYPE" = "zfs" ]; then
80         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 always_except LU-4341 170
104
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 always_except LU-3703 234
107 elif [ -r /etc/os-release ]; then
108         if grep -qi ubuntu /etc/os-release; then
109                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
110                                                 -e 's/^VERSION=//p' \
111                                                 /etc/os-release |
112                                                 awk '{ print $1 }'))
113
114                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
115                         always_except LU-10334 103a
116                         always_except LU-10366 410
117                 fi
118         fi
119 fi
120
121 build_test_filter
122 FAIL_ON_ERROR=false
123
124 cleanup() {
125         echo -n "cln.."
126         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
127         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
128 }
129 setup() {
130         echo -n "mnt.."
131         load_modules
132         setupall || exit 10
133         echo "done"
134 }
135
136 check_swap_layouts_support()
137 {
138         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
139                 skip "Does not support layout lock."
140 }
141
142 check_swap_layout_no_dom()
143 {
144         local FOLDER=$1
145         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
146         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
147 }
148
149 check_and_setup_lustre
150 DIR=${DIR:-$MOUNT}
151 assert_DIR
152
153 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
154
155 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
156 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
157 rm -rf $DIR/[Rdfs][0-9]*
158
159 # $RUNAS_ID may get set incorrectly somewhere else
160 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
161         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
162
163 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
164
165 if [ "${ONLY}" = "MOUNT" ] ; then
166         echo "Lustre is up, please go on"
167         exit
168 fi
169
170 echo "preparing for tests involving mounts"
171 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
172 touch $EXT2_DEV
173 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
174 echo # add a newline after mke2fs.
175
176 umask 077
177
178 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
179 lctl set_param debug=-1 2> /dev/null || true
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_1() {
272         test_mkdir $DIR/$tdir
273         test_mkdir $DIR/$tdir/d2
274         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
275         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
276         rmdir $DIR/$tdir/d2
277         rmdir $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
279 }
280 run_test 1 "mkdir; remkdir; rmdir"
281
282 test_2() {
283         test_mkdir $DIR/$tdir
284         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
285         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
286         rm -r $DIR/$tdir
287         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
288 }
289 run_test 2 "mkdir; touch; rmdir; check file"
290
291 test_3() {
292         test_mkdir $DIR/$tdir
293         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
294         touch $DIR/$tdir/$tfile
295         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
296         rm -r $DIR/$tdir
297         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
298 }
299 run_test 3 "mkdir; touch; rmdir; check dir"
300
301 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
302 test_4() {
303         test_mkdir -i 1 $DIR/$tdir
304
305         touch $DIR/$tdir/$tfile ||
306                 error "Create file under remote directory failed"
307
308         rmdir $DIR/$tdir &&
309                 error "Expect error removing in-use dir $DIR/$tdir"
310
311         test -d $DIR/$tdir || error "Remote directory disappeared"
312
313         rm -rf $DIR/$tdir || error "remove remote dir error"
314 }
315 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
316
317 test_5() {
318         test_mkdir $DIR/$tdir
319         test_mkdir $DIR/$tdir/d2
320         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
321         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
322         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
323 }
324 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
325
326 test_6a() {
327         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
328         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
329         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
330                 error "$tfile does not have perm 0666 or UID $UID"
331         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile should be 0666 and owned by UID $UID"
334 }
335 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
336
337 test_6c() {
338         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
339
340         touch $DIR/$tfile
341         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
342         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
343                 error "$tfile should be owned by UID $RUNAS_ID"
344         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347 }
348 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
349
350 test_6e() {
351         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
352
353         touch $DIR/$tfile
354         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
355         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
356                 error "$tfile should be owned by GID $UID"
357         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
360 }
361 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
362
363 test_6g() {
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         test_mkdir $DIR/$tdir
367         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
368         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
369         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
370         test_mkdir $DIR/$tdir/d/subdir
371         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
372                 error "$tdir/d/subdir should be GID $RUNAS_GID"
373         if [[ $MDSCOUNT -gt 1 ]]; then
374                 # check remote dir sgid inherite
375                 $LFS mkdir -i 0 $DIR/$tdir.local ||
376                         error "mkdir $tdir.local failed"
377                 chmod g+s $DIR/$tdir.local ||
378                         error "chmod $tdir.local failed"
379                 chgrp $RUNAS_GID $DIR/$tdir.local ||
380                         error "chgrp $tdir.local failed"
381                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
382                         error "mkdir $tdir.remote failed"
383                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
385                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be mode 02755"
387         fi
388 }
389 run_test 6g "verify new dir in sgid dir inherits group"
390
391 test_6h() { # bug 7331
392         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
393
394         touch $DIR/$tfile || error "touch failed"
395         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
396         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
397                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
398         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
399                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
400 }
401 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
402
403 test_7a() {
404         test_mkdir $DIR/$tdir
405         $MCREATE $DIR/$tdir/$tfile
406         chmod 0666 $DIR/$tdir/$tfile
407         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
408                 error "$tdir/$tfile should be mode 0666"
409 }
410 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
411
412 test_7b() {
413         if [ ! -d $DIR/$tdir ]; then
414                 test_mkdir $DIR/$tdir
415         fi
416         $MCREATE $DIR/$tdir/$tfile
417         echo -n foo > $DIR/$tdir/$tfile
418         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
419         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
420 }
421 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
422
423 test_8() {
424         test_mkdir $DIR/$tdir
425         touch $DIR/$tdir/$tfile
426         chmod 0666 $DIR/$tdir/$tfile
427         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
428                 error "$tfile mode not 0666"
429 }
430 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
431
432 test_9() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         test_mkdir $DIR/$tdir/d2/d3
436         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
437 }
438 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
439
440 test_10() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         touch $DIR/$tdir/d2/$tfile
444         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
445                 error "$tdir/d2/$tfile not a file"
446 }
447 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
448
449 test_11() {
450         test_mkdir $DIR/$tdir
451         test_mkdir $DIR/$tdir/d2
452         chmod 0666 $DIR/$tdir/d2
453         chmod 0705 $DIR/$tdir/d2
454         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
455                 error "$tdir/d2 mode not 0705"
456 }
457 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
458
459 test_12() {
460         test_mkdir $DIR/$tdir
461         touch $DIR/$tdir/$tfile
462         chmod 0666 $DIR/$tdir/$tfile
463         chmod 0654 $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
465                 error "$tdir/d2 mode not 0654"
466 }
467 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
468
469 test_13() {
470         test_mkdir $DIR/$tdir
471         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
472         >  $DIR/$tdir/$tfile
473         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
474                 error "$tdir/$tfile size not 0 after truncate"
475 }
476 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
477
478 test_14() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         rm $DIR/$tdir/$tfile
482         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
483 }
484 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
485
486 test_15() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
490         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
491                 error "$tdir/${tfile_2} not a file after rename"
492         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
493 }
494 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
495
496 test_16() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         rm -rf $DIR/$tdir/$tfile
500         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
501 }
502 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
503
504 test_17a() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
508         ls -l $DIR/$tdir
509         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not a symlink"
511         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not referencing a file"
513         rm -f $DIR/$tdir/l-exist
514         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
515 }
516 run_test 17a "symlinks: create, remove (real)"
517
518 test_17b() {
519         test_mkdir $DIR/$tdir
520         ln -s no-such-file $DIR/$tdir/l-dangle
521         ls -l $DIR/$tdir
522         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing no-such-file"
524         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing non-existent file"
526         rm -f $DIR/$tdir/l-dangle
527         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
528 }
529 run_test 17b "symlinks: create, remove (dangling)"
530
531 test_17c() { # bug 3440 - don't save failed open RPC for replay
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
535 }
536 run_test 17c "symlinks: open dangling (should return error)"
537
538 test_17d() {
539         test_mkdir $DIR/$tdir
540         ln -s foo $DIR/$tdir/$tfile
541         touch $DIR/$tdir/$tfile || error "creating to new symlink"
542 }
543 run_test 17d "symlinks: create dangling"
544
545 test_17e() {
546         test_mkdir $DIR/$tdir
547         local foo=$DIR/$tdir/$tfile
548         ln -s $foo $foo || error "create symlink failed"
549         ls -l $foo || error "ls -l failed"
550         ls $foo && error "ls not failed" || true
551 }
552 run_test 17e "symlinks: create recursive symlink (should return error)"
553
554 test_17f() {
555         test_mkdir $DIR/$tdir
556         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
561         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
562         ls -l  $DIR/$tdir
563 }
564 run_test 17f "symlinks: long and very long symlink name"
565
566 # str_repeat(S, N) generate a string that is string S repeated N times
567 str_repeat() {
568         local s=$1
569         local n=$2
570         local ret=''
571         while [ $((n -= 1)) -ge 0 ]; do
572                 ret=$ret$s
573         done
574         echo $ret
575 }
576
577 # Long symlinks and LU-2241
578 test_17g() {
579         test_mkdir $DIR/$tdir
580         local TESTS="59 60 61 4094 4095"
581
582         # Fix for inode size boundary in 2.1.4
583         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
584                 TESTS="4094 4095"
585
586         # Patch not applied to 2.2 or 2.3 branches
587         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
588         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
589                 TESTS="4094 4095"
590
591         for i in $TESTS; do
592                 local SYMNAME=$(str_repeat 'x' $i)
593                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
594                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
595         done
596 }
597 run_test 17g "symlinks: really long symlink name and inode boundaries"
598
599 test_17h() { #bug 17378
600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
601         remote_mds_nodsh && skip "remote MDS with nodsh"
602
603         local mdt_idx
604
605         test_mkdir $DIR/$tdir
606         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
607         $LFS setstripe -c -1 $DIR/$tdir
608         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
609         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
610         touch $DIR/$tdir/$tfile || true
611 }
612 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
613
614 test_17i() { #bug 20018
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         remote_mds_nodsh && skip "remote MDS with nodsh"
617
618         local foo=$DIR/$tdir/$tfile
619         local mdt_idx
620
621         test_mkdir -c1 $DIR/$tdir
622         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
623         ln -s $foo $foo || error "create symlink failed"
624 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
625         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
626         ls -l $foo && error "error not detected"
627         return 0
628 }
629 run_test 17i "don't panic on short symlink (should return error)"
630
631 test_17k() { #bug 22301
632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
633         [[ -z "$(which rsync 2>/dev/null)" ]] &&
634                 skip "no rsync command"
635         rsync --help | grep -q xattr ||
636                 skip_env "$(rsync --version | head -n1) does not support xattrs"
637         test_mkdir $DIR/$tdir
638         test_mkdir $DIR/$tdir.new
639         touch $DIR/$tdir/$tfile
640         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
641         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
642                 error "rsync failed with xattrs enabled"
643 }
644 run_test 17k "symlinks: rsync with xattrs enabled"
645
646 test_17l() { # LU-279
647         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
648                 skip "no getfattr command"
649
650         test_mkdir $DIR/$tdir
651         touch $DIR/$tdir/$tfile
652         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
653         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
654                 # -h to not follow symlinks. -m '' to list all the xattrs.
655                 # grep to remove first line: '# file: $path'.
656                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
657                 do
658                         lgetxattr_size_check $path $xattr ||
659                                 error "lgetxattr_size_check $path $xattr failed"
660                 done
661         done
662 }
663 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
664
665 # LU-1540
666 test_17m() {
667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
669         remote_mds_nodsh && skip "remote MDS with nodsh"
670         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
671         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
672                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
673
674         local short_sym="0123456789"
675         local wdir=$DIR/$tdir
676         local i
677
678         test_mkdir $wdir
679         long_sym=$short_sym
680         # create a long symlink file
681         for ((i = 0; i < 4; ++i)); do
682                 long_sym=${long_sym}${long_sym}
683         done
684
685         echo "create 512 short and long symlink files under $wdir"
686         for ((i = 0; i < 256; ++i)); do
687                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
688                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
689         done
690
691         echo "erase them"
692         rm -f $wdir/*
693         sync
694         wait_delete_completed
695
696         echo "recreate the 512 symlink files with a shorter string"
697         for ((i = 0; i < 512; ++i)); do
698                 # rewrite the symlink file with a shorter string
699                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
700                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
701         done
702
703         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
704
705         echo "stop and checking mds${mds_index}:"
706         # e2fsck should not return error
707         stop mds${mds_index}
708         local devname=$(mdsdevname $mds_index)
709         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
710         rc=$?
711
712         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
713                 error "start mds${mds_index} failed"
714         df $MOUNT > /dev/null 2>&1
715         [ $rc -eq 0 ] ||
716                 error "e2fsck detected error for short/long symlink: rc=$rc"
717         rm -f $wdir/*
718 }
719 run_test 17m "run e2fsck against MDT which contains short/long symlink"
720
721 check_fs_consistency_17n() {
722         local mdt_index
723         local rc=0
724
725         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
726         # so it only check MDT1/MDT2 instead of all of MDTs.
727         for mdt_index in 1 2; do
728                 # e2fsck should not return error
729                 stop mds${mdt_index}
730                 local devname=$(mdsdevname $mdt_index)
731                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
732                         rc=$((rc + $?))
733
734                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
735                         error "mount mds$mdt_index failed"
736                 df $MOUNT > /dev/null 2>&1
737         done
738         return $rc
739 }
740
741 test_17n() {
742         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
744         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
745         remote_mds_nodsh && skip "remote MDS with nodsh"
746         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
747         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
748                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
749
750         local i
751
752         test_mkdir $DIR/$tdir
753         for ((i=0; i<10; i++)); do
754                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
755                         error "create remote dir error $i"
756                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
757                         error "create files under remote dir failed $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after create files under remote dir"
762
763         for ((i = 0; i < 10; i++)); do
764                 rm -rf $DIR/$tdir/remote_dir_${i} ||
765                         error "destroy remote dir error $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after unlink files under remote dir"
770
771         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
772                 skip "lustre < 2.4.50 does not support migrate mv"
773
774         for ((i = 0; i < 10; i++)); do
775                 mkdir -p $DIR/$tdir/remote_dir_${i}
776                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
777                         error "create files under remote dir failed $i"
778                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
779                         error "migrate remote dir error $i"
780         done
781         check_fs_consistency_17n || error "e2fsck report error after migration"
782
783         for ((i = 0; i < 10; i++)); do
784                 rm -rf $DIR/$tdir/remote_dir_${i} ||
785                         error "destroy remote dir error $i"
786         done
787
788         check_fs_consistency_17n || error "e2fsck report error after unlink"
789 }
790 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
791
792 test_17o() {
793         remote_mds_nodsh && skip "remote MDS with nodsh"
794         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
795                 skip "Need MDS version at least 2.3.64"
796
797         local wdir=$DIR/${tdir}o
798         local mdt_index
799         local rc=0
800
801         test_mkdir $wdir
802         touch $wdir/$tfile
803         mdt_index=$($LFS getstripe -m $wdir/$tfile)
804         mdt_index=$((mdt_index + 1))
805
806         cancel_lru_locks mdc
807         #fail mds will wait the failover finish then set
808         #following fail_loc to avoid interfer the recovery process.
809         fail mds${mdt_index}
810
811         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
812         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
813         ls -l $wdir/$tfile && rc=1
814         do_facet mds${mdt_index} lctl set_param fail_loc=0
815         [[ $rc -eq 0 ]] || error "stat file should fail"
816 }
817 run_test 17o "stat file with incompat LMA feature"
818
819 test_18() {
820         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
821         ls $DIR || error "Failed to ls $DIR: $?"
822 }
823 run_test 18 "touch .../f ; ls ... =============================="
824
825 test_19a() {
826         touch $DIR/$tfile
827         ls -l $DIR
828         rm $DIR/$tfile
829         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
830 }
831 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
832
833 test_19b() {
834         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
835 }
836 run_test 19b "ls -l .../f19 (should return error) =============="
837
838 test_19c() {
839         [ $RUNAS_ID -eq $UID ] &&
840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
841
842         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
843 }
844 run_test 19c "$RUNAS touch .../f19 (should return error) =="
845
846 test_19d() {
847         cat $DIR/f19 && error || true
848 }
849 run_test 19d "cat .../f19 (should return error) =============="
850
851 test_20() {
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
859 }
860 run_test 20 "touch .../f ; ls -l ..."
861
862 test_21() {
863         test_mkdir $DIR/$tdir
864         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
865         ln -s dangle $DIR/$tdir/link
866         echo foo >> $DIR/$tdir/link
867         cat $DIR/$tdir/dangle
868         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
869         $CHECKSTAT -f -t file $DIR/$tdir/link ||
870                 error "$tdir/link not linked to a file"
871 }
872 run_test 21 "write to dangling link"
873
874 test_22() {
875         local wdir=$DIR/$tdir
876         test_mkdir $wdir
877         chown $RUNAS_ID:$RUNAS_GID $wdir
878         (cd $wdir || error "cd $wdir failed";
879                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
880                 $RUNAS tar xf -)
881         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
882         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
883         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
884                 error "checkstat -u failed"
885 }
886 run_test 22 "unpack tar archive as non-root user"
887
888 # was test_23
889 test_23a() {
890         test_mkdir $DIR/$tdir
891         local file=$DIR/$tdir/$tfile
892
893         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
894         openfile -f O_CREAT:O_EXCL $file &&
895                 error "$file recreate succeeded" || true
896 }
897 run_test 23a "O_CREAT|O_EXCL in subdir"
898
899 test_23b() { # bug 18988
900         test_mkdir $DIR/$tdir
901         local file=$DIR/$tdir/$tfile
902
903         rm -f $file
904         echo foo > $file || error "write filed"
905         echo bar >> $file || error "append filed"
906         $CHECKSTAT -s 8 $file || error "wrong size"
907         rm $file
908 }
909 run_test 23b "O_APPEND check"
910
911 # LU-9409, size with O_APPEND and tiny writes
912 test_23c() {
913         local file=$DIR/$tfile
914
915         # single dd
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
917         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
918         rm -f $file
919
920         # racing tiny writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         wait
924         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
925         rm -f $file
926
927         #racing tiny & normal writes
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
930         wait
931         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
932         rm -f $file
933
934         #racing tiny & normal writes 2, ugly numbers
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
937         wait
938         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
939         rm -f $file
940 }
941 run_test 23c "O_APPEND size checks for tiny writes"
942
943 # LU-11069 file offset is correct after appending writes
944 test_23d() {
945         local file=$DIR/$tfile
946         local offset
947
948         echo CentaurHauls > $file
949         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
950         if ((offset != 26)); then
951                 error "wrong offset, expected 26, got '$offset'"
952         fi
953 }
954 run_test 23d "file offset is correct after appending writes"
955
956 # rename sanity
957 test_24a() {
958         echo '-- same directory rename'
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.1
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24a "rename file to non-existent target"
965
966 test_24b() {
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.{1,2}
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
971         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
972 }
973 run_test 24b "rename file to existing target"
974
975 test_24c() {
976         test_mkdir $DIR/$tdir
977         test_mkdir $DIR/$tdir/d$testnum.1
978         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
979         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
980         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
981 }
982 run_test 24c "rename directory to non-existent target"
983
984 test_24d() {
985         test_mkdir -c1 $DIR/$tdir
986         test_mkdir -c1 $DIR/$tdir/d$testnum.1
987         test_mkdir -c1 $DIR/$tdir/d$testnum.2
988         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
989         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
990         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
991 }
992 run_test 24d "rename directory to existing target"
993
994 test_24e() {
995         echo '-- cross directory renames --'
996         test_mkdir $DIR/R5a
997         test_mkdir $DIR/R5b
998         touch $DIR/R5a/f
999         mv $DIR/R5a/f $DIR/R5b/g
1000         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1001         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1002 }
1003 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1004
1005 test_24f() {
1006         test_mkdir $DIR/R6a
1007         test_mkdir $DIR/R6b
1008         touch $DIR/R6a/f $DIR/R6b/g
1009         mv $DIR/R6a/f $DIR/R6b/g
1010         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1011         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1012 }
1013 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1014
1015 test_24g() {
1016         test_mkdir $DIR/R7a
1017         test_mkdir $DIR/R7b
1018         test_mkdir $DIR/R7a/d
1019         mv $DIR/R7a/d $DIR/R7b/e
1020         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1021         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1022 }
1023 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1024
1025 test_24h() {
1026         test_mkdir -c1 $DIR/R8a
1027         test_mkdir -c1 $DIR/R8b
1028         test_mkdir -c1 $DIR/R8a/d
1029         test_mkdir -c1 $DIR/R8b/e
1030         mrename $DIR/R8a/d $DIR/R8b/e
1031         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1032         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1033 }
1034 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1035
1036 test_24i() {
1037         echo "-- rename error cases"
1038         test_mkdir $DIR/R9
1039         test_mkdir $DIR/R9/a
1040         touch $DIR/R9/f
1041         mrename $DIR/R9/f $DIR/R9/a
1042         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1043         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1044         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1045 }
1046 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1047
1048 test_24j() {
1049         test_mkdir $DIR/R10
1050         mrename $DIR/R10/f $DIR/R10/g
1051         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1052         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1053         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1054 }
1055 run_test 24j "source does not exist ============================"
1056
1057 test_24k() {
1058         test_mkdir $DIR/R11a
1059         test_mkdir $DIR/R11a/d
1060         touch $DIR/R11a/f
1061         mv $DIR/R11a/f $DIR/R11a/d
1062         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1063         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1064 }
1065 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1066
1067 # bug 2429 - rename foo foo foo creates invalid file
1068 test_24l() {
1069         f="$DIR/f24l"
1070         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1071 }
1072 run_test 24l "Renaming a file to itself ========================"
1073
1074 test_24m() {
1075         f="$DIR/f24m"
1076         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1077         # on ext3 this does not remove either the source or target files
1078         # though the "expected" operation would be to remove the source
1079         $CHECKSTAT -t file ${f} || error "${f} missing"
1080         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1081 }
1082 run_test 24m "Renaming a file to a hard link to itself ========="
1083
1084 test_24n() {
1085     f="$DIR/f24n"
1086     # this stats the old file after it was renamed, so it should fail
1087     touch ${f}
1088     $CHECKSTAT ${f} || error "${f} missing"
1089     mv ${f} ${f}.rename
1090     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1091     $CHECKSTAT -a ${f} || error "${f} exists"
1092 }
1093 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1094
1095 test_24o() {
1096         test_mkdir $DIR/$tdir
1097         rename_many -s random -v -n 10 $DIR/$tdir
1098 }
1099 run_test 24o "rename of files during htree split"
1100
1101 test_24p() {
1102         test_mkdir $DIR/R12a
1103         test_mkdir $DIR/R12b
1104         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1105         mrename $DIR/R12a $DIR/R12b
1106         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1107         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1108         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1110 }
1111 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1112
1113 cleanup_multiop_pause() {
1114         trap 0
1115         kill -USR1 $MULTIPID
1116 }
1117
1118 test_24q() {
1119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1120
1121         test_mkdir $DIR/R13a
1122         test_mkdir $DIR/R13b
1123         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1124         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1125         MULTIPID=$!
1126
1127         trap cleanup_multiop_pause EXIT
1128         mrename $DIR/R13a $DIR/R13b
1129         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1130         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1131         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1132         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1133         cleanup_multiop_pause
1134         wait $MULTIPID || error "multiop close failed"
1135 }
1136 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1137
1138 test_24r() { #bug 3789
1139         test_mkdir $DIR/R14a
1140         test_mkdir $DIR/R14a/b
1141         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1142         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1143         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1144 }
1145 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1146
1147 test_24s() {
1148         test_mkdir $DIR/R15a
1149         test_mkdir $DIR/R15a/b
1150         test_mkdir $DIR/R15a/b/c
1151         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1152         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1153         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1154 }
1155 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1156 test_24t() {
1157         test_mkdir $DIR/R16a
1158         test_mkdir $DIR/R16a/b
1159         test_mkdir $DIR/R16a/b/c
1160         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1161         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1162         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1163 }
1164 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1165
1166 test_24u() { # bug12192
1167         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1168         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1169 }
1170 run_test 24u "create stripe file"
1171
1172 simple_cleanup_common() {
1173         local createmany=$1
1174         local rc=0
1175
1176         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1177
1178         local start=$SECONDS
1179
1180         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1181         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1182         rc=$?
1183         wait_delete_completed
1184         echo "cleanup time $((SECONDS - start))"
1185         return $rc
1186 }
1187
1188 max_pages_per_rpc() {
1189         local mdtname="$(printf "MDT%04x" ${1:-0})"
1190         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1191 }
1192
1193 test_24v() {
1194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1195
1196         local nrfiles=${COUNT:-100000}
1197         local fname="$DIR/$tdir/$tfile"
1198
1199         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1200         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1201
1202         test_mkdir "$(dirname $fname)"
1203         # assume MDT0000 has the fewest inodes
1204         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1205         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1206         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1207
1208         stack_trap "simple_cleanup_common $nrfiles"
1209
1210         createmany -m "$fname" $nrfiles
1211
1212         cancel_lru_locks mdc
1213         lctl set_param mdc.*.stats clear
1214
1215         # was previously test_24D: LU-6101
1216         # readdir() returns correct number of entries after cursor reload
1217         local num_ls=$(ls $DIR/$tdir | wc -l)
1218         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1219         local num_all=$(ls -a $DIR/$tdir | wc -l)
1220         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1221                 [ $num_all -ne $((nrfiles + 2)) ]; then
1222                         error "Expected $nrfiles files, got $num_ls " \
1223                                 "($num_uniq unique $num_all .&..)"
1224         fi
1225         # LU-5 large readdir
1226         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1227         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1228         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1229         # take into account of overhead in lu_dirpage header and end mark in
1230         # each page, plus one in rpc_num calculation.
1231         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1232         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1233         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1234         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1235         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1236         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1237         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1238         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1239                 error "large readdir doesn't take effect: " \
1240                       "$mds_readpage should be about $rpc_max"
1241 }
1242 run_test 24v "list large directory (test hash collision, b=17560)"
1243
1244 test_24w() { # bug21506
1245         SZ1=234852
1246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1247         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1248         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1249         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1250         [[ "$SZ1" -eq "$SZ2" ]] ||
1251                 error "Error reading at the end of the file $tfile"
1252 }
1253 run_test 24w "Reading a file larger than 4Gb"
1254
1255 test_24x() {
1256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1258         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1259                 skip "Need MDS version at least 2.7.56"
1260
1261         local MDTIDX=1
1262         local remote_dir=$DIR/$tdir/remote_dir
1263
1264         test_mkdir $DIR/$tdir
1265         $LFS mkdir -i $MDTIDX $remote_dir ||
1266                 error "create remote directory failed"
1267
1268         test_mkdir $DIR/$tdir/src_dir
1269         touch $DIR/$tdir/src_file
1270         test_mkdir $remote_dir/tgt_dir
1271         touch $remote_dir/tgt_file
1272
1273         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1274                 error "rename dir cross MDT failed!"
1275
1276         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1277                 error "rename file cross MDT failed!"
1278
1279         touch $DIR/$tdir/ln_file
1280         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1281                 error "ln file cross MDT failed"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24x "cross MDT rename/link"
1286
1287 test_24y() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1290
1291         local remote_dir=$DIR/$tdir/remote_dir
1292         local mdtidx=1
1293
1294         test_mkdir $DIR/$tdir
1295         $LFS mkdir -i $mdtidx $remote_dir ||
1296                 error "create remote directory failed"
1297
1298         test_mkdir $remote_dir/src_dir
1299         touch $remote_dir/src_file
1300         test_mkdir $remote_dir/tgt_dir
1301         touch $remote_dir/tgt_file
1302
1303         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1304                 error "rename subdir in the same remote dir failed!"
1305
1306         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1307                 error "rename files in the same remote dir failed!"
1308
1309         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1310                 error "link files in the same remote dir failed!"
1311
1312         rm -rf $DIR/$tdir || error "Can not delete directories"
1313 }
1314 run_test 24y "rename/link on the same dir should succeed"
1315
1316 test_24z() {
1317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1318         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1319                 skip "Need MDS version at least 2.12.51"
1320
1321         local index
1322
1323         for index in 0 1; do
1324                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1325                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1326         done
1327
1328         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1329
1330         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1331         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1332
1333         local mdts=$(comma_list $(mdts_nodes))
1334
1335         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1336         stack_trap "do_nodes $mdts $LCTL \
1337                 set_param mdt.*.enable_remote_rename=1" EXIT
1338
1339         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1340
1341         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1342         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1343 }
1344 run_test 24z "cross-MDT rename is done as cp"
1345
1346 test_24A() { # LU-3182
1347         local NFILES=5000
1348
1349         test_mkdir $DIR/$tdir
1350         stack_trap "simple_cleanup_common $NFILES"
1351         createmany -m $DIR/$tdir/$tfile $NFILES
1352         local t=$(ls $DIR/$tdir | wc -l)
1353         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1354         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1355
1356         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1357                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1358 }
1359 run_test 24A "readdir() returns correct number of entries."
1360
1361 test_24B() { # LU-4805
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         local count
1365
1366         test_mkdir $DIR/$tdir
1367         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1368                 error "create striped dir failed"
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 2 ] || error "Expected 2, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/a
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 3 ] || error "Expected 3, got $count"
1377
1378         touch $DIR/$tdir/striped_dir/.f
1379
1380         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1381         [ $count -eq 4 ] || error "Expected 4, got $count"
1382
1383         rm -rf $DIR/$tdir || error "Can not delete directories"
1384 }
1385 run_test 24B "readdir for striped dir return correct number of entries"
1386
1387 test_24C() {
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         mkdir $DIR/$tdir
1391         mkdir $DIR/$tdir/d0
1392         mkdir $DIR/$tdir/d1
1393
1394         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1395                 error "create striped dir failed"
1396
1397         cd $DIR/$tdir/d0/striped_dir
1398
1399         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1400         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1401         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d0_ino" = "$parent_ino" ] ||
1404                 error ".. wrong, expect $d0_ino, get $parent_ino"
1405
1406         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1407                 error "mv striped dir failed"
1408
1409         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1410
1411         [ "$d1_ino" = "$parent_ino" ] ||
1412                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1413 }
1414 run_test 24C "check .. in striped dir"
1415
1416 test_24E() {
1417         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1419
1420         mkdir -p $DIR/$tdir
1421         mkdir $DIR/$tdir/src_dir
1422         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1423                 error "create remote source failed"
1424
1425         touch $DIR/$tdir/src_dir/src_child/a
1426
1427         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1428                 error "create remote target dir failed"
1429
1430         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1431                 error "create remote target child failed"
1432
1433         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1434                 error "rename dir cross MDT failed!"
1435
1436         find $DIR/$tdir
1437
1438         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1439                 error "src_child still exists after rename"
1440
1441         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1442                 error "missing file(a) after rename"
1443
1444         rm -rf $DIR/$tdir || error "Can not delete directories"
1445 }
1446 run_test 24E "cross MDT rename/link"
1447
1448 test_24F () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1450
1451         local repeats=1000
1452         [ "$SLOW" = "no" ] && repeats=100
1453
1454         mkdir -p $DIR/$tdir
1455
1456         echo "$repeats repeats"
1457         for ((i = 0; i < repeats; i++)); do
1458                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1459                 touch $DIR/$tdir/test/a || error "touch fails"
1460                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1461                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1462         done
1463
1464         true
1465 }
1466 run_test 24F "hash order vs readdir (LU-11330)"
1467
1468 test_24G () {
1469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1470
1471         local ino1
1472         local ino2
1473
1474         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1475         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1476         touch $DIR/$tdir-0/f1 || error "touch f1"
1477         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1478         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1479         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1480         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1481         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1482 }
1483 run_test 24G "migrate symlink in rename"
1484
1485 test_24H() {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1488                 skip "MDT1 should be on another node"
1489
1490         test_mkdir -i 1 -c 1 $DIR/$tdir
1491 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1492         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1493         touch $DIR/$tdir/$tfile || error "touch failed"
1494 }
1495 run_test 24H "repeat FLD_QUERY rpc"
1496
1497 test_25a() {
1498         echo '== symlink sanity ============================================='
1499
1500         test_mkdir $DIR/d25
1501         ln -s d25 $DIR/s25
1502         touch $DIR/s25/foo ||
1503                 error "File creation in symlinked directory failed"
1504 }
1505 run_test 25a "create file in symlinked directory ==============="
1506
1507 test_25b() {
1508         [ ! -d $DIR/d25 ] && test_25a
1509         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1510 }
1511 run_test 25b "lookup file in symlinked directory ==============="
1512
1513 test_26a() {
1514         test_mkdir $DIR/d26
1515         test_mkdir $DIR/d26/d26-2
1516         ln -s d26/d26-2 $DIR/s26
1517         touch $DIR/s26/foo || error "File creation failed"
1518 }
1519 run_test 26a "multiple component symlink ======================="
1520
1521 test_26b() {
1522         test_mkdir -p $DIR/$tdir/d26-2
1523         ln -s $tdir/d26-2/foo $DIR/s26-2
1524         touch $DIR/s26-2 || error "File creation failed"
1525 }
1526 run_test 26b "multiple component symlink at end of lookup ======"
1527
1528 test_26c() {
1529         test_mkdir $DIR/d26.2
1530         touch $DIR/d26.2/foo
1531         ln -s d26.2 $DIR/s26.2-1
1532         ln -s s26.2-1 $DIR/s26.2-2
1533         ln -s s26.2-2 $DIR/s26.2-3
1534         chmod 0666 $DIR/s26.2-3/foo
1535 }
1536 run_test 26c "chain of symlinks"
1537
1538 # recursive symlinks (bug 439)
1539 test_26d() {
1540         ln -s d26-3/foo $DIR/d26-3
1541 }
1542 run_test 26d "create multiple component recursive symlink"
1543
1544 test_26e() {
1545         [ ! -h $DIR/d26-3 ] && test_26d
1546         rm $DIR/d26-3
1547 }
1548 run_test 26e "unlink multiple component recursive symlink"
1549
1550 # recursive symlinks (bug 7022)
1551 test_26f() {
1552         test_mkdir $DIR/$tdir
1553         test_mkdir $DIR/$tdir/$tfile
1554         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1555         test_mkdir -p lndir/bar1
1556         test_mkdir $DIR/$tdir/$tfile/$tfile
1557         cd $tfile                || error "cd $tfile failed"
1558         ln -s .. dotdot          || error "ln dotdot failed"
1559         ln -s dotdot/lndir lndir || error "ln lndir failed"
1560         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1561         output=`ls $tfile/$tfile/lndir/bar1`
1562         [ "$output" = bar1 ] && error "unexpected output"
1563         rm -r $tfile             || error "rm $tfile failed"
1564         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1565 }
1566 run_test 26f "rm -r of a directory which has recursive symlink"
1567
1568 test_27a() {
1569         test_mkdir $DIR/$tdir
1570         $LFS getstripe $DIR/$tdir
1571         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1572         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1573         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1574 }
1575 run_test 27a "one stripe file"
1576
1577 test_27b() {
1578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1579
1580         test_mkdir $DIR/$tdir
1581         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1582         $LFS getstripe -c $DIR/$tdir/$tfile
1583         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1584                 error "two-stripe file doesn't have two stripes"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1587 }
1588 run_test 27b "create and write to two stripe file"
1589
1590 # 27c family tests specific striping, setstripe -o
1591 test_27ca() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         test_mkdir -p $DIR/$tdir
1594         local osts="1"
1595
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1597         $LFS getstripe -i $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1599                 error "stripe not on specified OST"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1602 }
1603 run_test 27ca "one stripe on specified OST"
1604
1605 test_27cb() {
1606         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1607         test_mkdir -p $DIR/$tdir
1608         local osts="1,0"
1609         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1610         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1611         echo "$getstripe"
1612
1613         # Strip getstripe output to a space separated list of OSTs
1614         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1615                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1616         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1617                 error "stripes not on specified OSTs"
1618
1619         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1620 }
1621 run_test 27cb "two stripes on specified OSTs"
1622
1623 test_27cc() {
1624         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1625         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1626                 skip "server does not support overstriping"
1627
1628         test_mkdir -p $DIR/$tdir
1629         local osts="0,0"
1630         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1631         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1632         echo "$getstripe"
1633
1634         # Strip getstripe output to a space separated list of OSTs
1635         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1636                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1637         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1638                 error "stripes not on specified OSTs"
1639
1640         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1641 }
1642 run_test 27cc "two stripes on the same OST"
1643
1644 test_27cd() {
1645         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1646         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1647                 skip "server does not support overstriping"
1648         test_mkdir -p $DIR/$tdir
1649         local osts="0,1,1,0"
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27cd "four stripes on two OSTs"
1663
1664 test_27ce() {
1665         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1666                 skip_env "too many osts, skipping"
1667         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1668                 skip "server does not support overstriping"
1669         # We do one more stripe than we have OSTs
1670         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1671                 skip_env "ea_inode feature disabled"
1672
1673         test_mkdir -p $DIR/$tdir
1674         local osts=""
1675         for i in $(seq 0 $OSTCOUNT);
1676         do
1677                 osts=$osts"0"
1678                 if [ $i -ne $OSTCOUNT ]; then
1679                         osts=$osts","
1680                 fi
1681         done
1682         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1683         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1684         echo "$getstripe"
1685
1686         # Strip getstripe output to a space separated list of OSTs
1687         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1688                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1689         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1690                 error "stripes not on specified OSTs"
1691
1692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1693 }
1694 run_test 27ce "more stripes than OSTs with -o"
1695
1696 test_27cf() {
1697         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1698         local pid=0
1699
1700         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1702         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1704                 error "failed to set $osp_proc=0"
1705
1706         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1707         pid=$!
1708         sleep 1
1709         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1710         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1711                 error "failed to set $osp_proc=1"
1712         wait $pid
1713         [[ $pid -ne 0 ]] ||
1714                 error "should return error due to $osp_proc=0"
1715 }
1716 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1717
1718 test_27d() {
1719         test_mkdir $DIR/$tdir
1720         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1721                 error "setstripe failed"
1722         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1723         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1724 }
1725 run_test 27d "create file with default settings"
1726
1727 test_27e() {
1728         # LU-5839 adds check for existed layout before setting it
1729         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1730                 skip "Need MDS version at least 2.7.56"
1731
1732         test_mkdir $DIR/$tdir
1733         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1735         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1736 }
1737 run_test 27e "setstripe existing file (should return error)"
1738
1739 test_27f() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1742                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1743         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1744                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1745         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1746         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1747 }
1748 run_test 27f "setstripe with bad stripe size (should return error)"
1749
1750 test_27g() {
1751         test_mkdir $DIR/$tdir
1752         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1753         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1754                 error "$DIR/$tdir/$tfile has object"
1755 }
1756 run_test 27g "$LFS getstripe with no objects"
1757
1758 test_27ga() {
1759         test_mkdir $DIR/$tdir
1760         touch $DIR/$tdir/$tfile || error "touch failed"
1761         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1762         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1763         local rc=$?
1764         (( rc == 2 )) || error "getstripe did not return ENOENT"
1765 }
1766 run_test 27ga "$LFS getstripe with missing file (should return error)"
1767
1768 test_27i() {
1769         test_mkdir $DIR/$tdir
1770         touch $DIR/$tdir/$tfile || error "touch failed"
1771         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1772                 error "missing objects"
1773 }
1774 run_test 27i "$LFS getstripe with some objects"
1775
1776 test_27j() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1779                 error "setstripe failed" || true
1780 }
1781 run_test 27j "setstripe with bad stripe offset (should return error)"
1782
1783 test_27k() { # bug 2844
1784         test_mkdir $DIR/$tdir
1785         local file=$DIR/$tdir/$tfile
1786         local ll_max_blksize=$((4 * 1024 * 1024))
1787         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1788         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1789         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1790         dd if=/dev/zero of=$file bs=4k count=1
1791         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1792         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1793 }
1794 run_test 27k "limit i_blksize for broken user apps"
1795
1796 test_27l() {
1797         mcreate $DIR/$tfile || error "creating file"
1798         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1799                 error "setstripe should have failed" || true
1800 }
1801 run_test 27l "check setstripe permissions (should return error)"
1802
1803 test_27m() {
1804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1805
1806         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1807                 skip_env "multiple clients -- skipping"
1808
1809         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1810                    head -n1)
1811         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1812                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1813         fi
1814         stack_trap simple_cleanup_common
1815         test_mkdir $DIR/$tdir
1816         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1817         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1818                 error "dd should fill OST0"
1819         i=2
1820         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1821                 i=$((i + 1))
1822                 [ $i -gt 256 ] && break
1823         done
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"
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it" || true
1834 }
1835 run_test 27m "create file while OST0 was full"
1836
1837 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1838 # if the OST isn't full anymore.
1839 reset_enospc() {
1840         local ostidx=${1:-""}
1841         local delay
1842         local ready
1843         local get_prealloc
1844
1845         local list=$(comma_list $(osts_nodes))
1846         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1847
1848         do_nodes $list lctl set_param fail_loc=0
1849         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1850         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1851                 awk '{print $1 * 2;exit;}')
1852         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1853                         grep -v \"^0$\""
1854         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1855 }
1856
1857 test_27n() {
1858         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1860         remote_mds_nodsh && skip "remote MDS with nodsh"
1861         remote_ost_nodsh && skip "remote OST with nodsh"
1862
1863         reset_enospc
1864         rm -f $DIR/$tdir/$tfile
1865         exhaust_precreations 0 0x80000215
1866         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1867         touch $DIR/$tdir/$tfile || error "touch failed"
1868         $LFS getstripe $DIR/$tdir/$tfile
1869         reset_enospc
1870 }
1871 run_test 27n "create file with some full OSTs"
1872
1873 test_27o() {
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876         remote_mds_nodsh && skip "remote MDS with nodsh"
1877         remote_ost_nodsh && skip "remote OST with nodsh"
1878
1879         reset_enospc
1880         rm -f $DIR/$tdir/$tfile
1881         exhaust_all_precreations 0x215
1882
1883         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1884
1885         reset_enospc
1886         rm -rf $DIR/$tdir/*
1887 }
1888 run_test 27o "create file with all full OSTs (should error)"
1889
1890 function create_and_checktime() {
1891         local fname=$1
1892         local loops=$2
1893         local i
1894
1895         for ((i=0; i < $loops; i++)); do
1896                 local start=$SECONDS
1897                 multiop $fname-$i Oc
1898                 ((SECONDS-start < TIMEOUT)) ||
1899                         error "creation took " $((SECONDS-$start)) && return 1
1900         done
1901 }
1902
1903 test_27oo() {
1904         local mdts=$(comma_list $(mdts_nodes))
1905
1906         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1907                 skip "Need MDS version at least 2.13.57"
1908
1909         local f0=$DIR/${tfile}-0
1910         local f1=$DIR/${tfile}-1
1911
1912         wait_delete_completed
1913
1914         # refill precreated objects
1915         $LFS setstripe -i0 -c1 $f0
1916
1917         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1918         # force QoS allocation policy
1919         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1920         stack_trap "do_nodes $mdts $LCTL set_param \
1921                 lov.*.qos_threshold_rr=$saved" EXIT
1922         sleep_maxage
1923
1924         # one OST is unavailable, but still have few objects preallocated
1925         stop ost1
1926         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1927                 rm -rf $f1 $DIR/$tdir*" EXIT
1928
1929         for ((i=0; i < 7; i++)); do
1930                 mkdir $DIR/$tdir$i || error "can't create dir"
1931                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1932                         error "can't set striping"
1933         done
1934         for ((i=0; i < 7; i++)); do
1935                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1936         done
1937         wait
1938 }
1939 run_test 27oo "don't let few threads to reserve too many objects"
1940
1941 test_27p() {
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         reset_enospc
1948         rm -f $DIR/$tdir/$tfile
1949         test_mkdir $DIR/$tdir
1950
1951         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1952         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1953         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1954
1955         exhaust_precreations 0 0x80000215
1956         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1957         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1958         $LFS getstripe $DIR/$tdir/$tfile
1959
1960         reset_enospc
1961 }
1962 run_test 27p "append to a truncated file with some full OSTs"
1963
1964 test_27q() {
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         reset_enospc
1971         rm -f $DIR/$tdir/$tfile
1972
1973         mkdir_on_mdt0 $DIR/$tdir
1974         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1975         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1976                 error "truncate $DIR/$tdir/$tfile failed"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1978
1979         exhaust_all_precreations 0x215
1980
1981         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1982         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1983
1984         reset_enospc
1985 }
1986 run_test 27q "append to truncated file with all OSTs full (should error)"
1987
1988 test_27r() {
1989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992         remote_ost_nodsh && skip "remote OST with nodsh"
1993
1994         reset_enospc
1995         rm -f $DIR/$tdir/$tfile
1996         exhaust_precreations 0 0x80000215
1997
1998         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1999
2000         reset_enospc
2001 }
2002 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2003
2004 test_27s() { # bug 10725
2005         test_mkdir $DIR/$tdir
2006         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2007         local stripe_count=0
2008         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2009         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2010                 error "stripe width >= 2^32 succeeded" || true
2011
2012 }
2013 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2014
2015 test_27t() { # bug 10864
2016         WDIR=$(pwd)
2017         WLFS=$(which lfs)
2018         cd $DIR
2019         touch $tfile
2020         $WLFS getstripe $tfile
2021         cd $WDIR
2022 }
2023 run_test 27t "check that utils parse path correctly"
2024
2025 test_27u() { # bug 4900
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         remote_mds_nodsh && skip "remote MDS with nodsh"
2028
2029         local index
2030         local list=$(comma_list $(mdts_nodes))
2031
2032 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2033         do_nodes $list $LCTL set_param fail_loc=0x139
2034         test_mkdir -p $DIR/$tdir
2035         stack_trap "simple_cleanup_common 1000"
2036         createmany -o $DIR/$tdir/$tfile 1000
2037         do_nodes $list $LCTL set_param fail_loc=0
2038
2039         TLOG=$TMP/$tfile.getstripe
2040         $LFS getstripe $DIR/$tdir > $TLOG
2041         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2042         [[ $OBJS -gt 0 ]] &&
2043                 error "$OBJS objects created on OST-0. See $TLOG" ||
2044                 rm -f $TLOG
2045 }
2046 run_test 27u "skip object creation on OSC w/o objects"
2047
2048 test_27v() { # bug 4900
2049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2051         remote_mds_nodsh && skip "remote MDS with nodsh"
2052         remote_ost_nodsh && skip "remote OST with nodsh"
2053
2054         exhaust_all_precreations 0x215
2055         reset_enospc
2056
2057         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2058
2059         touch $DIR/$tdir/$tfile
2060         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2061         # all except ost1
2062         for (( i=1; i < OSTCOUNT; i++ )); do
2063                 do_facet ost$i lctl set_param fail_loc=0x705
2064         done
2065         local START=`date +%s`
2066         createmany -o $DIR/$tdir/$tfile 32
2067
2068         local FINISH=`date +%s`
2069         local TIMEOUT=`lctl get_param -n timeout`
2070         local PROCESS=$((FINISH - START))
2071         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2072                error "$FINISH - $START >= $TIMEOUT / 2"
2073         sleep $((TIMEOUT / 2 - PROCESS))
2074         reset_enospc
2075 }
2076 run_test 27v "skip object creation on slow OST"
2077
2078 test_27w() { # bug 10997
2079         test_mkdir $DIR/$tdir
2080         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2081         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2082                 error "stripe size $size != 65536" || true
2083         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2084                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2085 }
2086 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2087
2088 test_27wa() {
2089         [[ $OSTCOUNT -lt 2 ]] &&
2090                 skip_env "skipping multiple stripe count/offset test"
2091
2092         test_mkdir $DIR/$tdir
2093         for i in $(seq 1 $OSTCOUNT); do
2094                 offset=$((i - 1))
2095                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2096                         error "setstripe -c $i -i $offset failed"
2097                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2098                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2099                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2100                 [ $index -ne $offset ] &&
2101                         error "stripe offset $index != $offset" || true
2102         done
2103 }
2104 run_test 27wa "check $LFS setstripe -c -i options"
2105
2106 test_27x() {
2107         remote_ost_nodsh && skip "remote OST with nodsh"
2108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2110
2111         OFFSET=$(($OSTCOUNT - 1))
2112         OSTIDX=0
2113         local OST=$(ostname_from_index $OSTIDX)
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2117         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2118         sleep_maxage
2119         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2120         for i in $(seq 0 $OFFSET); do
2121                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2122                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2123                 error "OST0 was degraded but new created file still use it"
2124         done
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2126 }
2127 run_test 27x "create files while OST0 is degraded"
2128
2129 test_27y() {
2130         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2131         remote_mds_nodsh && skip "remote MDS with nodsh"
2132         remote_ost_nodsh && skip "remote OST with nodsh"
2133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2134
2135         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2136         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2137                 osp.$mdtosc.prealloc_last_id)
2138         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_next_id)
2140         local fcount=$((last_id - next_id))
2141         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2142         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2143
2144         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2145                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2146         local OST_DEACTIVE_IDX=-1
2147         local OSC
2148         local OSTIDX
2149         local OST
2150
2151         for OSC in $MDS_OSCS; do
2152                 OST=$(osc_to_ost $OSC)
2153                 OSTIDX=$(index_from_ostuuid $OST)
2154                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2155                         OST_DEACTIVE_IDX=$OSTIDX
2156                 fi
2157                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2158                         echo $OSC "is Deactivated:"
2159                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2160                 fi
2161         done
2162
2163         OSTIDX=$(index_from_ostuuid $OST)
2164         test_mkdir $DIR/$tdir
2165         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2166
2167         for OSC in $MDS_OSCS; do
2168                 OST=$(osc_to_ost $OSC)
2169                 OSTIDX=$(index_from_ostuuid $OST)
2170                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2171                         echo $OST "is degraded:"
2172                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2173                                                 obdfilter.$OST.degraded=1
2174                 fi
2175         done
2176
2177         sleep_maxage
2178         createmany -o $DIR/$tdir/$tfile $fcount
2179
2180         for OSC in $MDS_OSCS; do
2181                 OST=$(osc_to_ost $OSC)
2182                 OSTIDX=$(index_from_ostuuid $OST)
2183                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2184                         echo $OST "is recovered from degraded:"
2185                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2186                                                 obdfilter.$OST.degraded=0
2187                 else
2188                         do_facet $SINGLEMDS lctl --device %$OSC activate
2189                 fi
2190         done
2191
2192         # all osp devices get activated, hence -1 stripe count restored
2193         local stripe_count=0
2194
2195         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2196         # devices get activated.
2197         sleep_maxage
2198         $LFS setstripe -c -1 $DIR/$tfile
2199         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2200         rm -f $DIR/$tfile
2201         [ $stripe_count -ne $OSTCOUNT ] &&
2202                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2203         return 0
2204 }
2205 run_test 27y "create files while OST0 is degraded and the rest inactive"
2206
2207 check_seq_oid()
2208 {
2209         log "check file $1"
2210
2211         lmm_count=$($LFS getstripe -c $1)
2212         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2213         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2214
2215         local old_ifs="$IFS"
2216         IFS=$'[:]'
2217         fid=($($LFS path2fid $1))
2218         IFS="$old_ifs"
2219
2220         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2221         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2222
2223         # compare lmm_seq and lu_fid->f_seq
2224         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2225         # compare lmm_object_id and lu_fid->oid
2226         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2227
2228         # check the trusted.fid attribute of the OST objects of the file
2229         local have_obdidx=false
2230         local stripe_nr=0
2231         $LFS getstripe $1 | while read obdidx oid hex seq; do
2232                 # skip lines up to and including "obdidx"
2233                 [ -z "$obdidx" ] && break
2234                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2235                 $have_obdidx || continue
2236
2237                 local ost=$((obdidx + 1))
2238                 local dev=$(ostdevname $ost)
2239                 local oid_hex
2240
2241                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2242
2243                 seq=$(echo $seq | sed -e "s/^0x//g")
2244                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2245                         oid_hex=$(echo $oid)
2246                 else
2247                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2248                 fi
2249                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2250
2251                 local ff=""
2252                 #
2253                 # Don't unmount/remount the OSTs if we don't need to do that.
2254                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2255                 # update too, until that use mount/ll_decode_filter_fid/mount.
2256                 # Re-enable when debugfs will understand new filter_fid.
2257                 #
2258                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2259                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2260                                 $dev 2>/dev/null" | grep "parent=")
2261                 fi
2262                 if [ -z "$ff" ]; then
2263                         stop ost$ost
2264                         mount_fstype ost$ost
2265                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2266                                 $(facet_mntpt ost$ost)/$obj_file)
2267                         unmount_fstype ost$ost
2268                         start ost$ost $dev $OST_MOUNT_OPTS
2269                         clients_up
2270                 fi
2271
2272                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2273
2274                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2275
2276                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2277                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2278                 #
2279                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2280                 #       stripe_size=1048576 component_id=1 component_start=0 \
2281                 #       component_end=33554432
2282                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2283                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2284                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2285                 local ff_pstripe
2286                 if grep -q 'stripe=' <<<$ff; then
2287                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2288                 else
2289                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2290                         # into f_ver in this case.  See comment on ff_parent.
2291                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2292                 fi
2293
2294                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2295                 [ $ff_pseq = $lmm_seq ] ||
2296                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2297                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2298                 [ $ff_poid = $lmm_oid ] ||
2299                         error "FF parent OID $ff_poid != $lmm_oid"
2300                 (($ff_pstripe == $stripe_nr)) ||
2301                         error "FF stripe $ff_pstripe != $stripe_nr"
2302
2303                 stripe_nr=$((stripe_nr + 1))
2304                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2305                         continue
2306                 if grep -q 'stripe_count=' <<<$ff; then
2307                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2308                                             -e 's/ .*//' <<<$ff)
2309                         [ $lmm_count = $ff_scnt ] ||
2310                                 error "FF stripe count $lmm_count != $ff_scnt"
2311                 fi
2312         done
2313 }
2314
2315 test_27z() {
2316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2317         remote_ost_nodsh && skip "remote OST with nodsh"
2318
2319         test_mkdir $DIR/$tdir
2320         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2321                 { error "setstripe -c -1 failed"; return 1; }
2322         # We need to send a write to every object to get parent FID info set.
2323         # This _should_ also work for setattr, but does not currently.
2324         # touch $DIR/$tdir/$tfile-1 ||
2325         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2326                 { error "dd $tfile-1 failed"; return 2; }
2327         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2328                 { error "setstripe -c -1 failed"; return 3; }
2329         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2330                 { error "dd $tfile-2 failed"; return 4; }
2331
2332         # make sure write RPCs have been sent to OSTs
2333         sync; sleep 5; sync
2334
2335         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2336         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2337 }
2338 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2339
2340 test_27A() { # b=19102
2341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2342
2343         save_layout_restore_at_exit $MOUNT
2344         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2345         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2346                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2347         local default_size=$($LFS getstripe -S $MOUNT)
2348         local default_offset=$($LFS getstripe -i $MOUNT)
2349         local dsize=$(do_facet $SINGLEMDS \
2350                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2351         [ $default_size -eq $dsize ] ||
2352                 error "stripe size $default_size != $dsize"
2353         [ $default_offset -eq -1 ] ||
2354                 error "stripe offset $default_offset != -1"
2355 }
2356 run_test 27A "check filesystem-wide default LOV EA values"
2357
2358 test_27B() { # LU-2523
2359         test_mkdir $DIR/$tdir
2360         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2361         touch $DIR/$tdir/f0
2362         # open f1 with O_LOV_DELAY_CREATE
2363         # rename f0 onto f1
2364         # call setstripe ioctl on open file descriptor for f1
2365         # close
2366         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2367                 $DIR/$tdir/f0
2368
2369         rm -f $DIR/$tdir/f1
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # unlink f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2375
2376         # Allow multiop to fail in imitation of NFS's busted semantics.
2377         true
2378 }
2379 run_test 27B "call setstripe on open unlinked file/rename victim"
2380
2381 # 27C family tests full striping and overstriping
2382 test_27Ca() { #LU-2871
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384
2385         declare -a ost_idx
2386         local index
2387         local found
2388         local i
2389         local j
2390
2391         test_mkdir $DIR/$tdir
2392         cd $DIR/$tdir
2393         for i in $(seq 0 $((OSTCOUNT - 1))); do
2394                 # set stripe across all OSTs starting from OST$i
2395                 $LFS setstripe -i $i -c -1 $tfile$i
2396                 # get striping information
2397                 ost_idx=($($LFS getstripe $tfile$i |
2398                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2399                 echo "OST Index: ${ost_idx[*]}"
2400
2401                 # check the layout
2402                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2403                         error "${#ost_idx[@]} != $OSTCOUNT"
2404
2405                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2406                         found=0
2407                         for j in "${ost_idx[@]}"; do
2408                                 if [ $index -eq $j ]; then
2409                                         found=1
2410                                         break
2411                                 fi
2412                         done
2413                         [ $found = 1 ] ||
2414                                 error "Can not find $index in ${ost_idx[*]}"
2415                 done
2416         done
2417 }
2418 run_test 27Ca "check full striping across all OSTs"
2419
2420 test_27Cb() {
2421         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2422                 skip "server does not support overstriping"
2423         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2424                 skip_env "too many osts, skipping"
2425
2426         test_mkdir -p $DIR/$tdir
2427         local setcount=$(($OSTCOUNT * 2))
2428         [ $setcount -lt 160 ] || large_xattr_enabled ||
2429                 skip_env "ea_inode feature disabled"
2430
2431         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2432                 error "setstripe failed"
2433
2434         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2435         [ $count -eq $setcount ] ||
2436                 error "stripe count $count, should be $setcount"
2437
2438         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2439                 error "overstriped should be set in pattern"
2440
2441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2442                 error "dd failed"
2443 }
2444 run_test 27Cb "more stripes than OSTs with -C"
2445
2446 test_27Cc() {
2447         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2448                 skip "server does not support overstriping"
2449         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2450
2451         test_mkdir -p $DIR/$tdir
2452         local setcount=$(($OSTCOUNT - 1))
2453
2454         [ $setcount -lt 160 ] || large_xattr_enabled ||
2455                 skip_env "ea_inode feature disabled"
2456
2457         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2458                 error "setstripe failed"
2459
2460         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2461         [ $count -eq $setcount ] ||
2462                 error "stripe count $count, should be $setcount"
2463
2464         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2465                 error "overstriped should not be set in pattern"
2466
2467         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2468                 error "dd failed"
2469 }
2470 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2471
2472 test_27Cd() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2476         large_xattr_enabled || skip_env "ea_inode feature disabled"
2477
2478         test_mkdir -p $DIR/$tdir
2479         local setcount=$LOV_MAX_STRIPE_COUNT
2480
2481         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2482                 error "setstripe failed"
2483
2484         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2485         [ $count -eq $setcount ] ||
2486                 error "stripe count $count, should be $setcount"
2487
2488         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2489                 error "overstriped should be set in pattern"
2490
2491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2492                 error "dd failed"
2493
2494         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2495 }
2496 run_test 27Cd "test maximum stripe count"
2497
2498 test_27Ce() {
2499         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2500                 skip "server does not support overstriping"
2501         test_mkdir -p $DIR/$tdir
2502
2503         pool_add $TESTNAME || error "Pool creation failed"
2504         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2505
2506         local setcount=8
2507
2508         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2509                 error "setstripe failed"
2510
2511         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2512         [ $count -eq $setcount ] ||
2513                 error "stripe count $count, should be $setcount"
2514
2515         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2516                 error "overstriped should be set in pattern"
2517
2518         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2519                 error "dd failed"
2520
2521         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2522 }
2523 run_test 27Ce "test pool with overstriping"
2524
2525 test_27Cf() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2529                 skip_env "too many osts, skipping"
2530
2531         test_mkdir -p $DIR/$tdir
2532
2533         local setcount=$(($OSTCOUNT * 2))
2534         [ $setcount -lt 160 ] || large_xattr_enabled ||
2535                 skip_env "ea_inode feature disabled"
2536
2537         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2538                 error "setstripe failed"
2539
2540         echo 1 > $DIR/$tdir/$tfile
2541
2542         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2543         [ $count -eq $setcount ] ||
2544                 error "stripe count $count, should be $setcount"
2545
2546         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2547                 error "overstriped should be set in pattern"
2548
2549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2550                 error "dd failed"
2551
2552         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2553 }
2554 run_test 27Cf "test default inheritance with overstriping"
2555
2556 test_27D() {
2557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2559         remote_mds_nodsh && skip "remote MDS with nodsh"
2560
2561         local POOL=${POOL:-testpool}
2562         local first_ost=0
2563         local last_ost=$(($OSTCOUNT - 1))
2564         local ost_step=1
2565         local ost_list=$(seq $first_ost $ost_step $last_ost)
2566         local ost_range="$first_ost $last_ost $ost_step"
2567
2568         test_mkdir $DIR/$tdir
2569         pool_add $POOL || error "pool_add failed"
2570         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2571
2572         local skip27D
2573         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2574                 skip27D+="-s 29"
2575         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2576                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2577                         skip27D+=" -s 30,31"
2578         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2579           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2580                 skip27D+=" -s 32,33"
2581         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2582                 skip27D+=" -s 34"
2583         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2584                 error "llapi_layout_test failed"
2585
2586         destroy_test_pools || error "destroy test pools failed"
2587 }
2588 run_test 27D "validate llapi_layout API"
2589
2590 # Verify that default_easize is increased from its initial value after
2591 # accessing a widely striped file.
2592 test_27E() {
2593         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2594         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2595                 skip "client does not have LU-3338 fix"
2596
2597         # 72 bytes is the minimum space required to store striping
2598         # information for a file striped across one OST:
2599         # (sizeof(struct lov_user_md_v3) +
2600         #  sizeof(struct lov_user_ost_data_v1))
2601         local min_easize=72
2602         $LCTL set_param -n llite.*.default_easize $min_easize ||
2603                 error "lctl set_param failed"
2604         local easize=$($LCTL get_param -n llite.*.default_easize)
2605
2606         [ $easize -eq $min_easize ] ||
2607                 error "failed to set default_easize"
2608
2609         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2610                 error "setstripe failed"
2611         # In order to ensure stat() call actually talks to MDS we need to
2612         # do something drastic to this file to shake off all lock, e.g.
2613         # rename it (kills lookup lock forcing cache cleaning)
2614         mv $DIR/$tfile $DIR/${tfile}-1
2615         ls -l $DIR/${tfile}-1
2616         rm $DIR/${tfile}-1
2617
2618         easize=$($LCTL get_param -n llite.*.default_easize)
2619
2620         [ $easize -gt $min_easize ] ||
2621                 error "default_easize not updated"
2622 }
2623 run_test 27E "check that default extended attribute size properly increases"
2624
2625 test_27F() { # LU-5346/LU-7975
2626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2627         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2628         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2629                 skip "Need MDS version at least 2.8.51"
2630         remote_ost_nodsh && skip "remote OST with nodsh"
2631
2632         test_mkdir $DIR/$tdir
2633         rm -f $DIR/$tdir/f0
2634         $LFS setstripe -c 2 $DIR/$tdir
2635
2636         # stop all OSTs to reproduce situation for LU-7975 ticket
2637         for num in $(seq $OSTCOUNT); do
2638                 stop ost$num
2639         done
2640
2641         # open/create f0 with O_LOV_DELAY_CREATE
2642         # truncate f0 to a non-0 size
2643         # close
2644         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2645
2646         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2647         # open/write it again to force delayed layout creation
2648         cat /etc/hosts > $DIR/$tdir/f0 &
2649         catpid=$!
2650
2651         # restart OSTs
2652         for num in $(seq $OSTCOUNT); do
2653                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2654                         error "ost$num failed to start"
2655         done
2656
2657         wait $catpid || error "cat failed"
2658
2659         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2660         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2661                 error "wrong stripecount"
2662
2663 }
2664 run_test 27F "Client resend delayed layout creation with non-zero size"
2665
2666 test_27G() { #LU-10629
2667         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2668                 skip "Need MDS version at least 2.11.51"
2669         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2670         remote_mds_nodsh && skip "remote MDS with nodsh"
2671         local POOL=${POOL:-testpool}
2672         local ostrange="0 0 1"
2673
2674         test_mkdir $DIR/$tdir
2675         touch $DIR/$tdir/$tfile.nopool
2676         pool_add $POOL || error "pool_add failed"
2677         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2678         $LFS setstripe -p $POOL $DIR/$tdir
2679
2680         local pool=$($LFS getstripe -p $DIR/$tdir)
2681
2682         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2683         touch $DIR/$tdir/$tfile.default
2684         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2685         $LFS find $DIR/$tdir -type f --pool $POOL
2686         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2687         [[ "$found" == "2" ]] ||
2688                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2689
2690         $LFS setstripe -d $DIR/$tdir
2691
2692         pool=$($LFS getstripe -p -d $DIR/$tdir)
2693
2694         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2695 }
2696 run_test 27G "Clear OST pool from stripe"
2697
2698 test_27H() {
2699         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2700                 skip "Need MDS version newer than 2.11.54"
2701         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2704         touch $DIR/$tdir/$tfile
2705         $LFS getstripe -c $DIR/$tdir/$tfile
2706         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2707                 error "two-stripe file doesn't have two stripes"
2708
2709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2710         $LFS getstripe -y $DIR/$tdir/$tfile
2711         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2712              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2713                 error "expected l_ost_idx: [02]$ not matched"
2714
2715         # make sure ost list has been cleared
2716         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2717         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2718                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2719         touch $DIR/$tdir/f3
2720         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2721 }
2722 run_test 27H "Set specific OSTs stripe"
2723
2724 test_27I() {
2725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2727         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2728                 skip "Need MDS version newer than 2.12.52"
2729         local pool=$TESTNAME
2730         local ostrange="1 1 1"
2731
2732         save_layout_restore_at_exit $MOUNT
2733         $LFS setstripe -c 2 -i 0 $MOUNT
2734         pool_add $pool || error "pool_add failed"
2735         pool_add_targets $pool $ostrange ||
2736                 error "pool_add_targets failed"
2737         test_mkdir $DIR/$tdir
2738         $LFS setstripe -p $pool $DIR/$tdir
2739         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2740         $LFS getstripe $DIR/$tdir/$tfile
2741 }
2742 run_test 27I "check that root dir striping does not break parent dir one"
2743
2744 test_27J() {
2745         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2746                 skip "Need MDS version newer than 2.12.51"
2747
2748         test_mkdir $DIR/$tdir
2749         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2750         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2751
2752         # create foreign file (raw way)
2753         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2754                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2755
2756         ! $LFS setstripe --foreign --flags foo \
2757                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2758                         error "creating $tfile with '--flags foo' should fail"
2759
2760         ! $LFS setstripe --foreign --flags 0xffffffff \
2761                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2762                         error "creating $tfile w/ 0xffffffff flags should fail"
2763
2764         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2765                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2766
2767         # verify foreign file (raw way)
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2771         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_size: 73" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_type: 1" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2779         parse_foreign_file -f $DIR/$tdir/$tfile |
2780                 grep "lov_foreign_flags: 0x0000DA08" ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2782         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2783                 grep "lov_foreign_value: 0x" |
2784                 sed -e 's/lov_foreign_value: 0x//')
2785         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2786         [[ $lov = ${lov2// /} ]] ||
2787                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2788
2789         # create foreign file (lfs + API)
2790         $LFS setstripe --foreign=none --flags 0xda08 \
2791                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2792                 error "$DIR/$tdir/${tfile}2: create failed"
2793
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2795                 grep "lfm_magic:.*0x0BD70BD0" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2797         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2798         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_flags:.*0x0000DA08" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2805         $LFS getstripe $DIR/$tdir/${tfile}2 |
2806                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2808
2809         # modify striping should fail
2810         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2811                 error "$DIR/$tdir/$tfile: setstripe should fail"
2812         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2814
2815         # R/W should fail
2816         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2817         cat $DIR/$tdir/${tfile}2 &&
2818                 error "$DIR/$tdir/${tfile}2: read should fail"
2819         cat /etc/passwd > $DIR/$tdir/$tfile &&
2820                 error "$DIR/$tdir/$tfile: write should fail"
2821         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2822                 error "$DIR/$tdir/${tfile}2: write should fail"
2823
2824         # chmod should work
2825         chmod 222 $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chmod failed"
2827         chmod 222 $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chmod failed"
2829
2830         # chown should work
2831         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2832                 error "$DIR/$tdir/$tfile: chown failed"
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2834                 error "$DIR/$tdir/${tfile}2: chown failed"
2835
2836         # rename should work
2837         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2839         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2841
2842         #remove foreign file
2843         rm $DIR/$tdir/${tfile}.new ||
2844                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2845         rm $DIR/$tdir/${tfile}2.new ||
2846                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2847 }
2848 run_test 27J "basic ops on file with foreign LOV"
2849
2850 test_27K() {
2851         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2852                 skip "Need MDS version newer than 2.12.49"
2853
2854         test_mkdir $DIR/$tdir
2855         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2856         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2857
2858         # create foreign dir (raw way)
2859         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2860                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2861
2862         ! $LFS setdirstripe --foreign --flags foo \
2863                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2864                         error "creating $tdir with '--flags foo' should fail"
2865
2866         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2867                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2868                         error "creating $tdir w/ 0xffffffff flags should fail"
2869
2870         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2871                 error "create_foreign_dir FAILED"
2872
2873         # verify foreign dir (raw way)
2874         parse_foreign_dir -d $DIR/$tdir/$tdir |
2875                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2876                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2877         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir |
2882                 grep "lmv_foreign_flags: 55813$" ||
2883                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2884         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2885                 grep "lmv_foreign_value: 0x" |
2886                 sed 's/lmv_foreign_value: 0x//')
2887         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2888                 sed 's/ //g')
2889         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2890
2891         # create foreign dir (lfs + API)
2892         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2893                 $DIR/$tdir/${tdir}2 ||
2894                 error "$DIR/$tdir/${tdir}2: create failed"
2895
2896         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2897                 grep "lfm_magic:.*0x0CD50CD0" ||
2898                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2899         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2900         # - sizeof(lfm_type) - sizeof(lfm_flags)
2901         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2902                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_flags:.*0x0000DA05" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2908         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2909                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2911
2912         # file create in dir should fail
2913         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2914         touch $DIR/$tdir/${tdir}2/$tfile &&
2915                 error "$DIR/${tdir}2: file create should fail"
2916
2917         # chmod should work
2918         chmod 777 $DIR/$tdir/$tdir ||
2919                 error "$DIR/$tdir: chmod failed"
2920         chmod 777 $DIR/$tdir/${tdir}2 ||
2921                 error "$DIR/${tdir}2: chmod failed"
2922
2923         # chown should work
2924         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2925                 error "$DIR/$tdir: chown failed"
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2927                 error "$DIR/${tdir}2: chown failed"
2928
2929         # rename should work
2930         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2931                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2932         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2933                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2934
2935         #remove foreign dir
2936         rmdir $DIR/$tdir/${tdir}.new ||
2937                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2938         rmdir $DIR/$tdir/${tdir}2.new ||
2939                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2940 }
2941 run_test 27K "basic ops on dir with foreign LMV"
2942
2943 test_27L() {
2944         remote_mds_nodsh && skip "remote MDS with nodsh"
2945
2946         local POOL=${POOL:-$TESTNAME}
2947
2948         pool_add $POOL || error "pool_add failed"
2949
2950         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2951                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2952                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2953 }
2954 run_test 27L "lfs pool_list gives correct pool name"
2955
2956 test_27M() {
2957         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2958                 skip "Need MDS version >= than 2.12.57"
2959         remote_mds_nodsh && skip "remote MDS with nodsh"
2960         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2961
2962         test_mkdir $DIR/$tdir
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967
2968         # if we run against a 2.12 server which lacks overstring support
2969         # then the connect_flag will not report overstriping, even if client
2970         # is 2.14+
2971         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2972                 stripe_opt="-C $setcount"
2973         elif (( $OSTCOUNT >= $setcount )); then
2974                 stripe_opt="-c $setcount"
2975         else
2976                 skip "server does not support overstriping"
2977         fi
2978         $LFS setstripe $stripe_opt $DIR/$tdir
2979
2980         echo 1 > $DIR/$tdir/${tfile}.1
2981         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2982         [ $count -eq $setcount ] ||
2983                 error "(1) stripe count $count, should be $setcount"
2984
2985         # Capture existing append_stripe_count setting for restore
2986         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2987         local mdts=$(comma_list $(mdts_nodes))
2988         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2989
2990         local appendcount=$orig_count
2991         echo 1 >> $DIR/$tdir/${tfile}.2_append
2992         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2993         [ $count -eq $appendcount ] ||
2994                 error "(2)stripe count $count, should be $appendcount for append"
2995
2996         # Disable O_APPEND striping, verify it works
2997         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2998
2999         # Should now get the default striping, which is 4
3000         setcount=4
3001         echo 1 >> $DIR/$tdir/${tfile}.3_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3003         [ $count -eq $setcount ] ||
3004                 error "(3) stripe count $count, should be $setcount"
3005
3006         # Try changing the stripe count for append files
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3008
3009         # Append striping is now 2 (directory default is still 4)
3010         appendcount=2
3011         echo 1 >> $DIR/$tdir/${tfile}.4_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3013         [ $count -eq $appendcount ] ||
3014                 error "(4) stripe count $count, should be $appendcount for append"
3015
3016         # Test append stripe count of -1
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3018         appendcount=$OSTCOUNT
3019         echo 1 >> $DIR/$tdir/${tfile}.5
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3021         [ $count -eq $appendcount ] ||
3022                 error "(5) stripe count $count, should be $appendcount for append"
3023
3024         # Set append striping back to default of 1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3026
3027         # Try a new default striping, PFL + DOM
3028         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3029
3030         # Create normal DOM file, DOM returns stripe count == 0
3031         setcount=0
3032         touch $DIR/$tdir/${tfile}.6
3033         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3034         [ $count -eq $setcount ] ||
3035                 error "(6) stripe count $count, should be $setcount"
3036
3037         # Show
3038         appendcount=1
3039         echo 1 >> $DIR/$tdir/${tfile}.7_append
3040         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3041         [ $count -eq $appendcount ] ||
3042                 error "(7) stripe count $count, should be $appendcount for append"
3043
3044         # Clean up DOM layout
3045         $LFS setstripe -d $DIR/$tdir
3046
3047         save_layout_restore_at_exit $MOUNT
3048         # Now test that append striping works when layout is from root
3049         $LFS setstripe -c 2 $MOUNT
3050         # Make a special directory for this
3051         mkdir $DIR/${tdir}/${tdir}.2
3052
3053         # Verify for normal file
3054         setcount=2
3055         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3056         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3057         [ $count -eq $setcount ] ||
3058                 error "(8) stripe count $count, should be $setcount"
3059
3060         appendcount=1
3061         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3062         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3063         [ $count -eq $appendcount ] ||
3064                 error "(9) stripe count $count, should be $appendcount for append"
3065
3066         # Now test O_APPEND striping with pools
3067         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3068         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3069
3070         # Create the pool
3071         pool_add $TESTNAME || error "pool creation failed"
3072         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
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                 grep "lfm_magic:.*0x0CD50CD0" ||
3239                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3240         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3243                 grep "lfm_flags:.*0x0000DA05" ||
3244                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3245         $LFS getdirstripe $DIR/$tdir/${tdir} |
3246                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3248
3249         # file create in dir should fail
3250         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3251         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3252
3253         # rename should succeed
3254         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3255                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3256
3257         #remove foreign_symlink dir should fail
3258         rmdir $DIR/$tdir/${tdir}.new &&
3259                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3260
3261         #test fake symlink
3262         mkdir -p /tmp/${uuid1}/${uuid2} ||
3263                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3264         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3265                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3266         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3267         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3268                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3269         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3270                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3271
3272         #check that getstripe fails now that foreign_symlink enabled
3273         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3274                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3275
3276         # file create in dir should work now
3277         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3278                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3279         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3281         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3282                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3283
3284         # chmod should still succeed
3285         chmod 755 $DIR/$tdir/${tdir}.new ||
3286                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3287
3288         # chown should still succeed
3289         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3290                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3291
3292         # rename should still succeed
3293         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3294                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3295
3296         #remove foreign_symlink dir should still fail
3297         rmdir $DIR/$tdir/${tdir} &&
3298                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3299
3300         #use special ioctl() to unlink foreign_symlink file
3301         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3303
3304         #created file should still exist
3305         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3306                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3307         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3309 }
3310 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3311
3312 test_27Q() {
3313         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3314         stack_trap "rm -f $TMP/$tfile*"
3315
3316         test_mkdir $DIR/$tdir-1
3317         test_mkdir $DIR/$tdir-2
3318
3319         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3320         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3321
3322         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3323         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3324
3325         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3326         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3327
3328         # Create some bad symlinks and ensure that we don't loop
3329         # forever or something. These should return ELOOP (40) and
3330         # ENOENT (2) but I don't want to test for that because there's
3331         # always some weirdo architecture that needs to ruin
3332         # everything by defining these error numbers differently.
3333
3334         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3335         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3336
3337         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3338         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3339
3340         return 0
3341 }
3342 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3343
3344 test_27R() {
3345         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3346                 skip "need MDS 2.14.55 or later"
3347         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3348
3349         local testdir="$DIR/$tdir"
3350         test_mkdir -p $testdir
3351         stack_trap "rm -rf $testdir"
3352         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3353
3354         local f1="$testdir/f1"
3355         touch $f1 || error "failed to touch $f1"
3356         local count=$($LFS getstripe -c $f1)
3357         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3358
3359         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3360         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3361
3362         local maxcount=$(($OSTCOUNT - 1))
3363         local mdts=$(comma_list $(mdts_nodes))
3364         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3365         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3366
3367         local f2="$testdir/f2"
3368         touch $f2 || error "failed to touch $f2"
3369         local count=$($LFS getstripe -c $f2)
3370         (( $count == $maxcount )) || error "wrong stripe count"
3371 }
3372 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3373
3374 test_27S() {
3375         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3376                 skip "Need MDS version at least 2.14.54"
3377         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3378                 skip "needs different host for mdt1 ost1"
3379
3380         local count=$(precreated_ost_obj_count 0 0)
3381
3382         echo "precreate count $count"
3383         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3385         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3386         do_facet mds1 $LCTL set_param fail_loc=0x2109
3387         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3388         do_facet ost1 $LCTL set_param fail_loc=0x252
3389         createmany -o $DIR/$tdir/f $count &
3390         pid=$!
3391         echo "precreate count $(precreated_ost_obj_count 0 0)"
3392         do_facet mds1 $LCTL set_param fail_loc=0
3393         do_facet ost1 $LCTL set_param fail_loc=0
3394         wait $pid || error "createmany failed"
3395         echo "precreate count $(precreated_ost_obj_count 0 0)"
3396 }
3397 run_test 27S "don't deactivate OSP on network issue"
3398
3399 test_27T() {
3400         [ $(facet_host client) == $(facet_host ost1) ] &&
3401                 skip "need ost1 and client on different nodes"
3402
3403 #define OBD_FAIL_OSC_NO_GRANT            0x411
3404         $LCTL set_param fail_loc=0x20000411 fail_val=1
3405 #define OBD_FAIL_OST_ENOSPC              0x215
3406         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3407         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3408         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3409                 error "multiop failed"
3410 }
3411 run_test 27T "no eio on close on partial write due to enosp"
3412
3413 # createtest also checks that device nodes are created and
3414 # then visible correctly (#2091)
3415 test_28() { # bug 2091
3416         test_mkdir $DIR/d28
3417         $CREATETEST $DIR/d28/ct || error "createtest failed"
3418 }
3419 run_test 28 "create/mknod/mkdir with bad file types ============"
3420
3421 test_29() {
3422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3423
3424         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3425                 disable_opencache
3426                 stack_trap "restore_opencache"
3427         }
3428
3429         sync; sleep 1; sync # flush out any dirty pages from previous tests
3430         cancel_lru_locks
3431         test_mkdir $DIR/d29
3432         touch $DIR/d29/foo
3433         log 'first d29'
3434         ls -l $DIR/d29
3435
3436         declare -i LOCKCOUNTORIG=0
3437         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3438                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3439         done
3440         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3441
3442         declare -i LOCKUNUSEDCOUNTORIG=0
3443         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3444                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3445         done
3446
3447         log 'second d29'
3448         ls -l $DIR/d29
3449         log 'done'
3450
3451         declare -i LOCKCOUNTCURRENT=0
3452         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3453                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3454         done
3455
3456         declare -i LOCKUNUSEDCOUNTCURRENT=0
3457         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3458                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3459         done
3460
3461         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3462                 $LCTL set_param -n ldlm.dump_namespaces ""
3463                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3464                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3465                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3466                 return 2
3467         fi
3468         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3469                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3470                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3471                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3472                 return 3
3473         fi
3474 }
3475 run_test 29 "IT_GETATTR regression  ============================"
3476
3477 test_30a() { # was test_30
3478         cp $(which ls) $DIR || cp /bin/ls $DIR
3479         $DIR/ls / || error "Can't execute binary from lustre"
3480         rm $DIR/ls
3481 }
3482 run_test 30a "execute binary from Lustre (execve) =============="
3483
3484 test_30b() {
3485         cp `which ls` $DIR || cp /bin/ls $DIR
3486         chmod go+rx $DIR/ls
3487         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3488         rm $DIR/ls
3489 }
3490 run_test 30b "execute binary from Lustre as non-root ==========="
3491
3492 test_30c() { # b=22376
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         cp $(which ls) $DIR || cp /bin/ls $DIR
3496         chmod a-rw $DIR/ls
3497         cancel_lru_locks mdc
3498         cancel_lru_locks osc
3499         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3500         rm -f $DIR/ls
3501 }
3502 run_test 30c "execute binary from Lustre without read perms ===="
3503
3504 test_30d() {
3505         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3506
3507         for i in {1..10}; do
3508                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3509                 local PID=$!
3510                 sleep 1
3511                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3512                 wait $PID || error "executing dd from Lustre failed"
3513                 rm -f $DIR/$tfile
3514         done
3515
3516         rm -f $DIR/dd
3517 }
3518 run_test 30d "execute binary from Lustre while clear locks"
3519
3520 test_31a() {
3521         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3522         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3523 }
3524 run_test 31a "open-unlink file =================================="
3525
3526 test_31b() {
3527         touch $DIR/f31 || error "touch $DIR/f31 failed"
3528         ln $DIR/f31 $DIR/f31b || error "ln failed"
3529         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3530         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3531 }
3532 run_test 31b "unlink file with multiple links while open ======="
3533
3534 test_31c() {
3535         touch $DIR/f31 || error "touch $DIR/f31 failed"
3536         ln $DIR/f31 $DIR/f31c || error "ln failed"
3537         multiop_bg_pause $DIR/f31 O_uc ||
3538                 error "multiop_bg_pause for $DIR/f31 failed"
3539         MULTIPID=$!
3540         $MULTIOP $DIR/f31c Ouc
3541         kill -USR1 $MULTIPID
3542         wait $MULTIPID
3543 }
3544 run_test 31c "open-unlink file with multiple links ============="
3545
3546 test_31d() {
3547         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3548         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3549 }
3550 run_test 31d "remove of open directory ========================="
3551
3552 test_31e() { # bug 2904
3553         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3554 }
3555 run_test 31e "remove of open non-empty directory ==============="
3556
3557 test_31f() { # bug 4554
3558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3559
3560         set -vx
3561         test_mkdir $DIR/d31f
3562         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3563         cp /etc/hosts $DIR/d31f
3564         ls -l $DIR/d31f
3565         $LFS getstripe $DIR/d31f/hosts
3566         multiop_bg_pause $DIR/d31f D_c || return 1
3567         MULTIPID=$!
3568
3569         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3570         test_mkdir $DIR/d31f
3571         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3572         cp /etc/hosts $DIR/d31f
3573         ls -l $DIR/d31f
3574         $LFS getstripe $DIR/d31f/hosts
3575         multiop_bg_pause $DIR/d31f D_c || return 1
3576         MULTIPID2=$!
3577
3578         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3579         wait $MULTIPID || error "first opendir $MULTIPID failed"
3580
3581         sleep 6
3582
3583         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3584         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3585         set +vx
3586 }
3587 run_test 31f "remove of open directory with open-unlink file ==="
3588
3589 test_31g() {
3590         echo "-- cross directory link --"
3591         test_mkdir -c1 $DIR/${tdir}ga
3592         test_mkdir -c1 $DIR/${tdir}gb
3593         touch $DIR/${tdir}ga/f
3594         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3595         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3596         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3597         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3598         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3599 }
3600 run_test 31g "cross directory link==============="
3601
3602 test_31h() {
3603         echo "-- cross directory link --"
3604         test_mkdir -c1 $DIR/${tdir}
3605         test_mkdir -c1 $DIR/${tdir}/dir
3606         touch $DIR/${tdir}/f
3607         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3608         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3609         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3610         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3611         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3612 }
3613 run_test 31h "cross directory link under child==============="
3614
3615 test_31i() {
3616         echo "-- cross directory link --"
3617         test_mkdir -c1 $DIR/$tdir
3618         test_mkdir -c1 $DIR/$tdir/dir
3619         touch $DIR/$tdir/dir/f
3620         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3621         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3622         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3623         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3624         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3625 }
3626 run_test 31i "cross directory link under parent==============="
3627
3628 test_31j() {
3629         test_mkdir -c1 -p $DIR/$tdir
3630         test_mkdir -c1 -p $DIR/$tdir/dir1
3631         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3632         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3633         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3634         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3635         return 0
3636 }
3637 run_test 31j "link for directory==============="
3638
3639 test_31k() {
3640         test_mkdir -c1 -p $DIR/$tdir
3641         touch $DIR/$tdir/s
3642         touch $DIR/$tdir/exist
3643         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3644         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3645         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3646         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3647         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3648         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3649         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3650         return 0
3651 }
3652 run_test 31k "link to file: the same, non-existing, dir==============="
3653
3654 test_31m() {
3655         mkdir $DIR/d31m
3656         touch $DIR/d31m/s
3657         mkdir $DIR/d31m2
3658         touch $DIR/d31m2/exist
3659         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3660         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3661         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3662         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3663         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3664         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3665         return 0
3666 }
3667 run_test 31m "link to file: the same, non-existing, dir==============="
3668
3669 test_31n() {
3670         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3671         nlink=$(stat --format=%h $DIR/$tfile)
3672         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3673         local fd=$(free_fd)
3674         local cmd="exec $fd<$DIR/$tfile"
3675         eval $cmd
3676         cmd="exec $fd<&-"
3677         trap "eval $cmd" EXIT
3678         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3679         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3680         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3681         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3682         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3683         eval $cmd
3684 }
3685 run_test 31n "check link count of unlinked file"
3686
3687 link_one() {
3688         local tempfile=$(mktemp $1_XXXXXX)
3689         mlink $tempfile $1 2> /dev/null &&
3690                 echo "$BASHPID: link $tempfile to $1 succeeded"
3691         munlink $tempfile
3692 }
3693
3694 test_31o() { # LU-2901
3695         test_mkdir $DIR/$tdir
3696         for LOOP in $(seq 100); do
3697                 rm -f $DIR/$tdir/$tfile*
3698                 for THREAD in $(seq 8); do
3699                         link_one $DIR/$tdir/$tfile.$LOOP &
3700                 done
3701                 wait
3702                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3703                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3704                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3705                         break || true
3706         done
3707 }
3708 run_test 31o "duplicate hard links with same filename"
3709
3710 test_31p() {
3711         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3712
3713         test_mkdir $DIR/$tdir
3714         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3715         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3716
3717         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3718                 error "open unlink test1 failed"
3719         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3720                 error "open unlink test2 failed"
3721
3722         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3723                 error "test1 still exists"
3724         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3725                 error "test2 still exists"
3726 }
3727 run_test 31p "remove of open striped directory"
3728
3729 test_31q() {
3730         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3731
3732         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3733         index=$($LFS getdirstripe -i $DIR/$tdir)
3734         [ $index -eq 3 ] || error "first stripe index $index != 3"
3735         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3736         [ $index -eq 1 ] || error "second stripe index $index != 1"
3737
3738         # when "-c <stripe_count>" is set, the number of MDTs specified after
3739         # "-i" should equal to the stripe count
3740         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3741 }
3742 run_test 31q "create striped directory on specific MDTs"
3743
3744 #LU-14949
3745 test_31r() {
3746         touch $DIR/$tfile.target
3747         touch $DIR/$tfile.source
3748
3749         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3750         $LCTL set_param fail_loc=0x1419 fail_val=3
3751         cat $DIR/$tfile.target &
3752         CATPID=$!
3753
3754         # Guarantee open is waiting before we get here
3755         sleep 1
3756         mv $DIR/$tfile.source $DIR/$tfile.target
3757
3758         wait $CATPID
3759         RC=$?
3760         if [[ $RC -ne 0 ]]; then
3761                 error "open with cat failed, rc=$RC"
3762         fi
3763 }
3764 run_test 31r "open-rename(replace) race"
3765
3766 cleanup_test32_mount() {
3767         local rc=0
3768         trap 0
3769         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3770         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3771         losetup -d $loopdev || true
3772         rm -rf $DIR/$tdir
3773         return $rc
3774 }
3775
3776 test_32a() {
3777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3778
3779         echo "== more mountpoints and symlinks ================="
3780         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3781         trap cleanup_test32_mount EXIT
3782         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3783         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3784                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3785         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3786                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3787         cleanup_test32_mount
3788 }
3789 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3790
3791 test_32b() {
3792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3793
3794         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3795         trap cleanup_test32_mount EXIT
3796         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3797         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3798                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3799         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3800                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3801         cleanup_test32_mount
3802 }
3803 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3804
3805 test_32c() {
3806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3807
3808         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3809         trap cleanup_test32_mount EXIT
3810         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3811         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3812                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3813         test_mkdir -p $DIR/$tdir/d2/test_dir
3814         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3815                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3816         cleanup_test32_mount
3817 }
3818 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3819
3820 test_32d() {
3821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3822
3823         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3824         trap cleanup_test32_mount EXIT
3825         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3826         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3827                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3828         test_mkdir -p $DIR/$tdir/d2/test_dir
3829         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3830                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3831         cleanup_test32_mount
3832 }
3833 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3834
3835 test_32e() {
3836         rm -fr $DIR/$tdir
3837         test_mkdir -p $DIR/$tdir/tmp
3838         local tmp_dir=$DIR/$tdir/tmp
3839         ln -s $DIR/$tdir $tmp_dir/symlink11
3840         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3841         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3842         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3843 }
3844 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3845
3846 test_32f() {
3847         rm -fr $DIR/$tdir
3848         test_mkdir -p $DIR/$tdir/tmp
3849         local tmp_dir=$DIR/$tdir/tmp
3850         ln -s $DIR/$tdir $tmp_dir/symlink11
3851         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3852         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3853         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3854 }
3855 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3856
3857 test_32g() {
3858         local tmp_dir=$DIR/$tdir/tmp
3859         test_mkdir -p $tmp_dir
3860         test_mkdir $DIR/${tdir}2
3861         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3862         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3863         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3864         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3865         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3866         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3867 }
3868 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3869
3870 test_32h() {
3871         rm -fr $DIR/$tdir $DIR/${tdir}2
3872         tmp_dir=$DIR/$tdir/tmp
3873         test_mkdir -p $tmp_dir
3874         test_mkdir $DIR/${tdir}2
3875         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3876         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3877         ls $tmp_dir/symlink12 || error "listing symlink12"
3878         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3879 }
3880 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3881
3882 test_32i() {
3883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3884
3885         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3886         trap cleanup_test32_mount EXIT
3887         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3888         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3889                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3890         touch $DIR/$tdir/test_file
3891         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3892                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3893         cleanup_test32_mount
3894 }
3895 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3896
3897 test_32j() {
3898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3899
3900         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3901         trap cleanup_test32_mount EXIT
3902         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3903         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3904                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3905         touch $DIR/$tdir/test_file
3906         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3907                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3908         cleanup_test32_mount
3909 }
3910 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3911
3912 test_32k() {
3913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3914
3915         rm -fr $DIR/$tdir
3916         trap cleanup_test32_mount EXIT
3917         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3918         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3919                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3920         test_mkdir -p $DIR/$tdir/d2
3921         touch $DIR/$tdir/d2/test_file || error "touch failed"
3922         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3923                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3924         cleanup_test32_mount
3925 }
3926 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3927
3928 test_32l() {
3929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3930
3931         rm -fr $DIR/$tdir
3932         trap cleanup_test32_mount EXIT
3933         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3934         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3935                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3936         test_mkdir -p $DIR/$tdir/d2
3937         touch $DIR/$tdir/d2/test_file || error "touch failed"
3938         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3939                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3940         cleanup_test32_mount
3941 }
3942 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3943
3944 test_32m() {
3945         rm -fr $DIR/d32m
3946         test_mkdir -p $DIR/d32m/tmp
3947         TMP_DIR=$DIR/d32m/tmp
3948         ln -s $DIR $TMP_DIR/symlink11
3949         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3950         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3951                 error "symlink11 not a link"
3952         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3953                 error "symlink01 not a link"
3954 }
3955 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3956
3957 test_32n() {
3958         rm -fr $DIR/d32n
3959         test_mkdir -p $DIR/d32n/tmp
3960         TMP_DIR=$DIR/d32n/tmp
3961         ln -s $DIR $TMP_DIR/symlink11
3962         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3963         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3964         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3965 }
3966 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3967
3968 test_32o() {
3969         touch $DIR/$tfile
3970         test_mkdir -p $DIR/d32o/tmp
3971         TMP_DIR=$DIR/d32o/tmp
3972         ln -s $DIR/$tfile $TMP_DIR/symlink12
3973         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3974         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3975                 error "symlink12 not a link"
3976         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3977         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3978                 error "$DIR/d32o/tmp/symlink12 not file type"
3979         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3980                 error "$DIR/d32o/symlink02 not file type"
3981 }
3982 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3983
3984 test_32p() {
3985         log 32p_1
3986         rm -fr $DIR/d32p
3987         log 32p_2
3988         rm -f $DIR/$tfile
3989         log 32p_3
3990         touch $DIR/$tfile
3991         log 32p_4
3992         test_mkdir -p $DIR/d32p/tmp
3993         log 32p_5
3994         TMP_DIR=$DIR/d32p/tmp
3995         log 32p_6
3996         ln -s $DIR/$tfile $TMP_DIR/symlink12
3997         log 32p_7
3998         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3999         log 32p_8
4000         cat $DIR/d32p/tmp/symlink12 ||
4001                 error "Can't open $DIR/d32p/tmp/symlink12"
4002         log 32p_9
4003         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4004         log 32p_10
4005 }
4006 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4007
4008 test_32q() {
4009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4010
4011         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4012         trap cleanup_test32_mount EXIT
4013         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4014         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4015         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4016                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4017         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4018         cleanup_test32_mount
4019 }
4020 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4021
4022 test_32r() {
4023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4024
4025         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4026         trap cleanup_test32_mount EXIT
4027         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4028         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4029         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4030                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4031         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4032         cleanup_test32_mount
4033 }
4034 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4035
4036 test_33aa() {
4037         rm -f $DIR/$tfile
4038         touch $DIR/$tfile
4039         chmod 444 $DIR/$tfile
4040         chown $RUNAS_ID $DIR/$tfile
4041         log 33_1
4042         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4043         log 33_2
4044 }
4045 run_test 33aa "write file with mode 444 (should return error)"
4046
4047 test_33a() {
4048         rm -fr $DIR/$tdir
4049         test_mkdir $DIR/$tdir
4050         chown $RUNAS_ID $DIR/$tdir
4051         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4052                 error "$RUNAS create $tdir/$tfile failed"
4053         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4054                 error "open RDWR" || true
4055 }
4056 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4057
4058 test_33b() {
4059         rm -fr $DIR/$tdir
4060         test_mkdir $DIR/$tdir
4061         chown $RUNAS_ID $DIR/$tdir
4062         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4063 }
4064 run_test 33b "test open file with malformed flags (No panic)"
4065
4066 test_33c() {
4067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4068         remote_ost_nodsh && skip "remote OST with nodsh"
4069
4070         local ostnum
4071         local ostname
4072         local write_bytes
4073         local all_zeros
4074
4075         all_zeros=true
4076         test_mkdir $DIR/$tdir
4077         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4078
4079         sync
4080         for ostnum in $(seq $OSTCOUNT); do
4081                 # test-framework's OST numbering is one-based, while Lustre's
4082                 # is zero-based
4083                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4084                 # check if at least some write_bytes stats are counted
4085                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4086                               obdfilter.$ostname.stats |
4087                               awk '/^write_bytes/ {print $7}' )
4088                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4089                 if (( ${write_bytes:-0} > 0 )); then
4090                         all_zeros=false
4091                         break
4092                 fi
4093         done
4094
4095         $all_zeros || return 0
4096
4097         # Write four bytes
4098         echo foo > $DIR/$tdir/bar
4099         # Really write them
4100         sync
4101
4102         # Total up write_bytes after writing.  We'd better find non-zeros.
4103         for ostnum in $(seq $OSTCOUNT); do
4104                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4105                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4106                               obdfilter/$ostname/stats |
4107                               awk '/^write_bytes/ {print $7}' )
4108                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4109                 if (( ${write_bytes:-0} > 0 )); then
4110                         all_zeros=false
4111                         break
4112                 fi
4113         done
4114
4115         if $all_zeros; then
4116                 for ostnum in $(seq $OSTCOUNT); do
4117                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4118                         echo "Check write_bytes is in obdfilter.*.stats:"
4119                         do_facet ost$ostnum lctl get_param -n \
4120                                 obdfilter.$ostname.stats
4121                 done
4122                 error "OST not keeping write_bytes stats (b=22312)"
4123         fi
4124 }
4125 run_test 33c "test write_bytes stats"
4126
4127 test_33d() {
4128         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4130
4131         local MDTIDX=1
4132         local remote_dir=$DIR/$tdir/remote_dir
4133
4134         test_mkdir $DIR/$tdir
4135         $LFS mkdir -i $MDTIDX $remote_dir ||
4136                 error "create remote directory failed"
4137
4138         touch $remote_dir/$tfile
4139         chmod 444 $remote_dir/$tfile
4140         chown $RUNAS_ID $remote_dir/$tfile
4141
4142         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4143
4144         chown $RUNAS_ID $remote_dir
4145         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4146                                         error "create" || true
4147         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4148                                     error "open RDWR" || true
4149         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4150 }
4151 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4152
4153 test_33e() {
4154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4155
4156         mkdir $DIR/$tdir
4157
4158         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4159         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4160         mkdir $DIR/$tdir/local_dir
4161
4162         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4163         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4164         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4165
4166         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4167                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4168
4169         rmdir $DIR/$tdir/* || error "rmdir failed"
4170
4171         umask 777
4172         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4173         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4174         mkdir $DIR/$tdir/local_dir
4175
4176         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4177         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4178         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4179
4180         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4181                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4182
4183         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4184
4185         umask 000
4186         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4187         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4188         mkdir $DIR/$tdir/local_dir
4189
4190         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4191         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4192         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4193
4194         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4195                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4196 }
4197 run_test 33e "mkdir and striped directory should have same mode"
4198
4199 cleanup_33f() {
4200         trap 0
4201         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4202 }
4203
4204 test_33f() {
4205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4206         remote_mds_nodsh && skip "remote MDS with nodsh"
4207
4208         mkdir $DIR/$tdir
4209         chmod go+rwx $DIR/$tdir
4210         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4211         trap cleanup_33f EXIT
4212
4213         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4214                 error "cannot create striped directory"
4215
4216         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4217                 error "cannot create files in striped directory"
4218
4219         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4220                 error "cannot remove files in striped directory"
4221
4222         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4223                 error "cannot remove striped directory"
4224
4225         cleanup_33f
4226 }
4227 run_test 33f "nonroot user can create, access, and remove a striped directory"
4228
4229 test_33g() {
4230         mkdir -p $DIR/$tdir/dir2
4231
4232         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4233         echo $err
4234         [[ $err =~ "exists" ]] || error "Not exists error"
4235 }
4236 run_test 33g "nonroot user create already existing root created file"
4237
4238 test_33h() {
4239         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4240         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4241                 skip "Need MDS version at least 2.13.50"
4242
4243         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4244                 error "mkdir $tdir failed"
4245         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4246
4247         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4248         local index2
4249
4250         for fname in $DIR/$tdir/$tfile.bak \
4251                      $DIR/$tdir/$tfile.SAV \
4252                      $DIR/$tdir/$tfile.orig \
4253                      $DIR/$tdir/$tfile~; do
4254                 touch $fname  || error "touch $fname failed"
4255                 index2=$($LFS getstripe -m $fname)
4256                 [ $index -eq $index2 ] ||
4257                         error "$fname MDT index mismatch $index != $index2"
4258         done
4259
4260         local failed=0
4261         for i in {1..250}; do
4262                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4263                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4264                         touch $fname  || error "touch $fname failed"
4265                         index2=$($LFS getstripe -m $fname)
4266                         if [[ $index != $index2 ]]; then
4267                                 failed=$((failed + 1))
4268                                 echo "$fname MDT index mismatch $index != $index2"
4269                         fi
4270                 done
4271         done
4272         echo "$failed MDT index mismatches"
4273         (( failed < 20 )) || error "MDT index mismatch $failed times"
4274
4275 }
4276 run_test 33h "temp file is located on the same MDT as target"
4277
4278 test_33i()
4279 {
4280         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4281
4282         local FNAME=$(str_repeat 'f' 250)
4283
4284         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4285         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4286
4287         local count
4288         local total
4289
4290         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4291
4292         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4293
4294         lctl --device %$MDC deactivate
4295         stack_trap "lctl --device %$MDC activate"
4296         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4297         total=$(\ls -l $DIR/$tdir | wc -l)
4298         # "ls -l" will list total in the first line
4299         total=$((total - 1))
4300         (( total + count == 1000 )) ||
4301                 error "ls list $total files, $count files on MDT1"
4302 }
4303 run_test 33i "striped directory can be accessed when one MDT is down"
4304
4305 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4306 test_34a() {
4307         rm -f $DIR/f34
4308         $MCREATE $DIR/f34 || error "mcreate failed"
4309         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4310                 error "getstripe failed"
4311         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4312         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4313                 error "getstripe failed"
4314         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4315                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4316 }
4317 run_test 34a "truncate file that has not been opened ==========="
4318
4319 test_34b() {
4320         [ ! -f $DIR/f34 ] && test_34a
4321         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4322                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4323         $OPENFILE -f O_RDONLY $DIR/f34
4324         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4325                 error "getstripe failed"
4326         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4327                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4328 }
4329 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4330
4331 test_34c() {
4332         [ ! -f $DIR/f34 ] && test_34a
4333         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4334                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4335         $OPENFILE -f O_RDWR $DIR/f34
4336         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4337                 error "$LFS getstripe failed"
4338         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4339                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4340 }
4341 run_test 34c "O_RDWR opening file-with-size works =============="
4342
4343 test_34d() {
4344         [ ! -f $DIR/f34 ] && test_34a
4345         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4346                 error "dd failed"
4347         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4348                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4349         rm $DIR/f34
4350 }
4351 run_test 34d "write to sparse file ============================="
4352
4353 test_34e() {
4354         rm -f $DIR/f34e
4355         $MCREATE $DIR/f34e || error "mcreate failed"
4356         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4357         $CHECKSTAT -s 1000 $DIR/f34e ||
4358                 error "Size of $DIR/f34e not equal to 1000 bytes"
4359         $OPENFILE -f O_RDWR $DIR/f34e
4360         $CHECKSTAT -s 1000 $DIR/f34e ||
4361                 error "Size of $DIR/f34e not equal to 1000 bytes"
4362 }
4363 run_test 34e "create objects, some with size and some without =="
4364
4365 test_34f() { # bug 6242, 6243
4366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4367
4368         SIZE34F=48000
4369         rm -f $DIR/f34f
4370         $MCREATE $DIR/f34f || error "mcreate failed"
4371         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4372         dd if=$DIR/f34f of=$TMP/f34f
4373         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4374         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4375         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4376         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4377         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4378 }
4379 run_test 34f "read from a file with no objects until EOF ======="
4380
4381 test_34g() {
4382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4383
4384         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4385                 error "dd failed"
4386         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4387         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4388                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4389         cancel_lru_locks osc
4390         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4391                 error "wrong size after lock cancel"
4392
4393         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4394         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4395                 error "expanding truncate failed"
4396         cancel_lru_locks osc
4397         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4398                 error "wrong expanded size after lock cancel"
4399 }
4400 run_test 34g "truncate long file ==============================="
4401
4402 test_34h() {
4403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4404
4405         local gid=10
4406         local sz=1000
4407
4408         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4409         sync # Flush the cache so that multiop below does not block on cache
4410              # flush when getting the group lock
4411         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4412         MULTIPID=$!
4413
4414         # Since just timed wait is not good enough, let's do a sync write
4415         # that way we are sure enough time for a roundtrip + processing
4416         # passed + 2 seconds of extra margin.
4417         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4418         rm $DIR/${tfile}-1
4419         sleep 2
4420
4421         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4422                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4423                 kill -9 $MULTIPID
4424         fi
4425         wait $MULTIPID
4426         local nsz=`stat -c %s $DIR/$tfile`
4427         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4428 }
4429 run_test 34h "ftruncate file under grouplock should not block"
4430
4431 test_35a() {
4432         cp /bin/sh $DIR/f35a
4433         chmod 444 $DIR/f35a
4434         chown $RUNAS_ID $DIR/f35a
4435         $RUNAS $DIR/f35a && error || true
4436         rm $DIR/f35a
4437 }
4438 run_test 35a "exec file with mode 444 (should return and not leak)"
4439
4440 test_36a() {
4441         rm -f $DIR/f36
4442         utime $DIR/f36 || error "utime failed for MDS"
4443 }
4444 run_test 36a "MDS utime check (mknod, utime)"
4445
4446 test_36b() {
4447         echo "" > $DIR/f36
4448         utime $DIR/f36 || error "utime failed for OST"
4449 }
4450 run_test 36b "OST utime check (open, utime)"
4451
4452 test_36c() {
4453         rm -f $DIR/d36/f36
4454         test_mkdir $DIR/d36
4455         chown $RUNAS_ID $DIR/d36
4456         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4457 }
4458 run_test 36c "non-root MDS utime check (mknod, utime)"
4459
4460 test_36d() {
4461         [ ! -d $DIR/d36 ] && test_36c
4462         echo "" > $DIR/d36/f36
4463         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4464 }
4465 run_test 36d "non-root OST utime check (open, utime)"
4466
4467 test_36e() {
4468         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4469
4470         test_mkdir $DIR/$tdir
4471         touch $DIR/$tdir/$tfile
4472         $RUNAS utime $DIR/$tdir/$tfile &&
4473                 error "utime worked, expected failure" || true
4474 }
4475 run_test 36e "utime on non-owned file (should return error)"
4476
4477 subr_36fh() {
4478         local fl="$1"
4479         local LANG_SAVE=$LANG
4480         local LC_LANG_SAVE=$LC_LANG
4481         export LANG=C LC_LANG=C # for date language
4482
4483         DATESTR="Dec 20  2000"
4484         test_mkdir $DIR/$tdir
4485         lctl set_param fail_loc=$fl
4486         date; date +%s
4487         cp /etc/hosts $DIR/$tdir/$tfile
4488         sync & # write RPC generated with "current" inode timestamp, but delayed
4489         sleep 1
4490         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4491         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4492         cancel_lru_locks $OSC
4493         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4494         date; date +%s
4495         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4496                 echo "BEFORE: $LS_BEFORE" && \
4497                 echo "AFTER : $LS_AFTER" && \
4498                 echo "WANT  : $DATESTR" && \
4499                 error "$DIR/$tdir/$tfile timestamps changed" || true
4500
4501         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4502 }
4503
4504 test_36f() {
4505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4506
4507         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4508         subr_36fh "0x80000214"
4509 }
4510 run_test 36f "utime on file racing with OST BRW write =========="
4511
4512 test_36g() {
4513         remote_ost_nodsh && skip "remote OST with nodsh"
4514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4515         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4516                 skip "Need MDS version at least 2.12.51"
4517
4518         local fmd_max_age
4519         local fmd
4520         local facet="ost1"
4521         local tgt="obdfilter"
4522
4523         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4524
4525         test_mkdir $DIR/$tdir
4526         fmd_max_age=$(do_facet $facet \
4527                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4528                 head -n 1")
4529
4530         echo "FMD max age: ${fmd_max_age}s"
4531         touch $DIR/$tdir/$tfile
4532         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4533                 gawk '{cnt=cnt+$1}  END{print cnt}')
4534         echo "FMD before: $fmd"
4535         [[ $fmd == 0 ]] &&
4536                 error "FMD wasn't create by touch"
4537         sleep $((fmd_max_age + 12))
4538         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4539                 gawk '{cnt=cnt+$1}  END{print cnt}')
4540         echo "FMD after: $fmd"
4541         [[ $fmd == 0 ]] ||
4542                 error "FMD wasn't expired by ping"
4543 }
4544 run_test 36g "FMD cache expiry ====================="
4545
4546 test_36h() {
4547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4548
4549         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4550         subr_36fh "0x80000227"
4551 }
4552 run_test 36h "utime on file racing with OST BRW write =========="
4553
4554 test_36i() {
4555         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4556
4557         test_mkdir $DIR/$tdir
4558         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4559
4560         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4561         local new_mtime=$((mtime + 200))
4562
4563         #change Modify time of striped dir
4564         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4565                         error "change mtime failed"
4566
4567         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4568
4569         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4570 }
4571 run_test 36i "change mtime on striped directory"
4572
4573 # test_37 - duplicate with tests 32q 32r
4574
4575 test_38() {
4576         local file=$DIR/$tfile
4577         touch $file
4578         openfile -f O_DIRECTORY $file
4579         local RC=$?
4580         local ENOTDIR=20
4581         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4582         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4583 }
4584 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4585
4586 test_39a() { # was test_39
4587         touch $DIR/$tfile
4588         touch $DIR/${tfile}2
4589 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4590 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4591 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4592         sleep 2
4593         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4594         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4595                 echo "mtime"
4596                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4597                 echo "atime"
4598                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4599                 echo "ctime"
4600                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4601                 error "O_TRUNC didn't change timestamps"
4602         fi
4603 }
4604 run_test 39a "mtime changed on create"
4605
4606 test_39b() {
4607         test_mkdir -c1 $DIR/$tdir
4608         cp -p /etc/passwd $DIR/$tdir/fopen
4609         cp -p /etc/passwd $DIR/$tdir/flink
4610         cp -p /etc/passwd $DIR/$tdir/funlink
4611         cp -p /etc/passwd $DIR/$tdir/frename
4612         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4613
4614         sleep 1
4615         echo "aaaaaa" >> $DIR/$tdir/fopen
4616         echo "aaaaaa" >> $DIR/$tdir/flink
4617         echo "aaaaaa" >> $DIR/$tdir/funlink
4618         echo "aaaaaa" >> $DIR/$tdir/frename
4619
4620         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4621         local link_new=`stat -c %Y $DIR/$tdir/flink`
4622         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4623         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4624
4625         cat $DIR/$tdir/fopen > /dev/null
4626         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4627         rm -f $DIR/$tdir/funlink2
4628         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4629
4630         for (( i=0; i < 2; i++ )) ; do
4631                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4632                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4633                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4634                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4635
4636                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4637                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4638                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4639                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4640
4641                 cancel_lru_locks $OSC
4642                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4643         done
4644 }
4645 run_test 39b "mtime change on open, link, unlink, rename  ======"
4646
4647 # this should be set to past
4648 TEST_39_MTIME=`date -d "1 year ago" +%s`
4649
4650 # bug 11063
4651 test_39c() {
4652         touch $DIR1/$tfile
4653         sleep 2
4654         local mtime0=`stat -c %Y $DIR1/$tfile`
4655
4656         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658         [ "$mtime1" = $TEST_39_MTIME ] || \
4659                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4660
4661         local d1=`date +%s`
4662         echo hello >> $DIR1/$tfile
4663         local d2=`date +%s`
4664         local mtime2=`stat -c %Y $DIR1/$tfile`
4665         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4666                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4667
4668         mv $DIR1/$tfile $DIR1/$tfile-1
4669
4670         for (( i=0; i < 2; i++ )) ; do
4671                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4672                 [ "$mtime2" = "$mtime3" ] || \
4673                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4674
4675                 cancel_lru_locks $OSC
4676                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4677         done
4678 }
4679 run_test 39c "mtime change on rename ==========================="
4680
4681 # bug 21114
4682 test_39d() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         touch $DIR1/$tfile
4686         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime=`stat -c %Y $DIR1/$tfile`
4690                 [ $mtime = $TEST_39_MTIME ] || \
4691                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39d "create, utime, stat =============================="
4698
4699 # bug 21114
4700 test_39e() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         local mtime1=`stat -c %Y $DIR1/$tfile`
4705
4706         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4707
4708         for (( i=0; i < 2; i++ )) ; do
4709                 local mtime2=`stat -c %Y $DIR1/$tfile`
4710                 [ $mtime2 = $TEST_39_MTIME ] || \
4711                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4712
4713                 cancel_lru_locks $OSC
4714                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4715         done
4716 }
4717 run_test 39e "create, stat, utime, stat ========================"
4718
4719 # bug 21114
4720 test_39f() {
4721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4722
4723         touch $DIR1/$tfile
4724         mtime1=`stat -c %Y $DIR1/$tfile`
4725
4726         sleep 2
4727         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4728
4729         for (( i=0; i < 2; i++ )) ; do
4730                 local mtime2=`stat -c %Y $DIR1/$tfile`
4731                 [ $mtime2 = $TEST_39_MTIME ] || \
4732                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4733
4734                 cancel_lru_locks $OSC
4735                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4736         done
4737 }
4738 run_test 39f "create, stat, sleep, utime, stat ================="
4739
4740 # bug 11063
4741 test_39g() {
4742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4743
4744         echo hello >> $DIR1/$tfile
4745         local mtime1=`stat -c %Y $DIR1/$tfile`
4746
4747         sleep 2
4748         chmod o+r $DIR1/$tfile
4749
4750         for (( i=0; i < 2; i++ )) ; do
4751                 local mtime2=`stat -c %Y $DIR1/$tfile`
4752                 [ "$mtime1" = "$mtime2" ] || \
4753                         error "lost mtime: $mtime2, should be $mtime1"
4754
4755                 cancel_lru_locks $OSC
4756                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4757         done
4758 }
4759 run_test 39g "write, chmod, stat ==============================="
4760
4761 # bug 11063
4762 test_39h() {
4763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4764
4765         touch $DIR1/$tfile
4766         sleep 1
4767
4768         local d1=`date`
4769         echo hello >> $DIR1/$tfile
4770         local mtime1=`stat -c %Y $DIR1/$tfile`
4771
4772         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4773         local d2=`date`
4774         if [ "$d1" != "$d2" ]; then
4775                 echo "write and touch not within one second"
4776         else
4777                 for (( i=0; i < 2; i++ )) ; do
4778                         local mtime2=`stat -c %Y $DIR1/$tfile`
4779                         [ "$mtime2" = $TEST_39_MTIME ] || \
4780                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4781
4782                         cancel_lru_locks $OSC
4783                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4784                 done
4785         fi
4786 }
4787 run_test 39h "write, utime within one second, stat ============="
4788
4789 test_39i() {
4790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4791
4792         touch $DIR1/$tfile
4793         sleep 1
4794
4795         echo hello >> $DIR1/$tfile
4796         local mtime1=`stat -c %Y $DIR1/$tfile`
4797
4798         mv $DIR1/$tfile $DIR1/$tfile-1
4799
4800         for (( i=0; i < 2; i++ )) ; do
4801                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4802
4803                 [ "$mtime1" = "$mtime2" ] || \
4804                         error "lost mtime: $mtime2, should be $mtime1"
4805
4806                 cancel_lru_locks $OSC
4807                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4808         done
4809 }
4810 run_test 39i "write, rename, stat =============================="
4811
4812 test_39j() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814
4815         start_full_debug_logging
4816         touch $DIR1/$tfile
4817         sleep 1
4818
4819         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4820         lctl set_param fail_loc=0x80000412
4821         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4822                 error "multiop failed"
4823         local multipid=$!
4824         local mtime1=`stat -c %Y $DIR1/$tfile`
4825
4826         mv $DIR1/$tfile $DIR1/$tfile-1
4827
4828         kill -USR1 $multipid
4829         wait $multipid || error "multiop close failed"
4830
4831         for (( i=0; i < 2; i++ )) ; do
4832                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4833                 [ "$mtime1" = "$mtime2" ] ||
4834                         error "mtime is lost on close: $mtime2, " \
4835                               "should be $mtime1"
4836
4837                 cancel_lru_locks
4838                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4839         done
4840         lctl set_param fail_loc=0
4841         stop_full_debug_logging
4842 }
4843 run_test 39j "write, rename, close, stat ======================="
4844
4845 test_39k() {
4846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4847
4848         touch $DIR1/$tfile
4849         sleep 1
4850
4851         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4852         local multipid=$!
4853         local mtime1=`stat -c %Y $DIR1/$tfile`
4854
4855         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4856
4857         kill -USR1 $multipid
4858         wait $multipid || error "multiop close failed"
4859
4860         for (( i=0; i < 2; i++ )) ; do
4861                 local mtime2=`stat -c %Y $DIR1/$tfile`
4862
4863                 [ "$mtime2" = $TEST_39_MTIME ] || \
4864                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4865
4866                 cancel_lru_locks
4867                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4868         done
4869 }
4870 run_test 39k "write, utime, close, stat ========================"
4871
4872 # this should be set to future
4873 TEST_39_ATIME=`date -d "1 year" +%s`
4874
4875 test_39l() {
4876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4877         remote_mds_nodsh && skip "remote MDS with nodsh"
4878
4879         local atime_diff=$(do_facet $SINGLEMDS \
4880                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4881         rm -rf $DIR/$tdir
4882         mkdir_on_mdt0 $DIR/$tdir
4883
4884         # test setting directory atime to future
4885         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4886         local atime=$(stat -c %X $DIR/$tdir)
4887         [ "$atime" = $TEST_39_ATIME ] ||
4888                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4889
4890         # test setting directory atime from future to now
4891         local now=$(date +%s)
4892         touch -a -d @$now $DIR/$tdir
4893
4894         atime=$(stat -c %X $DIR/$tdir)
4895         [ "$atime" -eq "$now"  ] ||
4896                 error "atime is not updated from future: $atime, $now"
4897
4898         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4899         sleep 3
4900
4901         # test setting directory atime when now > dir atime + atime_diff
4902         local d1=$(date +%s)
4903         ls $DIR/$tdir
4904         local d2=$(date +%s)
4905         cancel_lru_locks mdc
4906         atime=$(stat -c %X $DIR/$tdir)
4907         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4908                 error "atime is not updated  : $atime, should be $d2"
4909
4910         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4911         sleep 3
4912
4913         # test not setting directory atime when now < dir atime + atime_diff
4914         ls $DIR/$tdir
4915         cancel_lru_locks mdc
4916         atime=$(stat -c %X $DIR/$tdir)
4917         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4918                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4919
4920         do_facet $SINGLEMDS \
4921                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4922 }
4923 run_test 39l "directory atime update ==========================="
4924
4925 test_39m() {
4926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4927
4928         touch $DIR1/$tfile
4929         sleep 2
4930         local far_past_mtime=$(date -d "May 29 1953" +%s)
4931         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4932
4933         touch -m -d @$far_past_mtime $DIR1/$tfile
4934         touch -a -d @$far_past_atime $DIR1/$tfile
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4938                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4939                         error "atime or mtime set incorrectly"
4940
4941                 cancel_lru_locks $OSC
4942                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4943         done
4944 }
4945 run_test 39m "test atime and mtime before 1970"
4946
4947 test_39n() { # LU-3832
4948         remote_mds_nodsh && skip "remote MDS with nodsh"
4949
4950         local atime_diff=$(do_facet $SINGLEMDS \
4951                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4952         local atime0
4953         local atime1
4954         local atime2
4955
4956         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4957
4958         rm -rf $DIR/$tfile
4959         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4960         atime0=$(stat -c %X $DIR/$tfile)
4961
4962         sleep 5
4963         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4964         atime1=$(stat -c %X $DIR/$tfile)
4965
4966         sleep 5
4967         cancel_lru_locks mdc
4968         cancel_lru_locks osc
4969         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4970         atime2=$(stat -c %X $DIR/$tfile)
4971
4972         do_facet $SINGLEMDS \
4973                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4974
4975         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4976         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4977 }
4978 run_test 39n "check that O_NOATIME is honored"
4979
4980 test_39o() {
4981         TESTDIR=$DIR/$tdir/$tfile
4982         [ -e $TESTDIR ] && rm -rf $TESTDIR
4983         mkdir -p $TESTDIR
4984         cd $TESTDIR
4985         links1=2
4986         ls
4987         mkdir a b
4988         ls
4989         links2=$(stat -c %h .)
4990         [ $(($links1 + 2)) != $links2 ] &&
4991                 error "wrong links count $(($links1 + 2)) != $links2"
4992         rmdir b
4993         links3=$(stat -c %h .)
4994         [ $(($links1 + 1)) != $links3 ] &&
4995                 error "wrong links count $links1 != $links3"
4996         return 0
4997 }
4998 run_test 39o "directory cached attributes updated after create"
4999
5000 test_39p() {
5001         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5002
5003         local MDTIDX=1
5004         TESTDIR=$DIR/$tdir/$tdir
5005         [ -e $TESTDIR ] && rm -rf $TESTDIR
5006         test_mkdir -p $TESTDIR
5007         cd $TESTDIR
5008         links1=2
5009         ls
5010         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5011         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5012         ls
5013         links2=$(stat -c %h .)
5014         [ $(($links1 + 2)) != $links2 ] &&
5015                 error "wrong links count $(($links1 + 2)) != $links2"
5016         rmdir remote_dir2
5017         links3=$(stat -c %h .)
5018         [ $(($links1 + 1)) != $links3 ] &&
5019                 error "wrong links count $links1 != $links3"
5020         return 0
5021 }
5022 run_test 39p "remote directory cached attributes updated after create ========"
5023
5024 test_39r() {
5025         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5026                 skip "no atime update on old OST"
5027         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5028                 skip_env "ldiskfs only test"
5029         fi
5030
5031         local saved_adiff
5032         saved_adiff=$(do_facet ost1 \
5033                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5034         stack_trap "do_facet ost1 \
5035                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5036
5037         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5038
5039         $LFS setstripe -i 0 $DIR/$tfile
5040         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5041                 error "can't write initial file"
5042         cancel_lru_locks osc
5043
5044         # exceed atime_diff and access file
5045         sleep 10
5046         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5047                 error "can't udpate atime"
5048
5049         local atime_cli=$(stat -c %X $DIR/$tfile)
5050         echo "client atime: $atime_cli"
5051         # allow atime update to be written to device
5052         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5053         sleep 5
5054
5055         local ostdev=$(ostdevname 1)
5056         local fid=($(lfs getstripe -y $DIR/$tfile |
5057                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5058         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5059         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5060
5061         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5062         local atime_ost=$(do_facet ost1 "$cmd" |&
5063                           awk -F'[: ]' '/atime:/ { print $4 }')
5064         (( atime_cli == atime_ost )) ||
5065                 error "atime on client $atime_cli != ost $atime_ost"
5066 }
5067 run_test 39r "lazy atime update on OST"
5068
5069 test_39q() { # LU-8041
5070         local testdir=$DIR/$tdir
5071         mkdir -p $testdir
5072         multiop_bg_pause $testdir D_c || error "multiop failed"
5073         local multipid=$!
5074         cancel_lru_locks mdc
5075         kill -USR1 $multipid
5076         local atime=$(stat -c %X $testdir)
5077         [ "$atime" -ne 0 ] || error "atime is zero"
5078 }
5079 run_test 39q "close won't zero out atime"
5080
5081 test_40() {
5082         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5083         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5084                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5085         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5086                 error "$tfile is not 4096 bytes in size"
5087 }
5088 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5089
5090 test_41() {
5091         # bug 1553
5092         small_write $DIR/f41 18
5093 }
5094 run_test 41 "test small file write + fstat ====================="
5095
5096 count_ost_writes() {
5097         lctl get_param -n ${OSC}.*.stats |
5098                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5099                         END { printf("%0.0f", writes) }'
5100 }
5101
5102 # decent default
5103 WRITEBACK_SAVE=500
5104 DIRTY_RATIO_SAVE=40
5105 MAX_DIRTY_RATIO=50
5106 BG_DIRTY_RATIO_SAVE=10
5107 MAX_BG_DIRTY_RATIO=25
5108
5109 start_writeback() {
5110         trap 0
5111         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5112         # dirty_ratio, dirty_background_ratio
5113         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5114                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5115                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5116                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5117         else
5118                 # if file not here, we are a 2.4 kernel
5119                 kill -CONT `pidof kupdated`
5120         fi
5121 }
5122
5123 stop_writeback() {
5124         # setup the trap first, so someone cannot exit the test at the
5125         # exact wrong time and mess up a machine
5126         trap start_writeback EXIT
5127         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5128         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5129                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5130                 sysctl -w vm.dirty_writeback_centisecs=0
5131                 sysctl -w vm.dirty_writeback_centisecs=0
5132                 # save and increase /proc/sys/vm/dirty_ratio
5133                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5134                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5135                 # save and increase /proc/sys/vm/dirty_background_ratio
5136                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5137                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5138         else
5139                 # if file not here, we are a 2.4 kernel
5140                 kill -STOP `pidof kupdated`
5141         fi
5142 }
5143
5144 # ensure that all stripes have some grant before we test client-side cache
5145 setup_test42() {
5146         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5147                 dd if=/dev/zero of=$i bs=4k count=1
5148                 rm $i
5149         done
5150 }
5151
5152 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5153 # file truncation, and file removal.
5154 test_42a() {
5155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5156
5157         setup_test42
5158         cancel_lru_locks $OSC
5159         stop_writeback
5160         sync; sleep 1; sync # just to be safe
5161         BEFOREWRITES=`count_ost_writes`
5162         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5163         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5164         AFTERWRITES=`count_ost_writes`
5165         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5166                 error "$BEFOREWRITES < $AFTERWRITES"
5167         start_writeback
5168 }
5169 run_test 42a "ensure that we don't flush on close"
5170
5171 test_42b() {
5172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5173
5174         setup_test42
5175         cancel_lru_locks $OSC
5176         stop_writeback
5177         sync
5178         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5179         BEFOREWRITES=$(count_ost_writes)
5180         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5181         AFTERWRITES=$(count_ost_writes)
5182         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5183                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5184         fi
5185         BEFOREWRITES=$(count_ost_writes)
5186         sync || error "sync: $?"
5187         AFTERWRITES=$(count_ost_writes)
5188         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5189                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5190         fi
5191         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5192         start_writeback
5193         return 0
5194 }
5195 run_test 42b "test destroy of file with cached dirty data ======"
5196
5197 # if these tests just want to test the effect of truncation,
5198 # they have to be very careful.  consider:
5199 # - the first open gets a {0,EOF}PR lock
5200 # - the first write conflicts and gets a {0, count-1}PW
5201 # - the rest of the writes are under {count,EOF}PW
5202 # - the open for truncate tries to match a {0,EOF}PR
5203 #   for the filesize and cancels the PWs.
5204 # any number of fixes (don't get {0,EOF} on open, match
5205 # composite locks, do smarter file size management) fix
5206 # this, but for now we want these tests to verify that
5207 # the cancellation with truncate intent works, so we
5208 # start the file with a full-file pw lock to match against
5209 # until the truncate.
5210 trunc_test() {
5211         test=$1
5212         file=$DIR/$test
5213         offset=$2
5214         cancel_lru_locks $OSC
5215         stop_writeback
5216         # prime the file with 0,EOF PW to match
5217         touch $file
5218         $TRUNCATE $file 0
5219         sync; sync
5220         # now the real test..
5221         dd if=/dev/zero of=$file bs=1024 count=100
5222         BEFOREWRITES=`count_ost_writes`
5223         $TRUNCATE $file $offset
5224         cancel_lru_locks $OSC
5225         AFTERWRITES=`count_ost_writes`
5226         start_writeback
5227 }
5228
5229 test_42c() {
5230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5231
5232         trunc_test 42c 1024
5233         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5234                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5235         rm $file
5236 }
5237 run_test 42c "test partial truncate of file with cached dirty data"
5238
5239 test_42d() {
5240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5241
5242         trunc_test 42d 0
5243         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5244                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5245         rm $file
5246 }
5247 run_test 42d "test complete truncate of file with cached dirty data"
5248
5249 test_42e() { # bug22074
5250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5251
5252         local TDIR=$DIR/${tdir}e
5253         local pages=16 # hardcoded 16 pages, don't change it.
5254         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5255         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5256         local max_dirty_mb
5257         local warmup_files
5258
5259         test_mkdir $DIR/${tdir}e
5260         $LFS setstripe -c 1 $TDIR
5261         createmany -o $TDIR/f $files
5262
5263         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5264
5265         # we assume that with $OSTCOUNT files, at least one of them will
5266         # be allocated on OST0.
5267         warmup_files=$((OSTCOUNT * max_dirty_mb))
5268         createmany -o $TDIR/w $warmup_files
5269
5270         # write a large amount of data into one file and sync, to get good
5271         # avail_grant number from OST.
5272         for ((i=0; i<$warmup_files; i++)); do
5273                 idx=$($LFS getstripe -i $TDIR/w$i)
5274                 [ $idx -ne 0 ] && continue
5275                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5276                 break
5277         done
5278         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5279         sync
5280         $LCTL get_param $proc_osc0/cur_dirty_bytes
5281         $LCTL get_param $proc_osc0/cur_grant_bytes
5282
5283         # create as much dirty pages as we can while not to trigger the actual
5284         # RPCs directly. but depends on the env, VFS may trigger flush during this
5285         # period, hopefully we are good.
5286         for ((i=0; i<$warmup_files; i++)); do
5287                 idx=$($LFS getstripe -i $TDIR/w$i)
5288                 [ $idx -ne 0 ] && continue
5289                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5290         done
5291         $LCTL get_param $proc_osc0/cur_dirty_bytes
5292         $LCTL get_param $proc_osc0/cur_grant_bytes
5293
5294         # perform the real test
5295         $LCTL set_param $proc_osc0/rpc_stats 0
5296         for ((;i<$files; i++)); do
5297                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5298                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5299         done
5300         sync
5301         $LCTL get_param $proc_osc0/rpc_stats
5302
5303         local percent=0
5304         local have_ppr=false
5305         $LCTL get_param $proc_osc0/rpc_stats |
5306                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5307                         # skip lines until we are at the RPC histogram data
5308                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5309                         $have_ppr || continue
5310
5311                         # we only want the percent stat for < 16 pages
5312                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5313
5314                         percent=$((percent + WPCT))
5315                         if [[ $percent -gt 15 ]]; then
5316                                 error "less than 16-pages write RPCs" \
5317                                       "$percent% > 15%"
5318                                 break
5319                         fi
5320                 done
5321         rm -rf $TDIR
5322 }
5323 run_test 42e "verify sub-RPC writes are not done synchronously"
5324
5325 test_43A() { # was test_43
5326         test_mkdir $DIR/$tdir
5327         cp -p /bin/ls $DIR/$tdir/$tfile
5328         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5329         pid=$!
5330         # give multiop a chance to open
5331         sleep 1
5332
5333         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5334         kill -USR1 $pid
5335         # Wait for multiop to exit
5336         wait $pid
5337 }
5338 run_test 43A "execution of file opened for write should return -ETXTBSY"
5339
5340 test_43a() {
5341         test_mkdir $DIR/$tdir
5342         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5343         $DIR/$tdir/sleep 60 &
5344         SLEEP_PID=$!
5345         # Make sure exec of $tdir/sleep wins race with truncate
5346         sleep 1
5347         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5348         kill $SLEEP_PID
5349 }
5350 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5351
5352 test_43b() {
5353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5354
5355         test_mkdir $DIR/$tdir
5356         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5357         $DIR/$tdir/sleep 60 &
5358         SLEEP_PID=$!
5359         # Make sure exec of $tdir/sleep wins race with truncate
5360         sleep 1
5361         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5362         kill $SLEEP_PID
5363 }
5364 run_test 43b "truncate of file being executed should return -ETXTBSY"
5365
5366 test_43c() {
5367         local testdir="$DIR/$tdir"
5368         test_mkdir $testdir
5369         cp $SHELL $testdir/
5370         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5371                 ( cd $testdir && md5sum -c )
5372 }
5373 run_test 43c "md5sum of copy into lustre"
5374
5375 test_44A() { # was test_44
5376         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5377
5378         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5379         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5380 }
5381 run_test 44A "zero length read from a sparse stripe"
5382
5383 test_44a() {
5384         local nstripe=$($LFS getstripe -c -d $DIR)
5385         [ -z "$nstripe" ] && skip "can't get stripe info"
5386         [[ $nstripe -gt $OSTCOUNT ]] &&
5387                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5388
5389         local stride=$($LFS getstripe -S -d $DIR)
5390         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5391                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5392         fi
5393
5394         OFFSETS="0 $((stride/2)) $((stride-1))"
5395         for offset in $OFFSETS; do
5396                 for i in $(seq 0 $((nstripe-1))); do
5397                         local GLOBALOFFSETS=""
5398                         # size in Bytes
5399                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5400                         local myfn=$DIR/d44a-$size
5401                         echo "--------writing $myfn at $size"
5402                         ll_sparseness_write $myfn $size ||
5403                                 error "ll_sparseness_write"
5404                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5405                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5406                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5407
5408                         for j in $(seq 0 $((nstripe-1))); do
5409                                 # size in Bytes
5410                                 size=$((((j + $nstripe )*$stride + $offset)))
5411                                 ll_sparseness_write $myfn $size ||
5412                                         error "ll_sparseness_write"
5413                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5414                         done
5415                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5416                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5417                         rm -f $myfn
5418                 done
5419         done
5420 }
5421 run_test 44a "test sparse pwrite ==============================="
5422
5423 dirty_osc_total() {
5424         tot=0
5425         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5426                 tot=$(($tot + $d))
5427         done
5428         echo $tot
5429 }
5430 do_dirty_record() {
5431         before=`dirty_osc_total`
5432         echo executing "\"$*\""
5433         eval $*
5434         after=`dirty_osc_total`
5435         echo before $before, after $after
5436 }
5437 test_45() {
5438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5439
5440         f="$DIR/f45"
5441         # Obtain grants from OST if it supports it
5442         echo blah > ${f}_grant
5443         stop_writeback
5444         sync
5445         do_dirty_record "echo blah > $f"
5446         [[ $before -eq $after ]] && error "write wasn't cached"
5447         do_dirty_record "> $f"
5448         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5449         do_dirty_record "echo blah > $f"
5450         [[ $before -eq $after ]] && error "write wasn't cached"
5451         do_dirty_record "sync"
5452         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5453         do_dirty_record "echo blah > $f"
5454         [[ $before -eq $after ]] && error "write wasn't cached"
5455         do_dirty_record "cancel_lru_locks osc"
5456         [[ $before -gt $after ]] ||
5457                 error "lock cancellation didn't lower dirty count"
5458         start_writeback
5459 }
5460 run_test 45 "osc io page accounting ============================"
5461
5462 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5463 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5464 # objects offset and an assert hit when an rpc was built with 1023's mapped
5465 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5466 test_46() {
5467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5468
5469         f="$DIR/f46"
5470         stop_writeback
5471         sync
5472         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5473         sync
5474         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5475         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5476         sync
5477         start_writeback
5478 }
5479 run_test 46 "dirtying a previously written page ================"
5480
5481 # test_47 is removed "Device nodes check" is moved to test_28
5482
5483 test_48a() { # bug 2399
5484         [ "$mds1_FSTYPE" = "zfs" ] &&
5485         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5486                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5487
5488         test_mkdir $DIR/$tdir
5489         cd $DIR/$tdir
5490         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5491         test_mkdir $DIR/$tdir
5492         touch foo || error "'touch foo' failed after recreating cwd"
5493         test_mkdir bar
5494         touch .foo || error "'touch .foo' failed after recreating cwd"
5495         test_mkdir .bar
5496         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5497         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5498         cd . || error "'cd .' failed after recreating cwd"
5499         mkdir . && error "'mkdir .' worked after recreating cwd"
5500         rmdir . && error "'rmdir .' worked after recreating cwd"
5501         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5502         cd .. || error "'cd ..' failed after recreating cwd"
5503 }
5504 run_test 48a "Access renamed working dir (should return errors)="
5505
5506 test_48b() { # bug 2399
5507         rm -rf $DIR/$tdir
5508         test_mkdir $DIR/$tdir
5509         cd $DIR/$tdir
5510         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5511         touch foo && error "'touch foo' worked after removing cwd"
5512         mkdir foo && error "'mkdir foo' worked after removing cwd"
5513         touch .foo && error "'touch .foo' worked after removing cwd"
5514         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5515         ls . > /dev/null && error "'ls .' worked after removing cwd"
5516         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5517         mkdir . && error "'mkdir .' worked after removing cwd"
5518         rmdir . && error "'rmdir .' worked after removing cwd"
5519         ln -s . foo && error "'ln -s .' worked after removing cwd"
5520         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5521 }
5522 run_test 48b "Access removed working dir (should return errors)="
5523
5524 test_48c() { # bug 2350
5525         #lctl set_param debug=-1
5526         #set -vx
5527         rm -rf $DIR/$tdir
5528         test_mkdir -p $DIR/$tdir/dir
5529         cd $DIR/$tdir/dir
5530         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5531         $TRACE touch foo && error "touch foo worked after removing cwd"
5532         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5533         touch .foo && error "touch .foo worked after removing cwd"
5534         mkdir .foo && error "mkdir .foo worked after removing cwd"
5535         $TRACE ls . && error "'ls .' worked after removing cwd"
5536         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5537         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5538         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5539         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5540         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5541 }
5542 run_test 48c "Access removed working subdir (should return errors)"
5543
5544 test_48d() { # bug 2350
5545         #lctl set_param debug=-1
5546         #set -vx
5547         rm -rf $DIR/$tdir
5548         test_mkdir -p $DIR/$tdir/dir
5549         cd $DIR/$tdir/dir
5550         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5551         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5552         $TRACE touch foo && error "'touch foo' worked after removing parent"
5553         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5554         touch .foo && error "'touch .foo' worked after removing parent"
5555         mkdir .foo && error "mkdir .foo worked after removing parent"
5556         $TRACE ls . && error "'ls .' worked after removing parent"
5557         $TRACE ls .. && error "'ls ..' worked after removing parent"
5558         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5559         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5560         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5561         true
5562 }
5563 run_test 48d "Access removed parent subdir (should return errors)"
5564
5565 test_48e() { # bug 4134
5566         #lctl set_param debug=-1
5567         #set -vx
5568         rm -rf $DIR/$tdir
5569         test_mkdir -p $DIR/$tdir/dir
5570         cd $DIR/$tdir/dir
5571         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5572         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5573         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5574         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5575         # On a buggy kernel addition of "touch foo" after cd .. will
5576         # produce kernel oops in lookup_hash_it
5577         touch ../foo && error "'cd ..' worked after recreate parent"
5578         cd $DIR
5579         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5580 }
5581 run_test 48e "Access to recreated parent subdir (should return errors)"
5582
5583 test_48f() {
5584         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5585                 skip "need MDS >= 2.13.55"
5586         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5587         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5588                 skip "needs different host for mdt1 mdt2"
5589         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5590
5591         $LFS mkdir -i0 $DIR/$tdir
5592         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5593
5594         for d in sub1 sub2 sub3; do
5595                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5596                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5597                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5598         done
5599
5600         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5601 }
5602 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5603
5604 test_49() { # LU-1030
5605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5606         remote_ost_nodsh && skip "remote OST with nodsh"
5607
5608         # get ost1 size - $FSNAME-OST0000
5609         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5610                 awk '{ print $4 }')
5611         # write 800M at maximum
5612         [[ $ost1_size -lt 2 ]] && ost1_size=2
5613         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5614
5615         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5616         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5617         local dd_pid=$!
5618
5619         # change max_pages_per_rpc while writing the file
5620         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5621         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5622         # loop until dd process exits
5623         while ps ax -opid | grep -wq $dd_pid; do
5624                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5625                 sleep $((RANDOM % 5 + 1))
5626         done
5627         # restore original max_pages_per_rpc
5628         $LCTL set_param $osc1_mppc=$orig_mppc
5629         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5630 }
5631 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5632
5633 test_50() {
5634         # bug 1485
5635         test_mkdir $DIR/$tdir
5636         cd $DIR/$tdir
5637         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5638 }
5639 run_test 50 "special situations: /proc symlinks  ==============="
5640
5641 test_51a() {    # was test_51
5642         # bug 1516 - create an empty entry right after ".." then split dir
5643         test_mkdir -c1 $DIR/$tdir
5644         touch $DIR/$tdir/foo
5645         $MCREATE $DIR/$tdir/bar
5646         rm $DIR/$tdir/foo
5647         createmany -m $DIR/$tdir/longfile 201
5648         FNUM=202
5649         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5650                 $MCREATE $DIR/$tdir/longfile$FNUM
5651                 FNUM=$(($FNUM + 1))
5652                 echo -n "+"
5653         done
5654         echo
5655         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5656 }
5657 run_test 51a "special situations: split htree with empty entry =="
5658
5659 cleanup_print_lfs_df () {
5660         trap 0
5661         $LFS df
5662         $LFS df -i
5663 }
5664
5665 test_51b() {
5666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5667
5668         local dir=$DIR/$tdir
5669         local nrdirs=$((65536 + 100))
5670
5671         # cleanup the directory
5672         rm -fr $dir
5673
5674         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5675
5676         $LFS df
5677         $LFS df -i
5678         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5679         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5680         [[ $numfree -lt $nrdirs ]] &&
5681                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5682
5683         # need to check free space for the directories as well
5684         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5685         numfree=$(( blkfree / $(fs_inode_ksize) ))
5686         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5687
5688         trap cleanup_print_lfs_df EXIT
5689
5690         # create files
5691         createmany -d $dir/d $nrdirs || {
5692                 unlinkmany $dir/d $nrdirs
5693                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5694         }
5695
5696         # really created :
5697         nrdirs=$(ls -U $dir | wc -l)
5698
5699         # unlink all but 100 subdirectories, then check it still works
5700         local left=100
5701         local delete=$((nrdirs - left))
5702
5703         $LFS df
5704         $LFS df -i
5705
5706         # for ldiskfs the nlink count should be 1, but this is OSD specific
5707         # and so this is listed for informational purposes only
5708         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5709         unlinkmany -d $dir/d $delete ||
5710                 error "unlink of first $delete subdirs failed"
5711
5712         echo "nlink between: $(stat -c %h $dir)"
5713         local found=$(ls -U $dir | wc -l)
5714         [ $found -ne $left ] &&
5715                 error "can't find subdirs: found only $found, expected $left"
5716
5717         unlinkmany -d $dir/d $delete $left ||
5718                 error "unlink of second $left subdirs failed"
5719         # regardless of whether the backing filesystem tracks nlink accurately
5720         # or not, the nlink count shouldn't be more than "." and ".." here
5721         local after=$(stat -c %h $dir)
5722         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5723                 echo "nlink after: $after"
5724
5725         cleanup_print_lfs_df
5726 }
5727 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5728
5729 test_51d() {
5730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5731         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5732         local qos_old
5733
5734         test_mkdir $DIR/$tdir
5735         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5736
5737         qos_old=$(do_facet mds1 \
5738                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5739         do_nodes $(comma_list $(mdts_nodes)) \
5740                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5741         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5742                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5743
5744         createmany -o $DIR/$tdir/t- 1000
5745         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5746         for ((n = 0; n < $OSTCOUNT; n++)); do
5747                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5748                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5749                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5750                             '($1 == '$n') { objs += 1 } \
5751                             END { printf("%0.0f", objs) }')
5752                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5753         done
5754         unlinkmany $DIR/$tdir/t- 1000
5755
5756         nlast=0
5757         for ((n = 0; n < $OSTCOUNT; n++)); do
5758                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5759                         { $LFS df && $LFS df -i &&
5760                         error "OST $n has fewer objects vs. OST $nlast" \
5761                               " (${objs[$n]} < ${objs[$nlast]}"; }
5762                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5763                         { $LFS df && $LFS df -i &&
5764                         error "OST $n has fewer objects vs. OST $nlast" \
5765                               " (${objs[$n]} < ${objs[$nlast]}"; }
5766
5767                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5768                         { $LFS df && $LFS df -i &&
5769                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5770                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5771                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5772                         { $LFS df && $LFS df -i &&
5773                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5774                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5775                 nlast=$n
5776         done
5777 }
5778 run_test 51d "check object distribution"
5779
5780 test_51e() {
5781         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5782                 skip_env "ldiskfs only test"
5783         fi
5784
5785         test_mkdir -c1 $DIR/$tdir
5786         test_mkdir -c1 $DIR/$tdir/d0
5787
5788         touch $DIR/$tdir/d0/foo
5789         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5790                 error "file exceed 65000 nlink limit!"
5791         unlinkmany $DIR/$tdir/d0/f- 65001
5792         return 0
5793 }
5794 run_test 51e "check file nlink limit"
5795
5796 test_51f() {
5797         test_mkdir $DIR/$tdir
5798
5799         local max=100000
5800         local ulimit_old=$(ulimit -n)
5801         local spare=20 # number of spare fd's for scripts/libraries, etc.
5802         local mdt=$($LFS getstripe -m $DIR/$tdir)
5803         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5804
5805         echo "MDT$mdt numfree=$numfree, max=$max"
5806         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5807         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5808                 while ! ulimit -n $((numfree + spare)); do
5809                         numfree=$((numfree * 3 / 4))
5810                 done
5811                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5812         else
5813                 echo "left ulimit at $ulimit_old"
5814         fi
5815
5816         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5817                 unlinkmany $DIR/$tdir/f $numfree
5818                 error "create+open $numfree files in $DIR/$tdir failed"
5819         }
5820         ulimit -n $ulimit_old
5821
5822         # if createmany exits at 120s there will be fewer than $numfree files
5823         unlinkmany $DIR/$tdir/f $numfree || true
5824 }
5825 run_test 51f "check many open files limit"
5826
5827 test_52a() {
5828         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5829         test_mkdir $DIR/$tdir
5830         touch $DIR/$tdir/foo
5831         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5832         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5833         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5834         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5835         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5836                                         error "link worked"
5837         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5838         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5839         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5840                                                      error "lsattr"
5841         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5842         cp -r $DIR/$tdir $TMP/
5843         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5844 }
5845 run_test 52a "append-only flag test (should return errors)"
5846
5847 test_52b() {
5848         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5849         test_mkdir $DIR/$tdir
5850         touch $DIR/$tdir/foo
5851         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5852         cat test > $DIR/$tdir/foo && error "cat test worked"
5853         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5854         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5855         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5856                                         error "link worked"
5857         echo foo >> $DIR/$tdir/foo && error "echo worked"
5858         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5859         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5860         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5861         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5862                                                         error "lsattr"
5863         chattr -i $DIR/$tdir/foo || error "chattr failed"
5864
5865         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5866 }
5867 run_test 52b "immutable flag test (should return errors) ======="
5868
5869 test_53() {
5870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5871         remote_mds_nodsh && skip "remote MDS with nodsh"
5872         remote_ost_nodsh && skip "remote OST with nodsh"
5873
5874         local param
5875         local param_seq
5876         local ostname
5877         local mds_last
5878         local mds_last_seq
5879         local ost_last
5880         local ost_last_seq
5881         local ost_last_id
5882         local ostnum
5883         local node
5884         local found=false
5885         local support_last_seq=true
5886
5887         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5888                 support_last_seq=false
5889
5890         # only test MDT0000
5891         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5892         local value
5893         for value in $(do_facet $SINGLEMDS \
5894                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5895                 param=$(echo ${value[0]} | cut -d "=" -f1)
5896                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5897
5898                 if $support_last_seq; then
5899                         param_seq=$(echo $param |
5900                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5901                         mds_last_seq=$(do_facet $SINGLEMDS \
5902                                        $LCTL get_param -n $param_seq)
5903                 fi
5904                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5905
5906                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5907                 node=$(facet_active_host ost$((ostnum+1)))
5908                 param="obdfilter.$ostname.last_id"
5909                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5910                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5911                         ost_last_id=$ost_last
5912
5913                         if $support_last_seq; then
5914                                 ost_last_id=$(echo $ost_last |
5915                                               awk -F':' '{print $2}' |
5916                                               sed -e "s/^0x//g")
5917                                 ost_last_seq=$(echo $ost_last |
5918                                                awk -F':' '{print $1}')
5919                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5920                         fi
5921
5922                         if [[ $ost_last_id != $mds_last ]]; then
5923                                 error "$ost_last_id != $mds_last"
5924                         else
5925                                 found=true
5926                                 break
5927                         fi
5928                 done
5929         done
5930         $found || error "can not match last_seq/last_id for $mdtosc"
5931         return 0
5932 }
5933 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5934
5935 test_54a() {
5936         perl -MSocket -e ';' || skip "no Socket perl module installed"
5937
5938         $SOCKETSERVER $DIR/socket ||
5939                 error "$SOCKETSERVER $DIR/socket failed: $?"
5940         $SOCKETCLIENT $DIR/socket ||
5941                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5942         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5943 }
5944 run_test 54a "unix domain socket test =========================="
5945
5946 test_54b() {
5947         f="$DIR/f54b"
5948         mknod $f c 1 3
5949         chmod 0666 $f
5950         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5951 }
5952 run_test 54b "char device works in lustre ======================"
5953
5954 find_loop_dev() {
5955         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5956         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5957         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5958
5959         for i in $(seq 3 7); do
5960                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5961                 LOOPDEV=$LOOPBASE$i
5962                 LOOPNUM=$i
5963                 break
5964         done
5965 }
5966
5967 cleanup_54c() {
5968         local rc=0
5969         loopdev="$DIR/loop54c"
5970
5971         trap 0
5972         $UMOUNT $DIR/$tdir || rc=$?
5973         losetup -d $loopdev || true
5974         losetup -d $LOOPDEV || true
5975         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5976         return $rc
5977 }
5978
5979 test_54c() {
5980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5981
5982         loopdev="$DIR/loop54c"
5983
5984         find_loop_dev
5985         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5986         trap cleanup_54c EXIT
5987         mknod $loopdev b 7 $LOOPNUM
5988         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5989         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5990         losetup $loopdev $DIR/$tfile ||
5991                 error "can't set up $loopdev for $DIR/$tfile"
5992         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5993         test_mkdir $DIR/$tdir
5994         mount -t ext2 $loopdev $DIR/$tdir ||
5995                 error "error mounting $loopdev on $DIR/$tdir"
5996         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5997                 error "dd write"
5998         df $DIR/$tdir
5999         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6000                 error "dd read"
6001         cleanup_54c
6002 }
6003 run_test 54c "block device works in lustre ====================="
6004
6005 test_54d() {
6006         local pipe="$DIR/$tfile.pipe"
6007         local string="aaaaaa"
6008
6009         mknod $pipe p
6010         echo -n "$string" > $pipe &
6011         local result=$(cat $pipe)
6012         [[ "$result" == "$string" ]] || error "$result != $string"
6013 }
6014 run_test 54d "fifo device works in lustre ======================"
6015
6016 test_54e() {
6017         f="$DIR/f54e"
6018         string="aaaaaa"
6019         cp -aL /dev/console $f
6020         echo $string > $f || error "echo $string to $f failed"
6021 }
6022 run_test 54e "console/tty device works in lustre ======================"
6023
6024 test_56a() {
6025         local numfiles=3
6026         local numdirs=2
6027         local dir=$DIR/$tdir
6028
6029         rm -rf $dir
6030         test_mkdir -p $dir/dir
6031         for i in $(seq $numfiles); do
6032                 touch $dir/file$i
6033                 touch $dir/dir/file$i
6034         done
6035
6036         local numcomp=$($LFS getstripe --component-count $dir)
6037
6038         [[ $numcomp == 0 ]] && numcomp=1
6039
6040         # test lfs getstripe with --recursive
6041         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6042
6043         [[ $filenum -eq $((numfiles * 2)) ]] ||
6044                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6045         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6046         [[ $filenum -eq $numfiles ]] ||
6047                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6048         echo "$LFS getstripe showed obdidx or l_ost_idx"
6049
6050         # test lfs getstripe with file instead of dir
6051         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6052         [[ $filenum -eq 1 ]] ||
6053                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6054         echo "$LFS getstripe file1 passed"
6055
6056         #test lfs getstripe with --verbose
6057         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6058         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6059                 error "$LFS getstripe --verbose $dir: "\
6060                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6061         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6062                 error "$LFS getstripe $dir: showed lmm_magic"
6063
6064         #test lfs getstripe with -v prints lmm_fid
6065         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6066         local countfids=$((numdirs + numfiles * numcomp))
6067         [[ $filenum -eq $countfids ]] ||
6068                 error "$LFS getstripe -v $dir: "\
6069                       "got $filenum want $countfids lmm_fid"
6070         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6071                 error "$LFS getstripe $dir: showed lmm_fid by default"
6072         echo "$LFS getstripe --verbose passed"
6073
6074         #check for FID information
6075         local fid1=$($LFS getstripe --fid $dir/file1)
6076         local fid2=$($LFS getstripe --verbose $dir/file1 |
6077                      awk '/lmm_fid: / { print $2; exit; }')
6078         local fid3=$($LFS path2fid $dir/file1)
6079
6080         [ "$fid1" != "$fid2" ] &&
6081                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6082         [ "$fid1" != "$fid3" ] &&
6083                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6084         echo "$LFS getstripe --fid passed"
6085
6086         #test lfs getstripe with --obd
6087         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6088                 error "$LFS getstripe --obd wrong_uuid: should return error"
6089
6090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6091
6092         local ostidx=1
6093         local obduuid=$(ostuuid_from_index $ostidx)
6094         local found=$($LFS getstripe -r --obd $obduuid $dir |
6095                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6096
6097         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6098         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6099                 ((filenum--))
6100         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6101                 ((filenum--))
6102
6103         [[ $found -eq $filenum ]] ||
6104                 error "$LFS getstripe --obd: found $found expect $filenum"
6105         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6106                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6107                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6108                 error "$LFS getstripe --obd: should not show file on other obd"
6109         echo "$LFS getstripe --obd passed"
6110 }
6111 run_test 56a "check $LFS getstripe"
6112
6113 test_56b() {
6114         local dir=$DIR/$tdir
6115         local numdirs=3
6116
6117         test_mkdir $dir
6118         for i in $(seq $numdirs); do
6119                 test_mkdir $dir/dir$i
6120         done
6121
6122         # test lfs getdirstripe default mode is non-recursion, which is
6123         # different from lfs getstripe
6124         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6125
6126         [[ $dircnt -eq 1 ]] ||
6127                 error "$LFS getdirstripe: found $dircnt, not 1"
6128         dircnt=$($LFS getdirstripe --recursive $dir |
6129                 grep -c lmv_stripe_count)
6130         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6131                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6132 }
6133 run_test 56b "check $LFS getdirstripe"
6134
6135 test_56c() {
6136         remote_ost_nodsh && skip "remote OST with nodsh"
6137
6138         local ost_idx=0
6139         local ost_name=$(ostname_from_index $ost_idx)
6140         local old_status=$(ost_dev_status $ost_idx)
6141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6142
6143         [[ -z "$old_status" ]] ||
6144                 skip_env "OST $ost_name is in $old_status status"
6145
6146         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6147         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6148                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6149         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6150                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6151                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6152         fi
6153
6154         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6155                 error "$LFS df -v showing inactive devices"
6156         sleep_maxage
6157
6158         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6159
6160         [[ "$new_status" =~ "D" ]] ||
6161                 error "$ost_name status is '$new_status', missing 'D'"
6162         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6163                 [[ "$new_status" =~ "N" ]] ||
6164                         error "$ost_name status is '$new_status', missing 'N'"
6165         fi
6166         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6167                 [[ "$new_status" =~ "f" ]] ||
6168                         error "$ost_name status is '$new_status', missing 'f'"
6169         fi
6170
6171         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6172         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6173                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6174         [[ -z "$p" ]] && restore_lustre_params < $p || true
6175         sleep_maxage
6176
6177         new_status=$(ost_dev_status $ost_idx)
6178         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6179                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6180         # can't check 'f' as devices may actually be on flash
6181 }
6182 run_test 56c "check 'lfs df' showing device status"
6183
6184 test_56d() {
6185         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6186         local osts=$($LFS df -v $MOUNT | grep -c OST)
6187
6188         $LFS df $MOUNT
6189
6190         (( mdts == MDSCOUNT )) ||
6191                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6192         (( osts == OSTCOUNT )) ||
6193                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6194 }
6195 run_test 56d "'lfs df -v' prints only configured devices"
6196
6197 test_56e() {
6198         err_enoent=2 # No such file or directory
6199         err_eopnotsupp=95 # Operation not supported
6200
6201         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6202         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6203
6204         # Check for handling of path not exists
6205         output=$($LFS df $enoent_mnt 2>&1)
6206         ret=$?
6207
6208         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6209         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6210                 error "expect failure $err_enoent, not $ret"
6211
6212         # Check for handling of non-Lustre FS
6213         output=$($LFS df $notsup_mnt)
6214         ret=$?
6215
6216         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6217         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6218                 error "expect success $err_eopnotsupp, not $ret"
6219
6220         # Check for multiple LustreFS argument
6221         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6222         ret=$?
6223
6224         [[ $output -eq 3 && $ret -eq 0 ]] ||
6225                 error "expect success 3, not $output, rc = $ret"
6226
6227         # Check for correct non-Lustre FS handling among multiple
6228         # LustreFS argument
6229         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6230                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6231         ret=$?
6232
6233         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6234                 error "expect success 2, not $output, rc = $ret"
6235 }
6236 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6237
6238 NUMFILES=3
6239 NUMDIRS=3
6240 setup_56() {
6241         local local_tdir="$1"
6242         local local_numfiles="$2"
6243         local local_numdirs="$3"
6244         local dir_params="$4"
6245         local dir_stripe_params="$5"
6246
6247         if [ ! -d "$local_tdir" ] ; then
6248                 test_mkdir -p $dir_stripe_params $local_tdir
6249                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6250                 for i in $(seq $local_numfiles) ; do
6251                         touch $local_tdir/file$i
6252                 done
6253                 for i in $(seq $local_numdirs) ; do
6254                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6255                         for j in $(seq $local_numfiles) ; do
6256                                 touch $local_tdir/dir$i/file$j
6257                         done
6258                 done
6259         fi
6260 }
6261
6262 setup_56_special() {
6263         local local_tdir=$1
6264         local local_numfiles=$2
6265         local local_numdirs=$3
6266
6267         setup_56 $local_tdir $local_numfiles $local_numdirs
6268
6269         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6270                 for i in $(seq $local_numfiles) ; do
6271                         mknod $local_tdir/loop${i}b b 7 $i
6272                         mknod $local_tdir/null${i}c c 1 3
6273                         ln -s $local_tdir/file1 $local_tdir/link${i}
6274                 done
6275                 for i in $(seq $local_numdirs) ; do
6276                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6277                         mknod $local_tdir/dir$i/null${i}c c 1 3
6278                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6279                 done
6280         fi
6281 }
6282
6283 test_56g() {
6284         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6285         local expected=$(($NUMDIRS + 2))
6286
6287         setup_56 $dir $NUMFILES $NUMDIRS
6288
6289         # test lfs find with -name
6290         for i in $(seq $NUMFILES) ; do
6291                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6292
6293                 [ $nums -eq $expected ] ||
6294                         error "lfs find -name '*$i' $dir wrong: "\
6295                               "found $nums, expected $expected"
6296         done
6297 }
6298 run_test 56g "check lfs find -name"
6299
6300 test_56h() {
6301         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6302         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6303
6304         setup_56 $dir $NUMFILES $NUMDIRS
6305
6306         # test lfs find with ! -name
6307         for i in $(seq $NUMFILES) ; do
6308                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6309
6310                 [ $nums -eq $expected ] ||
6311                         error "lfs find ! -name '*$i' $dir wrong: "\
6312                               "found $nums, expected $expected"
6313         done
6314 }
6315 run_test 56h "check lfs find ! -name"
6316
6317 test_56i() {
6318         local dir=$DIR/$tdir
6319
6320         test_mkdir $dir
6321
6322         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6323         local out=$($cmd)
6324
6325         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6326 }
6327 run_test 56i "check 'lfs find -ost UUID' skips directories"
6328
6329 test_56j() {
6330         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6331
6332         setup_56_special $dir $NUMFILES $NUMDIRS
6333
6334         local expected=$((NUMDIRS + 1))
6335         local cmd="$LFS find -type d $dir"
6336         local nums=$($cmd | wc -l)
6337
6338         [ $nums -eq $expected ] ||
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340 }
6341 run_test 56j "check lfs find -type d"
6342
6343 test_56k() {
6344         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6345
6346         setup_56_special $dir $NUMFILES $NUMDIRS
6347
6348         local expected=$(((NUMDIRS + 1) * NUMFILES))
6349         local cmd="$LFS find -type f $dir"
6350         local nums=$($cmd | wc -l)
6351
6352         [ $nums -eq $expected ] ||
6353                 error "'$cmd' wrong: found $nums, expected $expected"
6354 }
6355 run_test 56k "check lfs find -type f"
6356
6357 test_56l() {
6358         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6359
6360         setup_56_special $dir $NUMFILES $NUMDIRS
6361
6362         local expected=$((NUMDIRS + NUMFILES))
6363         local cmd="$LFS find -type b $dir"
6364         local nums=$($cmd | wc -l)
6365
6366         [ $nums -eq $expected ] ||
6367                 error "'$cmd' wrong: found $nums, expected $expected"
6368 }
6369 run_test 56l "check lfs find -type b"
6370
6371 test_56m() {
6372         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6373
6374         setup_56_special $dir $NUMFILES $NUMDIRS
6375
6376         local expected=$((NUMDIRS + NUMFILES))
6377         local cmd="$LFS find -type c $dir"
6378         local nums=$($cmd | wc -l)
6379         [ $nums -eq $expected ] ||
6380                 error "'$cmd' wrong: found $nums, expected $expected"
6381 }
6382 run_test 56m "check lfs find -type c"
6383
6384 test_56n() {
6385         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6386         setup_56_special $dir $NUMFILES $NUMDIRS
6387
6388         local expected=$((NUMDIRS + NUMFILES))
6389         local cmd="$LFS find -type l $dir"
6390         local nums=$($cmd | wc -l)
6391
6392         [ $nums -eq $expected ] ||
6393                 error "'$cmd' wrong: found $nums, expected $expected"
6394 }
6395 run_test 56n "check lfs find -type l"
6396
6397 test_56o() {
6398         local dir=$DIR/$tdir
6399
6400         setup_56 $dir $NUMFILES $NUMDIRS
6401         utime $dir/file1 > /dev/null || error "utime (1)"
6402         utime $dir/file2 > /dev/null || error "utime (2)"
6403         utime $dir/dir1 > /dev/null || error "utime (3)"
6404         utime $dir/dir2 > /dev/null || error "utime (4)"
6405         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6406         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6407
6408         local expected=4
6409         local nums=$($LFS find -mtime +0 $dir | wc -l)
6410
6411         [ $nums -eq $expected ] ||
6412                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6413
6414         expected=12
6415         cmd="$LFS find -mtime 0 $dir"
6416         nums=$($cmd | wc -l)
6417         [ $nums -eq $expected ] ||
6418                 error "'$cmd' wrong: found $nums, expected $expected"
6419 }
6420 run_test 56o "check lfs find -mtime for old files"
6421
6422 test_56ob() {
6423         local dir=$DIR/$tdir
6424         local expected=1
6425         local count=0
6426
6427         # just to make sure there is something that won't be found
6428         test_mkdir $dir
6429         touch $dir/$tfile.now
6430
6431         for age in year week day hour min; do
6432                 count=$((count + 1))
6433
6434                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6435                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6436                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6437
6438                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6439                 local nums=$($cmd | wc -l)
6440                 [ $nums -eq $expected ] ||
6441                         error "'$cmd' wrong: found $nums, expected $expected"
6442
6443                 cmd="$LFS find $dir -atime $count${age:0:1}"
6444                 nums=$($cmd | wc -l)
6445                 [ $nums -eq $expected ] ||
6446                         error "'$cmd' wrong: found $nums, expected $expected"
6447         done
6448
6449         sleep 2
6450         cmd="$LFS find $dir -ctime +1s -type f"
6451         nums=$($cmd | wc -l)
6452         (( $nums == $count * 2 + 1)) ||
6453                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6454 }
6455 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6456
6457 test_newerXY_base() {
6458         local x=$1
6459         local y=$2
6460         local dir=$DIR/$tdir
6461         local ref
6462         local negref
6463
6464         if [ $y == "t" ]; then
6465                 if [ $x == "b" ]; then
6466                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6467                 else
6468                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6469                 fi
6470         else
6471                 ref=$DIR/$tfile.newer.$x$y
6472                 touch $ref || error "touch $ref failed"
6473         fi
6474
6475         echo "before = $ref"
6476         sleep 2
6477         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6478         sleep 2
6479         if [ $y == "t" ]; then
6480                 if [ $x == "b" ]; then
6481                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6482                 else
6483                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6484                 fi
6485         else
6486                 negref=$DIR/$tfile.negnewer.$x$y
6487                 touch $negref || error "touch $negref failed"
6488         fi
6489
6490         echo "after = $negref"
6491         local cmd="$LFS find $dir -newer$x$y $ref"
6492         local nums=$(eval $cmd | wc -l)
6493         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6494
6495         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6496                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6497
6498         cmd="$LFS find $dir ! -newer$x$y $negref"
6499         nums=$(eval $cmd | wc -l)
6500         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6501                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6502
6503         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6504         nums=$(eval $cmd | wc -l)
6505         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6506                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6507
6508         rm -rf $DIR/*
6509 }
6510
6511 test_56oc() {
6512         test_newerXY_base "a" "a"
6513         test_newerXY_base "a" "m"
6514         test_newerXY_base "a" "c"
6515         test_newerXY_base "m" "a"
6516         test_newerXY_base "m" "m"
6517         test_newerXY_base "m" "c"
6518         test_newerXY_base "c" "a"
6519         test_newerXY_base "c" "m"
6520         test_newerXY_base "c" "c"
6521
6522         [[ -n "$sles_version" ]] &&
6523                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6524
6525         test_newerXY_base "a" "t"
6526         test_newerXY_base "m" "t"
6527         test_newerXY_base "c" "t"
6528
6529         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6530            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6531                 ! btime_supported && echo "btime unsupported" && return 0
6532
6533         test_newerXY_base "b" "b"
6534         test_newerXY_base "b" "t"
6535 }
6536 run_test 56oc "check lfs find -newerXY work"
6537
6538 btime_supported() {
6539         local dir=$DIR/$tdir
6540         local rc
6541
6542         mkdir -p $dir
6543         touch $dir/$tfile
6544         $LFS find $dir -btime -1d -type f
6545         rc=$?
6546         rm -rf $dir
6547         return $rc
6548 }
6549
6550 test_56od() {
6551         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6552                 ! btime_supported && skip "btime unsupported on MDS"
6553
6554         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6555                 ! btime_supported && skip "btime unsupported on clients"
6556
6557         local dir=$DIR/$tdir
6558         local ref=$DIR/$tfile.ref
6559         local negref=$DIR/$tfile.negref
6560
6561         mkdir $dir || error "mkdir $dir failed"
6562         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6563         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6564         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6565         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6566         touch $ref || error "touch $ref failed"
6567         # sleep 3 seconds at least
6568         sleep 3
6569
6570         local before=$(do_facet mds1 date +%s)
6571         local skew=$(($(date +%s) - before + 1))
6572
6573         if (( skew < 0 && skew > -5 )); then
6574                 sleep $((0 - skew + 1))
6575                 skew=0
6576         fi
6577
6578         # Set the dir stripe params to limit files all on MDT0,
6579         # otherwise we need to calc the max clock skew between
6580         # the client and MDTs.
6581         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6582         sleep 2
6583         touch $negref || error "touch $negref failed"
6584
6585         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6586         local nums=$($cmd | wc -l)
6587         local expected=$(((NUMFILES + 1) * NUMDIRS))
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591
6592         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6593         nums=$($cmd | wc -l)
6594         expected=$((NUMFILES + 1))
6595         [ $nums -eq $expected ] ||
6596                 error "'$cmd' wrong: found $nums, expected $expected"
6597
6598         [ $skew -lt 0 ] && return
6599
6600         local after=$(do_facet mds1 date +%s)
6601         local age=$((after - before + 1 + skew))
6602
6603         cmd="$LFS find $dir -btime -${age}s -type f"
6604         nums=$($cmd | wc -l)
6605         expected=$(((NUMFILES + 1) * NUMDIRS))
6606
6607         echo "Clock skew between client and server: $skew, age:$age"
6608         [ $nums -eq $expected ] ||
6609                 error "'$cmd' wrong: found $nums, expected $expected"
6610
6611         expected=$(($NUMDIRS + 1))
6612         cmd="$LFS find $dir -btime -${age}s -type d"
6613         nums=$($cmd | wc -l)
6614         [ $nums -eq $expected ] ||
6615                 error "'$cmd' wrong: found $nums, expected $expected"
6616         rm -f $ref $negref || error "Failed to remove $ref $negref"
6617 }
6618 run_test 56od "check lfs find -btime with units"
6619
6620 test_56p() {
6621         [ $RUNAS_ID -eq $UID ] &&
6622                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6623
6624         local dir=$DIR/$tdir
6625
6626         setup_56 $dir $NUMFILES $NUMDIRS
6627         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6628
6629         local expected=$NUMFILES
6630         local cmd="$LFS find -uid $RUNAS_ID $dir"
6631         local nums=$($cmd | wc -l)
6632
6633         [ $nums -eq $expected ] ||
6634                 error "'$cmd' wrong: found $nums, expected $expected"
6635
6636         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6637         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6638         nums=$($cmd | wc -l)
6639         [ $nums -eq $expected ] ||
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641 }
6642 run_test 56p "check lfs find -uid and ! -uid"
6643
6644 test_56q() {
6645         [ $RUNAS_ID -eq $UID ] &&
6646                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6647
6648         local dir=$DIR/$tdir
6649
6650         setup_56 $dir $NUMFILES $NUMDIRS
6651         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6652
6653         local expected=$NUMFILES
6654         local cmd="$LFS find -gid $RUNAS_GID $dir"
6655         local nums=$($cmd | wc -l)
6656
6657         [ $nums -eq $expected ] ||
6658                 error "'$cmd' wrong: found $nums, expected $expected"
6659
6660         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6661         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6662         nums=$($cmd | wc -l)
6663         [ $nums -eq $expected ] ||
6664                 error "'$cmd' wrong: found $nums, expected $expected"
6665 }
6666 run_test 56q "check lfs find -gid and ! -gid"
6667
6668 test_56r() {
6669         local dir=$DIR/$tdir
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS
6672
6673         local expected=12
6674         local cmd="$LFS find -size 0 -type f -lazy $dir"
6675         local nums=$($cmd | wc -l)
6676
6677         [ $nums -eq $expected ] ||
6678                 error "'$cmd' wrong: found $nums, expected $expected"
6679         cmd="$LFS find -size 0 -type f $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] ||
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683
6684         expected=0
6685         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6686         nums=$($cmd | wc -l)
6687         [ $nums -eq $expected ] ||
6688                 error "'$cmd' wrong: found $nums, expected $expected"
6689         cmd="$LFS find ! -size 0 -type f $dir"
6690         nums=$($cmd | wc -l)
6691         [ $nums -eq $expected ] ||
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693
6694         echo "test" > $dir/$tfile
6695         echo "test2" > $dir/$tfile.2 && sync
6696         expected=1
6697         cmd="$LFS find -size 5 -type f -lazy $dir"
6698         nums=$($cmd | wc -l)
6699         [ $nums -eq $expected ] ||
6700                 error "'$cmd' wrong: found $nums, expected $expected"
6701         cmd="$LFS find -size 5 -type f $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] ||
6704                 error "'$cmd' wrong: found $nums, expected $expected"
6705
6706         expected=1
6707         cmd="$LFS find -size +5 -type f -lazy $dir"
6708         nums=$($cmd | wc -l)
6709         [ $nums -eq $expected ] ||
6710                 error "'$cmd' wrong: found $nums, expected $expected"
6711         cmd="$LFS find -size +5 -type f $dir"
6712         nums=$($cmd | wc -l)
6713         [ $nums -eq $expected ] ||
6714                 error "'$cmd' wrong: found $nums, expected $expected"
6715
6716         expected=2
6717         cmd="$LFS find -size +0 -type f -lazy $dir"
6718         nums=$($cmd | wc -l)
6719         [ $nums -eq $expected ] ||
6720                 error "'$cmd' wrong: found $nums, expected $expected"
6721         cmd="$LFS find -size +0 -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         expected=2
6727         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6728         nums=$($cmd | wc -l)
6729         [ $nums -eq $expected ] ||
6730                 error "'$cmd' wrong: found $nums, expected $expected"
6731         cmd="$LFS find ! -size -5 -type f $dir"
6732         nums=$($cmd | wc -l)
6733         [ $nums -eq $expected ] ||
6734                 error "'$cmd' wrong: found $nums, expected $expected"
6735
6736         expected=12
6737         cmd="$LFS find -size -5 -type f -lazy $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741         cmd="$LFS find -size -5 -type f $dir"
6742         nums=$($cmd | wc -l)
6743         [ $nums -eq $expected ] ||
6744                 error "'$cmd' wrong: found $nums, expected $expected"
6745 }
6746 run_test 56r "check lfs find -size works"
6747
6748 test_56ra_sub() {
6749         local expected=$1
6750         local glimpses=$2
6751         local cmd="$3"
6752
6753         cancel_lru_locks $OSC
6754
6755         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6756         local nums=$($cmd | wc -l)
6757
6758         [ $nums -eq $expected ] ||
6759                 error "'$cmd' wrong: found $nums, expected $expected"
6760
6761         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6762
6763         if (( rpcs_before + glimpses != rpcs_after )); then
6764                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6765                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6766
6767                 if [[ $glimpses == 0 ]]; then
6768                         error "'$cmd' should not send glimpse RPCs to OST"
6769                 else
6770                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6771                 fi
6772         fi
6773 }
6774
6775 test_56ra() {
6776         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6777                 skip "MDS < 2.12.58 doesn't return LSOM data"
6778         local dir=$DIR/$tdir
6779         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6780
6781         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6782
6783         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6784         $LCTL set_param -n llite.*.statahead_agl=0
6785         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6786
6787         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6788         # open and close all files to ensure LSOM is updated
6789         cancel_lru_locks $OSC
6790         find $dir -type f | xargs cat > /dev/null
6791
6792         #   expect_found  glimpse_rpcs  command_to_run
6793         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6794         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6795         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6796         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6797
6798         echo "test" > $dir/$tfile
6799         echo "test2" > $dir/$tfile.2 && sync
6800         cancel_lru_locks $OSC
6801         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6802
6803         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6804         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6805         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6806         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6807
6808         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6809         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6810         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6811         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6812         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6813         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6814 }
6815 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6816
6817 test_56rb() {
6818         local dir=$DIR/$tdir
6819         local tmp=$TMP/$tfile.log
6820         local mdt_idx;
6821
6822         test_mkdir -p $dir || error "failed to mkdir $dir"
6823         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6824                 error "failed to setstripe $dir/$tfile"
6825         mdt_idx=$($LFS getdirstripe -i $dir)
6826         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6827
6828         stack_trap "rm -f $tmp" EXIT
6829         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6830         ! grep -q obd_uuid $tmp ||
6831                 error "failed to find --size +100K --ost 0 $dir"
6832         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6833         ! grep -q obd_uuid $tmp ||
6834                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6835 }
6836 run_test 56rb "check lfs find --size --ost/--mdt works"
6837
6838 test_56rc() {
6839         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6840         local dir=$DIR/$tdir
6841         local found
6842
6843         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6844         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6845         (( $MDSCOUNT > 2 )) &&
6846                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6847         mkdir $dir/$tdir-{1..10}
6848         touch $dir/$tfile-{1..10}
6849
6850         found=$($LFS find $dir --mdt-count 2 | wc -l)
6851         expect=11
6852         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6853
6854         found=$($LFS find $dir -T +1 | wc -l)
6855         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6856         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6857
6858         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6859         expect=11
6860         (( $found == $expect )) || error "found $found all_char, expect $expect"
6861
6862         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6863         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6864         (( $found == $expect )) || error "found $found all_char, expect $expect"
6865 }
6866 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6867
6868 test_56s() { # LU-611 #LU-9369
6869         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6870
6871         local dir=$DIR/$tdir
6872         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6873
6874         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6875         for i in $(seq $NUMDIRS); do
6876                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6877         done
6878
6879         local expected=$NUMDIRS
6880         local cmd="$LFS find -c $OSTCOUNT $dir"
6881         local nums=$($cmd | wc -l)
6882
6883         [ $nums -eq $expected ] || {
6884                 $LFS getstripe -R $dir
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886         }
6887
6888         expected=$((NUMDIRS + onestripe))
6889         cmd="$LFS find -stripe-count +0 -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] || {
6892                 $LFS getstripe -R $dir
6893                 error "'$cmd' wrong: found $nums, expected $expected"
6894         }
6895
6896         expected=$onestripe
6897         cmd="$LFS find -stripe-count 1 -type f $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] || {
6900                 $LFS getstripe -R $dir
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902         }
6903
6904         cmd="$LFS find -stripe-count -2 -type f $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] || {
6907                 $LFS getstripe -R $dir
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909         }
6910
6911         expected=0
6912         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] || {
6915                 $LFS getstripe -R $dir
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917         }
6918 }
6919 run_test 56s "check lfs find -stripe-count works"
6920
6921 test_56t() { # LU-611 #LU-9369
6922         local dir=$DIR/$tdir
6923
6924         setup_56 $dir 0 $NUMDIRS
6925         for i in $(seq $NUMDIRS); do
6926                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6927         done
6928
6929         local expected=$NUMDIRS
6930         local cmd="$LFS find -S 8M $dir"
6931         local nums=$($cmd | wc -l)
6932
6933         [ $nums -eq $expected ] || {
6934                 $LFS getstripe -R $dir
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936         }
6937         rm -rf $dir
6938
6939         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6940
6941         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6942
6943         expected=$(((NUMDIRS + 1) * NUMFILES))
6944         cmd="$LFS find -stripe-size 512k -type f $dir"
6945         nums=$($cmd | wc -l)
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948
6949         cmd="$LFS find -stripe-size +320k -type f $dir"
6950         nums=$($cmd | wc -l)
6951         [ $nums -eq $expected ] ||
6952                 error "'$cmd' wrong: found $nums, expected $expected"
6953
6954         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6955         cmd="$LFS find -stripe-size +200k -type f $dir"
6956         nums=$($cmd | wc -l)
6957         [ $nums -eq $expected ] ||
6958                 error "'$cmd' wrong: found $nums, expected $expected"
6959
6960         cmd="$LFS find -stripe-size -640k -type f $dir"
6961         nums=$($cmd | wc -l)
6962         [ $nums -eq $expected ] ||
6963                 error "'$cmd' wrong: found $nums, expected $expected"
6964
6965         expected=4
6966         cmd="$LFS find -stripe-size 256k -type f $dir"
6967         nums=$($cmd | wc -l)
6968         [ $nums -eq $expected ] ||
6969                 error "'$cmd' wrong: found $nums, expected $expected"
6970
6971         cmd="$LFS find -stripe-size -320k -type f $dir"
6972         nums=$($cmd | wc -l)
6973         [ $nums -eq $expected ] ||
6974                 error "'$cmd' wrong: found $nums, expected $expected"
6975
6976         expected=0
6977         cmd="$LFS find -stripe-size 1024k -type f $dir"
6978         nums=$($cmd | wc -l)
6979         [ $nums -eq $expected ] ||
6980                 error "'$cmd' wrong: found $nums, expected $expected"
6981 }
6982 run_test 56t "check lfs find -stripe-size works"
6983
6984 test_56u() { # LU-611
6985         local dir=$DIR/$tdir
6986
6987         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6988
6989         if [[ $OSTCOUNT -gt 1 ]]; then
6990                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6991                 onestripe=4
6992         else
6993                 onestripe=0
6994         fi
6995
6996         local expected=$(((NUMDIRS + 1) * NUMFILES))
6997         local cmd="$LFS find -stripe-index 0 -type f $dir"
6998         local nums=$($cmd | wc -l)
6999
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002
7003         expected=$onestripe
7004         cmd="$LFS find -stripe-index 1 -type f $dir"
7005         nums=$($cmd | wc -l)
7006         [ $nums -eq $expected ] ||
7007                 error "'$cmd' wrong: found $nums, expected $expected"
7008
7009         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7010         nums=$($cmd | wc -l)
7011         [ $nums -eq $expected ] ||
7012                 error "'$cmd' wrong: found $nums, expected $expected"
7013
7014         expected=0
7015         # This should produce an error and not return any files
7016         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7017         nums=$($cmd 2>/dev/null | wc -l)
7018         [ $nums -eq $expected ] ||
7019                 error "'$cmd' wrong: found $nums, expected $expected"
7020
7021         if [[ $OSTCOUNT -gt 1 ]]; then
7022                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7023                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7024                 nums=$($cmd | wc -l)
7025                 [ $nums -eq $expected ] ||
7026                         error "'$cmd' wrong: found $nums, expected $expected"
7027         fi
7028 }
7029 run_test 56u "check lfs find -stripe-index works"
7030
7031 test_56v() {
7032         local mdt_idx=0
7033         local dir=$DIR/$tdir
7034
7035         setup_56 $dir $NUMFILES $NUMDIRS
7036
7037         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7038         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7039
7040         for file in $($LFS find -m $UUID $dir); do
7041                 file_midx=$($LFS getstripe -m $file)
7042                 [ $file_midx -eq $mdt_idx ] ||
7043                         error "lfs find -m $UUID != getstripe -m $file_midx"
7044         done
7045 }
7046 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7047
7048 test_56w() {
7049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7051
7052         local dir=$DIR/$tdir
7053
7054         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7055
7056         local stripe_size=$($LFS getstripe -S -d $dir) ||
7057                 error "$LFS getstripe -S -d $dir failed"
7058         stripe_size=${stripe_size%% *}
7059
7060         local file_size=$((stripe_size * OSTCOUNT))
7061         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7062         local required_space=$((file_num * file_size))
7063         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7064                            head -n1)
7065         [[ $free_space -le $((required_space / 1024)) ]] &&
7066                 skip_env "need $required_space, have $free_space kbytes"
7067
7068         local dd_bs=65536
7069         local dd_count=$((file_size / dd_bs))
7070
7071         # write data into the files
7072         local i
7073         local j
7074         local file
7075
7076         for i in $(seq $NUMFILES); do
7077                 file=$dir/file$i
7078                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7079                         error "write data into $file failed"
7080         done
7081         for i in $(seq $NUMDIRS); do
7082                 for j in $(seq $NUMFILES); do
7083                         file=$dir/dir$i/file$j
7084                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7085                                 error "write data into $file failed"
7086                 done
7087         done
7088
7089         # $LFS_MIGRATE will fail if hard link migration is unsupported
7090         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7091                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7092                         error "creating links to $dir/dir1/file1 failed"
7093         fi
7094
7095         local expected=-1
7096
7097         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7098
7099         # lfs_migrate file
7100         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7101
7102         echo "$cmd"
7103         eval $cmd || error "$cmd failed"
7104
7105         check_stripe_count $dir/file1 $expected
7106
7107         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7108         then
7109                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7110                 # OST 1 if it is on OST 0. This file is small enough to
7111                 # be on only one stripe.
7112                 file=$dir/migr_1_ost
7113                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7114                         error "write data into $file failed"
7115                 local obdidx=$($LFS getstripe -i $file)
7116                 local oldmd5=$(md5sum $file)
7117                 local newobdidx=0
7118
7119                 [[ $obdidx -eq 0 ]] && newobdidx=1
7120                 cmd="$LFS migrate -i $newobdidx $file"
7121                 echo $cmd
7122                 eval $cmd || error "$cmd failed"
7123
7124                 local realobdix=$($LFS getstripe -i $file)
7125                 local newmd5=$(md5sum $file)
7126
7127                 [[ $newobdidx -ne $realobdix ]] &&
7128                         error "new OST is different (was=$obdidx, "\
7129                               "wanted=$newobdidx, got=$realobdix)"
7130                 [[ "$oldmd5" != "$newmd5" ]] &&
7131                         error "md5sum differ: $oldmd5, $newmd5"
7132         fi
7133
7134         # lfs_migrate dir
7135         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7136         echo "$cmd"
7137         eval $cmd || error "$cmd failed"
7138
7139         for j in $(seq $NUMFILES); do
7140                 check_stripe_count $dir/dir1/file$j $expected
7141         done
7142
7143         # lfs_migrate works with lfs find
7144         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7145              $LFS_MIGRATE -y -c $expected"
7146         echo "$cmd"
7147         eval $cmd || error "$cmd failed"
7148
7149         for i in $(seq 2 $NUMFILES); do
7150                 check_stripe_count $dir/file$i $expected
7151         done
7152         for i in $(seq 2 $NUMDIRS); do
7153                 for j in $(seq $NUMFILES); do
7154                 check_stripe_count $dir/dir$i/file$j $expected
7155                 done
7156         done
7157 }
7158 run_test 56w "check lfs_migrate -c stripe_count works"
7159
7160 test_56wb() {
7161         local file1=$DIR/$tdir/file1
7162         local create_pool=false
7163         local initial_pool=$($LFS getstripe -p $DIR)
7164         local pool_list=()
7165         local pool=""
7166
7167         echo -n "Creating test dir..."
7168         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7169         echo "done."
7170
7171         echo -n "Creating test file..."
7172         touch $file1 || error "cannot create file"
7173         echo "done."
7174
7175         echo -n "Detecting existing pools..."
7176         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7177
7178         if [ ${#pool_list[@]} -gt 0 ]; then
7179                 echo "${pool_list[@]}"
7180                 for thispool in "${pool_list[@]}"; do
7181                         if [[ -z "$initial_pool" ||
7182                               "$initial_pool" != "$thispool" ]]; then
7183                                 pool="$thispool"
7184                                 echo "Using existing pool '$pool'"
7185                                 break
7186                         fi
7187                 done
7188         else
7189                 echo "none detected."
7190         fi
7191         if [ -z "$pool" ]; then
7192                 pool=${POOL:-testpool}
7193                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7194                 echo -n "Creating pool '$pool'..."
7195                 create_pool=true
7196                 pool_add $pool &> /dev/null ||
7197                         error "pool_add failed"
7198                 echo "done."
7199
7200                 echo -n "Adding target to pool..."
7201                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7202                         error "pool_add_targets failed"
7203                 echo "done."
7204         fi
7205
7206         echo -n "Setting pool using -p option..."
7207         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7208                 error "migrate failed rc = $?"
7209         echo "done."
7210
7211         echo -n "Verifying test file is in pool after migrating..."
7212         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7213                 error "file was not migrated to pool $pool"
7214         echo "done."
7215
7216         echo -n "Removing test file from pool '$pool'..."
7217         # "lfs migrate $file" won't remove the file from the pool
7218         # until some striping information is changed.
7219         $LFS migrate -c 1 $file1 &> /dev/null ||
7220                 error "cannot remove from pool"
7221         [ "$($LFS getstripe -p $file1)" ] &&
7222                 error "pool still set"
7223         echo "done."
7224
7225         echo -n "Setting pool using --pool option..."
7226         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7227                 error "migrate failed rc = $?"
7228         echo "done."
7229
7230         # Clean up
7231         rm -f $file1
7232         if $create_pool; then
7233                 destroy_test_pools 2> /dev/null ||
7234                         error "destroy test pools failed"
7235         fi
7236 }
7237 run_test 56wb "check lfs_migrate pool support"
7238
7239 test_56wc() {
7240         local file1="$DIR/$tdir/file1"
7241         local parent_ssize
7242         local parent_scount
7243         local cur_ssize
7244         local cur_scount
7245         local orig_ssize
7246
7247         echo -n "Creating test dir..."
7248         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7249         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7250                 error "cannot set stripe by '-S 1M -c 1'"
7251         echo "done"
7252
7253         echo -n "Setting initial stripe for test file..."
7254         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7255                 error "cannot set stripe"
7256         cur_ssize=$($LFS getstripe -S "$file1")
7257         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7258         echo "done."
7259
7260         # File currently set to -S 512K -c 1
7261
7262         # Ensure -c and -S options are rejected when -R is set
7263         echo -n "Verifying incompatible options are detected..."
7264         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7265                 error "incompatible -c and -R options not detected"
7266         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7267                 error "incompatible -S and -R options not detected"
7268         echo "done."
7269
7270         # Ensure unrecognized options are passed through to 'lfs migrate'
7271         echo -n "Verifying -S option is passed through to lfs migrate..."
7272         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7273                 error "migration failed"
7274         cur_ssize=$($LFS getstripe -S "$file1")
7275         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7276         echo "done."
7277
7278         # File currently set to -S 1M -c 1
7279
7280         # Ensure long options are supported
7281         echo -n "Verifying long options supported..."
7282         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7283                 error "long option without argument not supported"
7284         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7285                 error "long option with argument not supported"
7286         cur_ssize=$($LFS getstripe -S "$file1")
7287         [ $cur_ssize -eq 524288 ] ||
7288                 error "migrate --stripe-size $cur_ssize != 524288"
7289         echo "done."
7290
7291         # File currently set to -S 512K -c 1
7292
7293         if [ "$OSTCOUNT" -gt 1 ]; then
7294                 echo -n "Verifying explicit stripe count can be set..."
7295                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7296                         error "migrate failed"
7297                 cur_scount=$($LFS getstripe -c "$file1")
7298                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7299                 echo "done."
7300         fi
7301
7302         # File currently set to -S 512K -c 1 or -S 512K -c 2
7303
7304         # Ensure parent striping is used if -R is set, and no stripe
7305         # count or size is specified
7306         echo -n "Setting stripe for parent directory..."
7307         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7308                 error "cannot set stripe '-S 2M -c 1'"
7309         echo "done."
7310
7311         echo -n "Verifying restripe option uses parent stripe settings..."
7312         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7313         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7314         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7315                 error "migrate failed"
7316         cur_ssize=$($LFS getstripe -S "$file1")
7317         [ $cur_ssize -eq $parent_ssize ] ||
7318                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7319         cur_scount=$($LFS getstripe -c "$file1")
7320         [ $cur_scount -eq $parent_scount ] ||
7321                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7322         echo "done."
7323
7324         # File currently set to -S 1M -c 1
7325
7326         # Ensure striping is preserved if -R is not set, and no stripe
7327         # count or size is specified
7328         echo -n "Verifying striping size preserved when not specified..."
7329         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7330         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7331                 error "cannot set stripe on parent directory"
7332         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7333                 error "migrate failed"
7334         cur_ssize=$($LFS getstripe -S "$file1")
7335         [ $cur_ssize -eq $orig_ssize ] ||
7336                 error "migrate by default $cur_ssize != $orig_ssize"
7337         echo "done."
7338
7339         # Ensure file name properly detected when final option has no argument
7340         echo -n "Verifying file name properly detected..."
7341         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7342                 error "file name interpreted as option argument"
7343         echo "done."
7344
7345         # Clean up
7346         rm -f "$file1"
7347 }
7348 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7349
7350 test_56wd() {
7351         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7352
7353         local file1=$DIR/$tdir/file1
7354
7355         echo -n "Creating test dir..."
7356         test_mkdir $DIR/$tdir || error "cannot create dir"
7357         echo "done."
7358
7359         echo -n "Creating test file..."
7360         touch $file1
7361         echo "done."
7362
7363         # Ensure 'lfs migrate' will fail by using a non-existent option,
7364         # and make sure rsync is not called to recover
7365         echo -n "Make sure --no-rsync option works..."
7366         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7367                 grep -q 'refusing to fall back to rsync' ||
7368                 error "rsync was called with --no-rsync set"
7369         echo "done."
7370
7371         # Ensure rsync is called without trying 'lfs migrate' first
7372         echo -n "Make sure --rsync option works..."
7373         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7374                 grep -q 'falling back to rsync' &&
7375                 error "lfs migrate was called with --rsync set"
7376         echo "done."
7377
7378         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7379         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7380                 grep -q 'at the same time' ||
7381                 error "--rsync and --no-rsync accepted concurrently"
7382         echo "done."
7383
7384         # Clean up
7385         rm -f $file1
7386 }
7387 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7388
7389 test_56we() {
7390         local td=$DIR/$tdir
7391         local tf=$td/$tfile
7392
7393         test_mkdir $td || error "cannot create $td"
7394         touch $tf || error "cannot touch $tf"
7395
7396         echo -n "Make sure --non-direct|-D works..."
7397         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7398                 grep -q "lfs migrate --non-direct" ||
7399                 error "--non-direct option cannot work correctly"
7400         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7401                 grep -q "lfs migrate -D" ||
7402                 error "-D option cannot work correctly"
7403         echo "done."
7404 }
7405 run_test 56we "check lfs_migrate --non-direct|-D support"
7406
7407 test_56x() {
7408         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7409         check_swap_layouts_support
7410
7411         local dir=$DIR/$tdir
7412         local ref1=/etc/passwd
7413         local file1=$dir/file1
7414
7415         test_mkdir $dir || error "creating dir $dir"
7416         $LFS setstripe -c 2 $file1
7417         cp $ref1 $file1
7418         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7419         stripe=$($LFS getstripe -c $file1)
7420         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7421         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7422
7423         # clean up
7424         rm -f $file1
7425 }
7426 run_test 56x "lfs migration support"
7427
7428 test_56xa() {
7429         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7430         check_swap_layouts_support
7431
7432         local dir=$DIR/$tdir/$testnum
7433
7434         test_mkdir -p $dir
7435
7436         local ref1=/etc/passwd
7437         local file1=$dir/file1
7438
7439         $LFS setstripe -c 2 $file1
7440         cp $ref1 $file1
7441         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7442
7443         local stripe=$($LFS getstripe -c $file1)
7444
7445         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7446         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7447
7448         # clean up
7449         rm -f $file1
7450 }
7451 run_test 56xa "lfs migration --block support"
7452
7453 check_migrate_links() {
7454         local dir="$1"
7455         local file1="$dir/file1"
7456         local begin="$2"
7457         local count="$3"
7458         local runas="$4"
7459         local total_count=$(($begin + $count - 1))
7460         local symlink_count=10
7461         local uniq_count=10
7462
7463         if [ ! -f "$file1" ]; then
7464                 echo -n "creating initial file..."
7465                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7466                         error "cannot setstripe initial file"
7467                 echo "done"
7468
7469                 echo -n "creating symlinks..."
7470                 for s in $(seq 1 $symlink_count); do
7471                         ln -s "$file1" "$dir/slink$s" ||
7472                                 error "cannot create symlinks"
7473                 done
7474                 echo "done"
7475
7476                 echo -n "creating nonlinked files..."
7477                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7478                         error "cannot create nonlinked files"
7479                 echo "done"
7480         fi
7481
7482         # create hard links
7483         if [ ! -f "$dir/file$total_count" ]; then
7484                 echo -n "creating hard links $begin:$total_count..."
7485                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7486                         /dev/null || error "cannot create hard links"
7487                 echo "done"
7488         fi
7489
7490         echo -n "checking number of hard links listed in xattrs..."
7491         local fid=$($LFS getstripe -F "$file1")
7492         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7493
7494         echo "${#paths[*]}"
7495         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7496                         skip "hard link list has unexpected size, skipping test"
7497         fi
7498         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7499                         error "link names should exceed xattrs size"
7500         fi
7501
7502         echo -n "migrating files..."
7503         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7504         local rc=$?
7505         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7506         echo "done"
7507
7508         # make sure all links have been properly migrated
7509         echo -n "verifying files..."
7510         fid=$($LFS getstripe -F "$file1") ||
7511                 error "cannot get fid for file $file1"
7512         for i in $(seq 2 $total_count); do
7513                 local fid2=$($LFS getstripe -F $dir/file$i)
7514
7515                 [ "$fid2" == "$fid" ] ||
7516                         error "migrated hard link has mismatched FID"
7517         done
7518
7519         # make sure hard links were properly detected, and migration was
7520         # performed only once for the entire link set; nonlinked files should
7521         # also be migrated
7522         local actual=$(grep -c 'done' <<< "$migrate_out")
7523         local expected=$(($uniq_count + 1))
7524
7525         [ "$actual" -eq  "$expected" ] ||
7526                 error "hard links individually migrated ($actual != $expected)"
7527
7528         # make sure the correct number of hard links are present
7529         local hardlinks=$(stat -c '%h' "$file1")
7530
7531         [ $hardlinks -eq $total_count ] ||
7532                 error "num hard links $hardlinks != $total_count"
7533         echo "done"
7534
7535         return 0
7536 }
7537
7538 test_56xb() {
7539         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7540                 skip "Need MDS version at least 2.10.55"
7541
7542         local dir="$DIR/$tdir"
7543
7544         test_mkdir "$dir" || error "cannot create dir $dir"
7545
7546         echo "testing lfs migrate mode when all links fit within xattrs"
7547         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7548
7549         echo "testing rsync mode when all links fit within xattrs"
7550         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7551
7552         echo "testing lfs migrate mode when all links do not fit within xattrs"
7553         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7554
7555         echo "testing rsync mode when all links do not fit within xattrs"
7556         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7557
7558         chown -R $RUNAS_ID $dir
7559         echo "testing non-root lfs migrate mode when not all links are in xattr"
7560         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7561
7562         # clean up
7563         rm -rf $dir
7564 }
7565 run_test 56xb "lfs migration hard link support"
7566
7567 test_56xc() {
7568         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7569
7570         local dir="$DIR/$tdir"
7571
7572         test_mkdir "$dir" || error "cannot create dir $dir"
7573
7574         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7575         echo -n "Setting initial stripe for 20MB test file..."
7576         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7577                 error "cannot setstripe 20MB file"
7578         echo "done"
7579         echo -n "Sizing 20MB test file..."
7580         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7581         echo "done"
7582         echo -n "Verifying small file autostripe count is 1..."
7583         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7584                 error "cannot migrate 20MB file"
7585         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7586                 error "cannot get stripe for $dir/20mb"
7587         [ $stripe_count -eq 1 ] ||
7588                 error "unexpected stripe count $stripe_count for 20MB file"
7589         rm -f "$dir/20mb"
7590         echo "done"
7591
7592         # Test 2: File is small enough to fit within the available space on
7593         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7594         # have at least an additional 1KB for each desired stripe for test 3
7595         echo -n "Setting stripe for 1GB test file..."
7596         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7597         echo "done"
7598         echo -n "Sizing 1GB test file..."
7599         # File size is 1GB + 3KB
7600         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7601         echo "done"
7602
7603         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7604         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7605         if (( avail > 524288 * OSTCOUNT )); then
7606                 echo -n "Migrating 1GB file..."
7607                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7608                         error "cannot migrate 1GB file"
7609                 echo "done"
7610                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7611                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7612                         error "cannot getstripe for 1GB file"
7613                 [ $stripe_count -eq 2 ] ||
7614                         error "unexpected stripe count $stripe_count != 2"
7615                 echo "done"
7616         fi
7617
7618         # Test 3: File is too large to fit within the available space on
7619         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7620         if [ $OSTCOUNT -ge 3 ]; then
7621                 # The required available space is calculated as
7622                 # file size (1GB + 3KB) / OST count (3).
7623                 local kb_per_ost=349526
7624
7625                 echo -n "Migrating 1GB file with limit..."
7626                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7627                         error "cannot migrate 1GB file with limit"
7628                 echo "done"
7629
7630                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7631                 echo -n "Verifying 1GB autostripe count with limited space..."
7632                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7633                         error "unexpected stripe count $stripe_count (min 3)"
7634                 echo "done"
7635         fi
7636
7637         # clean up
7638         rm -rf $dir
7639 }
7640 run_test 56xc "lfs migration autostripe"
7641
7642 test_56xd() {
7643         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7644
7645         local dir=$DIR/$tdir
7646         local f_mgrt=$dir/$tfile.mgrt
7647         local f_yaml=$dir/$tfile.yaml
7648         local f_copy=$dir/$tfile.copy
7649         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7650         local layout_copy="-c 2 -S 2M -i 1"
7651         local yamlfile=$dir/yamlfile
7652         local layout_before;
7653         local layout_after;
7654
7655         test_mkdir "$dir" || error "cannot create dir $dir"
7656         $LFS setstripe $layout_yaml $f_yaml ||
7657                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7658         $LFS getstripe --yaml $f_yaml > $yamlfile
7659         $LFS setstripe $layout_copy $f_copy ||
7660                 error "cannot setstripe $f_copy with layout $layout_copy"
7661         touch $f_mgrt
7662         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7663
7664         # 1. test option --yaml
7665         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7666                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7667         layout_before=$(get_layout_param $f_yaml)
7668         layout_after=$(get_layout_param $f_mgrt)
7669         [ "$layout_after" == "$layout_before" ] ||
7670                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7671
7672         # 2. test option --copy
7673         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7674                 error "cannot migrate $f_mgrt with --copy $f_copy"
7675         layout_before=$(get_layout_param $f_copy)
7676         layout_after=$(get_layout_param $f_mgrt)
7677         [ "$layout_after" == "$layout_before" ] ||
7678                 error "lfs_migrate --copy: $layout_after != $layout_before"
7679 }
7680 run_test 56xd "check lfs_migrate --yaml and --copy support"
7681
7682 test_56xe() {
7683         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7684
7685         local dir=$DIR/$tdir
7686         local f_comp=$dir/$tfile
7687         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7688         local layout_before=""
7689         local layout_after=""
7690
7691         test_mkdir "$dir" || error "cannot create dir $dir"
7692         $LFS setstripe $layout $f_comp ||
7693                 error "cannot setstripe $f_comp with layout $layout"
7694         layout_before=$(get_layout_param $f_comp)
7695         dd if=/dev/zero of=$f_comp bs=1M count=4
7696
7697         # 1. migrate a comp layout file by lfs_migrate
7698         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7699         layout_after=$(get_layout_param $f_comp)
7700         [ "$layout_before" == "$layout_after" ] ||
7701                 error "lfs_migrate: $layout_before != $layout_after"
7702
7703         # 2. migrate a comp layout file by lfs migrate
7704         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7705         layout_after=$(get_layout_param $f_comp)
7706         [ "$layout_before" == "$layout_after" ] ||
7707                 error "lfs migrate: $layout_before != $layout_after"
7708 }
7709 run_test 56xe "migrate a composite layout file"
7710
7711 test_56xf() {
7712         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7713
7714         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7715                 skip "Need server version at least 2.13.53"
7716
7717         local dir=$DIR/$tdir
7718         local f_comp=$dir/$tfile
7719         local layout="-E 1M -c1 -E -1 -c2"
7720         local fid_before=""
7721         local fid_after=""
7722
7723         test_mkdir "$dir" || error "cannot create dir $dir"
7724         $LFS setstripe $layout $f_comp ||
7725                 error "cannot setstripe $f_comp with layout $layout"
7726         fid_before=$($LFS getstripe --fid $f_comp)
7727         dd if=/dev/zero of=$f_comp bs=1M count=4
7728
7729         # 1. migrate a comp layout file to a comp layout
7730         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7731         fid_after=$($LFS getstripe --fid $f_comp)
7732         [ "$fid_before" == "$fid_after" ] ||
7733                 error "comp-to-comp migrate: $fid_before != $fid_after"
7734
7735         # 2. migrate a comp layout file to a plain layout
7736         $LFS migrate -c2 $f_comp ||
7737                 error "cannot migrate $f_comp by lfs migrate"
7738         fid_after=$($LFS getstripe --fid $f_comp)
7739         [ "$fid_before" == "$fid_after" ] ||
7740                 error "comp-to-plain migrate: $fid_before != $fid_after"
7741
7742         # 3. migrate a plain layout file to a comp layout
7743         $LFS migrate $layout $f_comp ||
7744                 error "cannot migrate $f_comp by lfs migrate"
7745         fid_after=$($LFS getstripe --fid $f_comp)
7746         [ "$fid_before" == "$fid_after" ] ||
7747                 error "plain-to-comp migrate: $fid_before != $fid_after"
7748 }
7749 run_test 56xf "FID is not lost during migration of a composite layout file"
7750
7751 check_file_ost_range() {
7752         local file="$1"
7753         shift
7754         local range="$*"
7755         local -a file_range
7756         local idx
7757
7758         file_range=($($LFS getstripe -y "$file" |
7759                 awk '/l_ost_idx:/ { print $NF }'))
7760
7761         if [[ "${#file_range[@]}" = 0 ]]; then
7762                 echo "No osts found for $file"
7763                 return 1
7764         fi
7765
7766         for idx in "${file_range[@]}"; do
7767                 [[ " $range " =~ " $idx " ]] ||
7768                         return 1
7769         done
7770
7771         return 0
7772 }
7773
7774 sub_test_56xg() {
7775         local stripe_opt="$1"
7776         local pool="$2"
7777         shift 2
7778         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7779
7780         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7781                 error "Fail to migrate $tfile on $pool"
7782         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7783                 error "$tfile is not in pool $pool"
7784         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7785                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7786 }
7787
7788 test_56xg() {
7789         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7790         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7791         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7792                 skip "Need MDS version newer than 2.14.52"
7793
7794         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7795         local -a pool_ranges=("0 0" "1 1" "0 1")
7796
7797         # init pools
7798         for i in "${!pool_names[@]}"; do
7799                 pool_add ${pool_names[$i]} ||
7800                         error "pool_add failed (pool: ${pool_names[$i]})"
7801                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7802                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7803         done
7804
7805         # init the file to migrate
7806         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7807                 error "Unable to create $tfile on OST1"
7808         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7809                 error "Unable to write on $tfile"
7810
7811         echo "1. migrate $tfile on pool ${pool_names[0]}"
7812         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7813
7814         echo "2. migrate $tfile on pool ${pool_names[2]}"
7815         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7816
7817         echo "3. migrate $tfile on pool ${pool_names[1]}"
7818         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7819
7820         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7821         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7822         echo
7823
7824         # Clean pools
7825         destroy_test_pools ||
7826                 error "pool_destroy failed"
7827 }
7828 run_test 56xg "lfs migrate pool support"
7829
7830 test_56y() {
7831         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7832                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7833
7834         local res=""
7835         local dir=$DIR/$tdir
7836         local f1=$dir/file1
7837         local f2=$dir/file2
7838
7839         test_mkdir -p $dir || error "creating dir $dir"
7840         touch $f1 || error "creating std file $f1"
7841         $MULTIOP $f2 H2c || error "creating released file $f2"
7842
7843         # a directory can be raid0, so ask only for files
7844         res=$($LFS find $dir -L raid0 -type f | wc -l)
7845         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7846
7847         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7848         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7849
7850         # only files can be released, so no need to force file search
7851         res=$($LFS find $dir -L released)
7852         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7853
7854         res=$($LFS find $dir -type f \! -L released)
7855         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7856 }
7857 run_test 56y "lfs find -L raid0|released"
7858
7859 test_56z() { # LU-4824
7860         # This checks to make sure 'lfs find' continues after errors
7861         # There are two classes of errors that should be caught:
7862         # - If multiple paths are provided, all should be searched even if one
7863         #   errors out
7864         # - If errors are encountered during the search, it should not terminate
7865         #   early
7866         local dir=$DIR/$tdir
7867         local i
7868
7869         test_mkdir $dir
7870         for i in d{0..9}; do
7871                 test_mkdir $dir/$i
7872                 touch $dir/$i/$tfile
7873         done
7874         $LFS find $DIR/non_existent_dir $dir &&
7875                 error "$LFS find did not return an error"
7876         # Make a directory unsearchable. This should NOT be the last entry in
7877         # directory order.  Arbitrarily pick the 6th entry
7878         chmod 700 $($LFS find $dir -type d | sed '6!d')
7879
7880         $RUNAS $LFS find $DIR/non_existent $dir
7881         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7882
7883         # The user should be able to see 10 directories and 9 files
7884         (( count == 19 )) ||
7885                 error "$LFS find found $count != 19 entries after error"
7886 }
7887 run_test 56z "lfs find should continue after an error"
7888
7889 test_56aa() { # LU-5937
7890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7891
7892         local dir=$DIR/$tdir
7893
7894         mkdir $dir
7895         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7896
7897         createmany -o $dir/striped_dir/${tfile}- 1024
7898         local dirs=$($LFS find --size +8k $dir/)
7899
7900         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7901 }
7902 run_test 56aa "lfs find --size under striped dir"
7903
7904 test_56ab() { # LU-10705
7905         test_mkdir $DIR/$tdir
7906         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7907         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7909         # Flush writes to ensure valid blocks.  Need to be more thorough for
7910         # ZFS, since blocks are not allocated/returned to client immediately.
7911         sync_all_data
7912         wait_zfs_commit ost1 2
7913         cancel_lru_locks osc
7914         ls -ls $DIR/$tdir
7915
7916         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7917
7918         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7919
7920         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7921         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7922
7923         rm -f $DIR/$tdir/$tfile.[123]
7924 }
7925 run_test 56ab "lfs find --blocks"
7926
7927 # LU-11188
7928 test_56aca() {
7929         local dir="$DIR/$tdir"
7930         local perms=(001 002 003 004 005 006 007
7931                      010 020 030 040 050 060 070
7932                      100 200 300 400 500 600 700
7933                      111 222 333 444 555 666 777)
7934         local perm_minus=(8 8 4 8 4 4 2
7935                           8 8 4 8 4 4 2
7936                           8 8 4 8 4 4 2
7937                           4 4 2 4 2 2 1)
7938         local perm_slash=(8  8 12  8 12 12 14
7939                           8  8 12  8 12 12 14
7940                           8  8 12  8 12 12 14
7941                          16 16 24 16 24 24 28)
7942
7943         test_mkdir "$dir"
7944         for perm in ${perms[*]}; do
7945                 touch "$dir/$tfile.$perm"
7946                 chmod $perm "$dir/$tfile.$perm"
7947         done
7948
7949         for ((i = 0; i < ${#perms[*]}; i++)); do
7950                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7951                 (( $num == 1 )) ||
7952                         error "lfs find -perm ${perms[i]}:"\
7953                               "$num != 1"
7954
7955                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7956                 (( $num == ${perm_minus[i]} )) ||
7957                         error "lfs find -perm -${perms[i]}:"\
7958                               "$num != ${perm_minus[i]}"
7959
7960                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7961                 (( $num == ${perm_slash[i]} )) ||
7962                         error "lfs find -perm /${perms[i]}:"\
7963                               "$num != ${perm_slash[i]}"
7964         done
7965 }
7966 run_test 56aca "check lfs find -perm with octal representation"
7967
7968 test_56acb() {
7969         local dir=$DIR/$tdir
7970         # p is the permission of write and execute for user, group and other
7971         # without the umask. It is used to test +wx.
7972         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7973         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7974         local symbolic=(+t  a+t u+t g+t o+t
7975                         g+s u+s o+s +s o+sr
7976                         o=r,ug+o,u+w
7977                         u+ g+ o+ a+ ugo+
7978                         u- g- o- a- ugo-
7979                         u= g= o= a= ugo=
7980                         o=r,ug+o,u+w u=r,a+u,u+w
7981                         g=r,ugo=g,u+w u+x,+X +X
7982                         u+x,u+X u+X u+x,g+X o+r,+X
7983                         u+x,go+X +wx +rwx)
7984
7985         test_mkdir $dir
7986         for perm in ${perms[*]}; do
7987                 touch "$dir/$tfile.$perm"
7988                 chmod $perm "$dir/$tfile.$perm"
7989         done
7990
7991         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7992                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7993
7994                 (( $num == 1 )) ||
7995                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7996         done
7997 }
7998 run_test 56acb "check lfs find -perm with symbolic representation"
7999
8000 test_56acc() {
8001         local dir=$DIR/$tdir
8002         local tests="17777 787 789 abcd
8003                 ug=uu ug=a ug=gu uo=ou urw
8004                 u+xg+x a=r,u+x,"
8005
8006         test_mkdir $dir
8007         for err in $tests; do
8008                 if $LFS find $dir -perm $err 2>/dev/null; then
8009                         error "lfs find -perm $err: parsing should have failed"
8010                 fi
8011         done
8012 }
8013 run_test 56acc "check parsing error for lfs find -perm"
8014
8015 test_56ba() {
8016         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8017                 skip "Need MDS version at least 2.10.50"
8018
8019         # Create composite files with one component
8020         local dir=$DIR/$tdir
8021
8022         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8023         # Create composite files with three components
8024         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8025         # Create non-composite files
8026         createmany -o $dir/${tfile}- 10
8027
8028         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8029
8030         [[ $nfiles == 10 ]] ||
8031                 error "lfs find -E 1M found $nfiles != 10 files"
8032
8033         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8034         [[ $nfiles == 25 ]] ||
8035                 error "lfs find ! -E 1M found $nfiles != 25 files"
8036
8037         # All files have a component that starts at 0
8038         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8039         [[ $nfiles == 35 ]] ||
8040                 error "lfs find --component-start 0 - $nfiles != 35 files"
8041
8042         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8043         [[ $nfiles == 15 ]] ||
8044                 error "lfs find --component-start 2M - $nfiles != 15 files"
8045
8046         # All files created here have a componenet that does not starts at 2M
8047         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8048         [[ $nfiles == 35 ]] ||
8049                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8050
8051         # Find files with a specified number of components
8052         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8053         [[ $nfiles == 15 ]] ||
8054                 error "lfs find --component-count 3 - $nfiles != 15 files"
8055
8056         # Remember non-composite files have a component count of zero
8057         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8058         [[ $nfiles == 10 ]] ||
8059                 error "lfs find --component-count 0 - $nfiles != 10 files"
8060
8061         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8062         [[ $nfiles == 20 ]] ||
8063                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8064
8065         # All files have a flag called "init"
8066         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8067         [[ $nfiles == 35 ]] ||
8068                 error "lfs find --component-flags init - $nfiles != 35 files"
8069
8070         # Multi-component files will have a component not initialized
8071         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8072         [[ $nfiles == 15 ]] ||
8073                 error "lfs find !--component-flags init - $nfiles != 15 files"
8074
8075         rm -rf $dir
8076
8077 }
8078 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8079
8080 test_56ca() {
8081         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8082                 skip "Need MDS version at least 2.10.57"
8083
8084         local td=$DIR/$tdir
8085         local tf=$td/$tfile
8086         local dir
8087         local nfiles
8088         local cmd
8089         local i
8090         local j
8091
8092         # create mirrored directories and mirrored files
8093         mkdir $td || error "mkdir $td failed"
8094         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8095         createmany -o $tf- 10 || error "create $tf- failed"
8096
8097         for i in $(seq 2); do
8098                 dir=$td/dir$i
8099                 mkdir $dir || error "mkdir $dir failed"
8100                 $LFS mirror create -N$((3 + i)) $dir ||
8101                         error "create mirrored dir $dir failed"
8102                 createmany -o $dir/$tfile- 10 ||
8103                         error "create $dir/$tfile- failed"
8104         done
8105
8106         # change the states of some mirrored files
8107         echo foo > $tf-6
8108         for i in $(seq 2); do
8109                 dir=$td/dir$i
8110                 for j in $(seq 4 9); do
8111                         echo foo > $dir/$tfile-$j
8112                 done
8113         done
8114
8115         # find mirrored files with specific mirror count
8116         cmd="$LFS find --mirror-count 3 --type f $td"
8117         nfiles=$($cmd | wc -l)
8118         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8119
8120         cmd="$LFS find ! --mirror-count 3 --type f $td"
8121         nfiles=$($cmd | wc -l)
8122         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8123
8124         cmd="$LFS find --mirror-count +2 --type f $td"
8125         nfiles=$($cmd | wc -l)
8126         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8127
8128         cmd="$LFS find --mirror-count -6 --type f $td"
8129         nfiles=$($cmd | wc -l)
8130         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8131
8132         # find mirrored files with specific file state
8133         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8134         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8135
8136         cmd="$LFS find --mirror-state=ro --type f $td"
8137         nfiles=$($cmd | wc -l)
8138         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8139
8140         cmd="$LFS find ! --mirror-state=ro --type f $td"
8141         nfiles=$($cmd | wc -l)
8142         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8143
8144         cmd="$LFS find --mirror-state=wp --type f $td"
8145         nfiles=$($cmd | wc -l)
8146         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8147
8148         cmd="$LFS find ! --mirror-state=sp --type f $td"
8149         nfiles=$($cmd | wc -l)
8150         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8151 }
8152 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8153
8154 test_56da() { # LU-14179
8155         local path=$DIR/$tdir
8156
8157         test_mkdir $path
8158         cd $path
8159
8160         local longdir=$(str_repeat 'a' 255)
8161
8162         for i in {1..15}; do
8163                 path=$path/$longdir
8164                 test_mkdir $longdir
8165                 cd $longdir
8166         done
8167
8168         local len=${#path}
8169         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8170
8171         test_mkdir $lastdir
8172         cd $lastdir
8173         # PATH_MAX-1
8174         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8175
8176         # NAME_MAX
8177         touch $(str_repeat 'f' 255)
8178
8179         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8180                 error "lfs find reported an error"
8181
8182         rm -rf $DIR/$tdir
8183 }
8184 run_test 56da "test lfs find with long paths"
8185
8186 test_56ea() { #LU-10378
8187         local path=$DIR/$tdir
8188         local pool=$TESTNAME
8189
8190         # Create ost pool
8191         pool_add $pool || error "pool_add $pool failed"
8192         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8193                 error "adding targets to $pool failed"
8194
8195         # Set default pool on directory before creating file
8196         mkdir $path || error "mkdir $path failed"
8197         $LFS setstripe -p $pool $path ||
8198                 error "set OST pool on $pool failed"
8199         touch $path/$tfile || error "touch $path/$tfile failed"
8200
8201         # Compare basic file attributes from -printf and stat
8202         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8203         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8204
8205         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8206                 error "Attrs from lfs find and stat don't match"
8207
8208         # Compare Lustre attributes from lfs find and lfs getstripe
8209         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8210         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8211         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8212         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8213         local fpool=$($LFS getstripe --pool $path/$tfile)
8214         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8215
8216         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8217                 error "Attrs from lfs find and lfs getstripe don't match"
8218
8219         # Verify behavior for unknown escape/format sequences
8220         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8221
8222         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8223                 error "Escape/format codes don't match"
8224 }
8225 run_test 56ea "test lfs find -printf option"
8226
8227 test_57a() {
8228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8229         # note test will not do anything if MDS is not local
8230         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8231                 skip_env "ldiskfs only test"
8232         fi
8233         remote_mds_nodsh && skip "remote MDS with nodsh"
8234
8235         local MNTDEV="osd*.*MDT*.mntdev"
8236         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8237         [ -z "$DEV" ] && error "can't access $MNTDEV"
8238         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8239                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8240                         error "can't access $DEV"
8241                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8242                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8243                 rm $TMP/t57a.dump
8244         done
8245 }
8246 run_test 57a "verify MDS filesystem created with large inodes =="
8247
8248 test_57b() {
8249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8250         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8251                 skip_env "ldiskfs only test"
8252         fi
8253         remote_mds_nodsh && skip "remote MDS with nodsh"
8254
8255         local dir=$DIR/$tdir
8256         local filecount=100
8257         local file1=$dir/f1
8258         local fileN=$dir/f$filecount
8259
8260         rm -rf $dir || error "removing $dir"
8261         test_mkdir -c1 $dir
8262         local mdtidx=$($LFS getstripe -m $dir)
8263         local mdtname=MDT$(printf %04x $mdtidx)
8264         local facet=mds$((mdtidx + 1))
8265
8266         echo "mcreating $filecount files"
8267         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8268
8269         # verify that files do not have EAs yet
8270         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8271                 error "$file1 has an EA"
8272         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8273                 error "$fileN has an EA"
8274
8275         sync
8276         sleep 1
8277         df $dir  #make sure we get new statfs data
8278         local mdsfree=$(do_facet $facet \
8279                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8280         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8281         local file
8282
8283         echo "opening files to create objects/EAs"
8284         for file in $(seq -f $dir/f%g 1 $filecount); do
8285                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8286                         error "opening $file"
8287         done
8288
8289         # verify that files have EAs now
8290         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8291         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8292
8293         sleep 1  #make sure we get new statfs data
8294         df $dir
8295         local mdsfree2=$(do_facet $facet \
8296                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8297         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8298
8299         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8300                 if [ "$mdsfree" != "$mdsfree2" ]; then
8301                         error "MDC before $mdcfree != after $mdcfree2"
8302                 else
8303                         echo "MDC before $mdcfree != after $mdcfree2"
8304                         echo "unable to confirm if MDS has large inodes"
8305                 fi
8306         fi
8307         rm -rf $dir
8308 }
8309 run_test 57b "default LOV EAs are stored inside large inodes ==="
8310
8311 test_58() {
8312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8313         [ -z "$(which wiretest 2>/dev/null)" ] &&
8314                         skip_env "could not find wiretest"
8315
8316         wiretest
8317 }
8318 run_test 58 "verify cross-platform wire constants =============="
8319
8320 test_59() {
8321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8322
8323         echo "touch 130 files"
8324         createmany -o $DIR/f59- 130
8325         echo "rm 130 files"
8326         unlinkmany $DIR/f59- 130
8327         sync
8328         # wait for commitment of removal
8329         wait_delete_completed
8330 }
8331 run_test 59 "verify cancellation of llog records async ========="
8332
8333 TEST60_HEAD="test_60 run $RANDOM"
8334 test_60a() {
8335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8336         remote_mgs_nodsh && skip "remote MGS with nodsh"
8337         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8338                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8339                         skip_env "missing subtest run-llog.sh"
8340
8341         log "$TEST60_HEAD - from kernel mode"
8342         do_facet mgs "$LCTL dk > /dev/null"
8343         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8344         do_facet mgs $LCTL dk > $TMP/$tfile
8345
8346         # LU-6388: test llog_reader
8347         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8348         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8349         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8350                         skip_env "missing llog_reader"
8351         local fstype=$(facet_fstype mgs)
8352         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8353                 skip_env "Only for ldiskfs or zfs type mgs"
8354
8355         local mntpt=$(facet_mntpt mgs)
8356         local mgsdev=$(mgsdevname 1)
8357         local fid_list
8358         local fid
8359         local rec_list
8360         local rec
8361         local rec_type
8362         local obj_file
8363         local path
8364         local seq
8365         local oid
8366         local pass=true
8367
8368         #get fid and record list
8369         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8370                 tail -n 4))
8371         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8372                 tail -n 4))
8373         #remount mgs as ldiskfs or zfs type
8374         stop mgs || error "stop mgs failed"
8375         mount_fstype mgs || error "remount mgs failed"
8376         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8377                 fid=${fid_list[i]}
8378                 rec=${rec_list[i]}
8379                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8380                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8381                 oid=$((16#$oid))
8382
8383                 case $fstype in
8384                         ldiskfs )
8385                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8386                         zfs )
8387                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8388                 esac
8389                 echo "obj_file is $obj_file"
8390                 do_facet mgs $llog_reader $obj_file
8391
8392                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8393                         awk '{ print $3 }' | sed -e "s/^type=//g")
8394                 if [ $rec_type != $rec ]; then
8395                         echo "FAILED test_60a wrong record type $rec_type," \
8396                               "should be $rec"
8397                         pass=false
8398                         break
8399                 fi
8400
8401                 #check obj path if record type is LLOG_LOGID_MAGIC
8402                 if [ "$rec" == "1064553b" ]; then
8403                         path=$(do_facet mgs $llog_reader $obj_file |
8404                                 grep "path=" | awk '{ print $NF }' |
8405                                 sed -e "s/^path=//g")
8406                         if [ $obj_file != $mntpt/$path ]; then
8407                                 echo "FAILED test_60a wrong obj path" \
8408                                       "$montpt/$path, should be $obj_file"
8409                                 pass=false
8410                                 break
8411                         fi
8412                 fi
8413         done
8414         rm -f $TMP/$tfile
8415         #restart mgs before "error", otherwise it will block the next test
8416         stop mgs || error "stop mgs failed"
8417         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8418         $pass || error "test failed, see FAILED test_60a messages for specifics"
8419 }
8420 run_test 60a "llog_test run from kernel module and test llog_reader"
8421
8422 test_60b() { # bug 6411
8423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8424
8425         dmesg > $DIR/$tfile
8426         LLOG_COUNT=$(do_facet mgs dmesg |
8427                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8428                           /llog_[a-z]*.c:[0-9]/ {
8429                                 if (marker)
8430                                         from_marker++
8431                                 from_begin++
8432                           }
8433                           END {
8434                                 if (marker)
8435                                         print from_marker
8436                                 else
8437                                         print from_begin
8438                           }")
8439
8440         [[ $LLOG_COUNT -gt 120 ]] &&
8441                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8442 }
8443 run_test 60b "limit repeated messages from CERROR/CWARN"
8444
8445 test_60c() {
8446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8447
8448         echo "create 5000 files"
8449         createmany -o $DIR/f60c- 5000
8450 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8451         lctl set_param fail_loc=0x80000137
8452         unlinkmany $DIR/f60c- 5000
8453         lctl set_param fail_loc=0
8454 }
8455 run_test 60c "unlink file when mds full"
8456
8457 test_60d() {
8458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8459
8460         SAVEPRINTK=$(lctl get_param -n printk)
8461         # verify "lctl mark" is even working"
8462         MESSAGE="test message ID $RANDOM $$"
8463         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8464         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8465
8466         lctl set_param printk=0 || error "set lnet.printk failed"
8467         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8468         MESSAGE="new test message ID $RANDOM $$"
8469         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8470         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8471         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8472
8473         lctl set_param -n printk="$SAVEPRINTK"
8474 }
8475 run_test 60d "test printk console message masking"
8476
8477 test_60e() {
8478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8479         remote_mds_nodsh && skip "remote MDS with nodsh"
8480
8481         touch $DIR/$tfile
8482 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8483         do_facet mds1 lctl set_param fail_loc=0x15b
8484         rm $DIR/$tfile
8485 }
8486 run_test 60e "no space while new llog is being created"
8487
8488 test_60f() {
8489         local old_path=$($LCTL get_param -n debug_path)
8490
8491         stack_trap "$LCTL set_param debug_path=$old_path"
8492         stack_trap "rm -f $TMP/$tfile*"
8493         rm -f $TMP/$tfile* 2> /dev/null
8494         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8495         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8496         test_mkdir $DIR/$tdir
8497         # retry in case the open is cached and not released
8498         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8499                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8500                 sleep 0.1
8501         done
8502         ls $TMP/$tfile*
8503         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8504 }
8505 run_test 60f "change debug_path works"
8506
8507 test_60g() {
8508         local pid
8509         local i
8510
8511         test_mkdir -c $MDSCOUNT $DIR/$tdir
8512
8513         (
8514                 local index=0
8515                 while true; do
8516                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8517                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8518                                 2>/dev/null
8519                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8520                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8521                         index=$((index + 1))
8522                 done
8523         ) &
8524
8525         pid=$!
8526
8527         for i in {0..100}; do
8528                 # define OBD_FAIL_OSD_TXN_START    0x19a
8529                 local index=$((i % MDSCOUNT + 1))
8530
8531                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8532                         > /dev/null
8533                 sleep 0.01
8534         done
8535
8536         kill -9 $pid
8537
8538         for i in $(seq $MDSCOUNT); do
8539                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8540         done
8541
8542         mkdir $DIR/$tdir/new || error "mkdir failed"
8543         rmdir $DIR/$tdir/new || error "rmdir failed"
8544
8545         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8546                 -t namespace
8547         for i in $(seq $MDSCOUNT); do
8548                 wait_update_facet mds$i "$LCTL get_param -n \
8549                         mdd.$(facet_svc mds$i).lfsck_namespace |
8550                         awk '/^status/ { print \\\$2 }'" "completed"
8551         done
8552
8553         ls -R $DIR/$tdir
8554         rm -rf $DIR/$tdir || error "rmdir failed"
8555 }
8556 run_test 60g "transaction abort won't cause MDT hung"
8557
8558 test_60h() {
8559         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8560                 skip "Need MDS version at least 2.12.52"
8561         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8562
8563         local f
8564
8565         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8566         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8567         for fail_loc in 0x80000188 0x80000189; do
8568                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8569                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8570                         error "mkdir $dir-$fail_loc failed"
8571                 for i in {0..10}; do
8572                         # create may fail on missing stripe
8573                         echo $i > $DIR/$tdir-$fail_loc/$i
8574                 done
8575                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8576                         error "getdirstripe $tdir-$fail_loc failed"
8577                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8578                         error "migrate $tdir-$fail_loc failed"
8579                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8580                         error "getdirstripe $tdir-$fail_loc failed"
8581                 pushd $DIR/$tdir-$fail_loc
8582                 for f in *; do
8583                         echo $f | cmp $f - || error "$f data mismatch"
8584                 done
8585                 popd
8586                 rm -rf $DIR/$tdir-$fail_loc
8587         done
8588 }
8589 run_test 60h "striped directory with missing stripes can be accessed"
8590
8591 function t60i_load() {
8592         mkdir $DIR/$tdir
8593         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8594         $LCTL set_param fail_loc=0x131c fail_val=1
8595         for ((i=0; i<5000; i++)); do
8596                 touch $DIR/$tdir/f$i
8597         done
8598 }
8599
8600 test_60i() {
8601         changelog_register || error "changelog_register failed"
8602         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8603         changelog_users $SINGLEMDS | grep -q $cl_user ||
8604                 error "User $cl_user not found in changelog_users"
8605         changelog_chmask "ALL"
8606         t60i_load &
8607         local PID=$!
8608         for((i=0; i<100; i++)); do
8609                 changelog_dump >/dev/null ||
8610                         error "can't read changelog"
8611         done
8612         kill $PID
8613         wait $PID
8614         changelog_deregister || error "changelog_deregister failed"
8615         $LCTL set_param fail_loc=0
8616 }
8617 run_test 60i "llog: new record vs reader race"
8618
8619 test_61a() {
8620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8621
8622         f="$DIR/f61"
8623         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8624         cancel_lru_locks osc
8625         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8626         sync
8627 }
8628 run_test 61a "mmap() writes don't make sync hang ================"
8629
8630 test_61b() {
8631         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8632 }
8633 run_test 61b "mmap() of unstriped file is successful"
8634
8635 # bug 2330 - insufficient obd_match error checking causes LBUG
8636 test_62() {
8637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8638
8639         f="$DIR/f62"
8640         echo foo > $f
8641         cancel_lru_locks osc
8642         lctl set_param fail_loc=0x405
8643         cat $f && error "cat succeeded, expect -EIO"
8644         lctl set_param fail_loc=0
8645 }
8646 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8647 # match every page all of the time.
8648 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8649
8650 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8651 # Though this test is irrelevant anymore, it helped to reveal some
8652 # other grant bugs (LU-4482), let's keep it.
8653 test_63a() {   # was test_63
8654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8655
8656         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8657
8658         for i in `seq 10` ; do
8659                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8660                 sleep 5
8661                 kill $!
8662                 sleep 1
8663         done
8664
8665         rm -f $DIR/f63 || true
8666 }
8667 run_test 63a "Verify oig_wait interruption does not crash ======="
8668
8669 # bug 2248 - async write errors didn't return to application on sync
8670 # bug 3677 - async write errors left page locked
8671 test_63b() {
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         debugsave
8675         lctl set_param debug=-1
8676
8677         # ensure we have a grant to do async writes
8678         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8679         rm $DIR/$tfile
8680
8681         sync    # sync lest earlier test intercept the fail_loc
8682
8683         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8684         lctl set_param fail_loc=0x80000406
8685         $MULTIOP $DIR/$tfile Owy && \
8686                 error "sync didn't return ENOMEM"
8687         sync; sleep 2; sync     # do a real sync this time to flush page
8688         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8689                 error "locked page left in cache after async error" || true
8690         debugrestore
8691 }
8692 run_test 63b "async write errors should be returned to fsync ==="
8693
8694 test_64a () {
8695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8696
8697         lfs df $DIR
8698         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8699 }
8700 run_test 64a "verify filter grant calculations (in kernel) ====="
8701
8702 test_64b () {
8703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8704
8705         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8706 }
8707 run_test 64b "check out-of-space detection on client"
8708
8709 test_64c() {
8710         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8711 }
8712 run_test 64c "verify grant shrink"
8713
8714 import_param() {
8715         local tgt=$1
8716         local param=$2
8717
8718         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8719 }
8720
8721 # this does exactly what osc_request.c:osc_announce_cached() does in
8722 # order to calculate max amount of grants to ask from server
8723 want_grant() {
8724         local tgt=$1
8725
8726         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8727         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8728
8729         ((rpc_in_flight++));
8730         nrpages=$((nrpages * rpc_in_flight))
8731
8732         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8733
8734         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8735
8736         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8737         local undirty=$((nrpages * PAGE_SIZE))
8738
8739         local max_extent_pages
8740         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8741         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8742         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8743         local grant_extent_tax
8744         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8745
8746         undirty=$((undirty + nrextents * grant_extent_tax))
8747
8748         echo $undirty
8749 }
8750
8751 # this is size of unit for grant allocation. It should be equal to
8752 # what tgt_grant.c:tgt_grant_chunk() calculates
8753 grant_chunk() {
8754         local tgt=$1
8755         local max_brw_size
8756         local grant_extent_tax
8757
8758         max_brw_size=$(import_param $tgt max_brw_size)
8759
8760         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8761
8762         echo $(((max_brw_size + grant_extent_tax) * 2))
8763 }
8764
8765 test_64d() {
8766         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8767                 skip "OST < 2.10.55 doesn't limit grants enough"
8768
8769         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8770
8771         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8772                 skip "no grant_param connect flag"
8773
8774         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8775
8776         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8777         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8778
8779
8780         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8781         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8782
8783         $LFS setstripe $DIR/$tfile -i 0 -c 1
8784         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8785         ddpid=$!
8786
8787         while kill -0 $ddpid; do
8788                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8789
8790                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8791                         kill $ddpid
8792                         error "cur_grant $cur_grant > $max_cur_granted"
8793                 fi
8794
8795                 sleep 1
8796         done
8797 }
8798 run_test 64d "check grant limit exceed"
8799
8800 check_grants() {
8801         local tgt=$1
8802         local expected=$2
8803         local msg=$3
8804         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8805
8806         ((cur_grants == expected)) ||
8807                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8808 }
8809
8810 round_up_p2() {
8811         echo $((($1 + $2 - 1) & ~($2 - 1)))
8812 }
8813
8814 test_64e() {
8815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8816         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8817                 skip "Need OSS version at least 2.11.56"
8818
8819         # Remount client to reset grant
8820         remount_client $MOUNT || error "failed to remount client"
8821         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8822
8823         local init_grants=$(import_param $osc_tgt initial_grant)
8824
8825         check_grants $osc_tgt $init_grants "init grants"
8826
8827         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8828         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8829         local gbs=$(import_param $osc_tgt grant_block_size)
8830
8831         # write random number of bytes from max_brw_size / 4 to max_brw_size
8832         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8833         # align for direct io
8834         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8835         # round to grant consumption unit
8836         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8837
8838         local grants=$((wb_round_up + extent_tax))
8839
8840         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8841
8842         # define OBD_FAIL_TGT_NO_GRANT 0x725
8843         # make the server not grant more back
8844         do_facet ost1 $LCTL set_param fail_loc=0x725
8845         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8846
8847         do_facet ost1 $LCTL set_param fail_loc=0
8848
8849         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8850
8851         rm -f $DIR/$tfile || error "rm failed"
8852
8853         # Remount client to reset grant
8854         remount_client $MOUNT || error "failed to remount client"
8855         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8856
8857         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8858
8859         # define OBD_FAIL_TGT_NO_GRANT 0x725
8860         # make the server not grant more back
8861         do_facet ost1 $LCTL set_param fail_loc=0x725
8862         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8863         do_facet ost1 $LCTL set_param fail_loc=0
8864
8865         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8866 }
8867 run_test 64e "check grant consumption (no grant allocation)"
8868
8869 test_64f() {
8870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8871
8872         # Remount client to reset grant
8873         remount_client $MOUNT || error "failed to remount client"
8874         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8875
8876         local init_grants=$(import_param $osc_tgt initial_grant)
8877         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8878         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8879         local gbs=$(import_param $osc_tgt grant_block_size)
8880         local chunk=$(grant_chunk $osc_tgt)
8881
8882         # write random number of bytes from max_brw_size / 4 to max_brw_size
8883         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8884         # align for direct io
8885         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8886         # round to grant consumption unit
8887         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8888
8889         local grants=$((wb_round_up + extent_tax))
8890
8891         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8892         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8893                 error "error writing to $DIR/$tfile"
8894
8895         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8896                 "direct io with grant allocation"
8897
8898         rm -f $DIR/$tfile || error "rm failed"
8899
8900         # Remount client to reset grant
8901         remount_client $MOUNT || error "failed to remount client"
8902         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8903
8904         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8905
8906         local cmd="oO_WRONLY:w${write_bytes}_yc"
8907
8908         $MULTIOP $DIR/$tfile $cmd &
8909         MULTIPID=$!
8910         sleep 1
8911
8912         check_grants $osc_tgt $((init_grants - grants)) \
8913                 "buffered io, not write rpc"
8914
8915         kill -USR1 $MULTIPID
8916         wait
8917
8918         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8919                 "buffered io, one RPC"
8920 }
8921 run_test 64f "check grant consumption (with grant allocation)"
8922
8923 test_64g() {
8924         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8925                 skip "Need MDS version at least 2.14.56"
8926
8927         local mdts=$(comma_list $(mdts_nodes))
8928
8929         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8930                         tr '\n' ' ')
8931         stack_trap "$LCTL set_param $old"
8932
8933         # generate dirty pages and increase dirty granted on MDT
8934         stack_trap "rm -f $DIR/$tfile-*"
8935         for (( i = 0; i < 10; i++)); do
8936                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8937                         error "can't set stripe"
8938                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8939                         error "can't dd"
8940                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8941                         $LFS getstripe $DIR/$tfile-$i
8942                         error "not DoM file"
8943                 }
8944         done
8945
8946         # flush dirty pages
8947         sync
8948
8949         # wait until grant shrink reset grant dirty on MDTs
8950         for ((i = 0; i < 120; i++)); do
8951                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8952                         awk '{sum=sum+$1} END {print sum}')
8953                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8954                 echo "$grant_dirty grants, $vm_dirty pages"
8955                 (( grant_dirty + vm_dirty == 0 )) && break
8956                 (( i == 3 )) && sync &&
8957                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8958                 sleep 1
8959         done
8960
8961         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8962                 awk '{sum=sum+$1} END {print sum}')
8963         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8964 }
8965 run_test 64g "grant shrink on MDT"
8966
8967 test_64h() {
8968         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
8969                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
8970
8971         local instance=$($LFS getname -i $DIR)
8972         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8973         local num_exps=$(do_facet ost1 \
8974             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8975         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8976         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8977         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8978
8979         # 10MiB is for file to be written, max_brw_size * 16 *
8980         # num_exps is space reserve so that tgt_grant_shrink() decided
8981         # to not shrink
8982         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8983         (( avail * 1024 < expect )) &&
8984                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8985
8986         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8987         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8988         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8989         $LCTL set_param osc.*OST0000*.grant_shrink=1
8990         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8991
8992         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8993         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8994
8995         # drop cache so that coming read would do rpc
8996         cancel_lru_locks osc
8997
8998         # shrink interval is set to 10, pause for 7 seconds so that
8999         # grant thread did not wake up yet but coming read entered
9000         # shrink mode for rpc (osc_should_shrink_grant())
9001         sleep 7
9002
9003         declare -a cur_grant_bytes
9004         declare -a tot_granted
9005         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9006         tot_granted[0]=$(do_facet ost1 \
9007             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9008
9009         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9010
9011         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9012         tot_granted[1]=$(do_facet ost1 \
9013             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9014
9015         # grant change should be equal on both sides
9016         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9017                 tot_granted[0] - tot_granted[1])) ||
9018                 error "grant change mismatch, "                                \
9019                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9020                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9021 }
9022 run_test 64h "grant shrink on read"
9023
9024 test_64i() {
9025         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9026                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9027
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029         remote_ost_nodsh && skip "remote OSTs with nodsh"
9030
9031         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9032
9033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9034
9035         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9036         local instance=$($LFS getname -i $DIR)
9037
9038         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9039         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9040
9041         # shrink grants and simulate rpc loss
9042         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9043         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9044         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9045
9046         fail ost1
9047
9048         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9049
9050         local testid=$(echo $TESTNAME | tr '_' ' ')
9051
9052         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9053                 grep "GRANT, real grant" &&
9054                 error "client has more grants then it owns" || true
9055 }
9056 run_test 64i "shrink on reconnect"
9057
9058 # bug 1414 - set/get directories' stripe info
9059 test_65a() {
9060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9061
9062         test_mkdir $DIR/$tdir
9063         touch $DIR/$tdir/f1
9064         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9065 }
9066 run_test 65a "directory with no stripe info"
9067
9068 test_65b() {
9069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9070
9071         test_mkdir $DIR/$tdir
9072         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9073
9074         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9075                                                 error "setstripe"
9076         touch $DIR/$tdir/f2
9077         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9078 }
9079 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9080
9081 test_65c() {
9082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9083         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9084
9085         test_mkdir $DIR/$tdir
9086         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9087
9088         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9089                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9090         touch $DIR/$tdir/f3
9091         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9092 }
9093 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9094
9095 test_65d() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097
9098         test_mkdir $DIR/$tdir
9099         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9100         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9101
9102         if [[ $STRIPECOUNT -le 0 ]]; then
9103                 sc=1
9104         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9105                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9106                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9107         else
9108                 sc=$(($STRIPECOUNT - 1))
9109         fi
9110         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9111         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9112         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9113                 error "lverify failed"
9114 }
9115 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9116
9117 test_65e() {
9118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9119
9120         test_mkdir $DIR/$tdir
9121
9122         $LFS setstripe $DIR/$tdir || error "setstripe"
9123         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9124                                         error "no stripe info failed"
9125         touch $DIR/$tdir/f6
9126         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9127 }
9128 run_test 65e "directory setstripe defaults"
9129
9130 test_65f() {
9131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9132
9133         test_mkdir $DIR/${tdir}f
9134         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9135                 error "setstripe succeeded" || true
9136 }
9137 run_test 65f "dir setstripe permission (should return error) ==="
9138
9139 test_65g() {
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141
9142         test_mkdir $DIR/$tdir
9143         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9144
9145         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9146                 error "setstripe -S failed"
9147         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9148         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9149                 error "delete default stripe failed"
9150 }
9151 run_test 65g "directory setstripe -d"
9152
9153 test_65h() {
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155
9156         test_mkdir $DIR/$tdir
9157         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9158
9159         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9160                 error "setstripe -S failed"
9161         test_mkdir $DIR/$tdir/dd1
9162         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9163                 error "stripe info inherit failed"
9164 }
9165 run_test 65h "directory stripe info inherit ===================="
9166
9167 test_65i() {
9168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9169
9170         save_layout_restore_at_exit $MOUNT
9171
9172         # bug6367: set non-default striping on root directory
9173         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9174
9175         # bug12836: getstripe on -1 default directory striping
9176         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9177
9178         # bug12836: getstripe -v on -1 default directory striping
9179         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9180
9181         # bug12836: new find on -1 default directory striping
9182         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9183 }
9184 run_test 65i "various tests to set root directory striping"
9185
9186 test_65j() { # bug6367
9187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9188
9189         sync; sleep 1
9190
9191         # if we aren't already remounting for each test, do so for this test
9192         if [ "$I_MOUNTED" = "yes" ]; then
9193                 cleanup || error "failed to unmount"
9194                 setup
9195         fi
9196
9197         save_layout_restore_at_exit $MOUNT
9198
9199         $LFS setstripe -d $MOUNT || error "setstripe failed"
9200 }
9201 run_test 65j "set default striping on root directory (bug 6367)="
9202
9203 cleanup_65k() {
9204         rm -rf $DIR/$tdir
9205         wait_delete_completed
9206         do_facet $SINGLEMDS "lctl set_param -n \
9207                 osp.$ost*MDT0000.max_create_count=$max_count"
9208         do_facet $SINGLEMDS "lctl set_param -n \
9209                 osp.$ost*MDT0000.create_count=$count"
9210         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9211         echo $INACTIVE_OSC "is Activate"
9212
9213         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9214 }
9215
9216 test_65k() { # bug11679
9217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9218         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9219         remote_mds_nodsh && skip "remote MDS with nodsh"
9220
9221         local disable_precreate=true
9222         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9223                 disable_precreate=false
9224
9225         echo "Check OST status: "
9226         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9227                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9228
9229         for OSC in $MDS_OSCS; do
9230                 echo $OSC "is active"
9231                 do_facet $SINGLEMDS lctl --device %$OSC activate
9232         done
9233
9234         for INACTIVE_OSC in $MDS_OSCS; do
9235                 local ost=$(osc_to_ost $INACTIVE_OSC)
9236                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9237                                lov.*md*.target_obd |
9238                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9239
9240                 mkdir -p $DIR/$tdir
9241                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9242                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9243
9244                 echo "Deactivate: " $INACTIVE_OSC
9245                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9246
9247                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9248                               osp.$ost*MDT0000.create_count")
9249                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9250                                   osp.$ost*MDT0000.max_create_count")
9251                 $disable_precreate &&
9252                         do_facet $SINGLEMDS "lctl set_param -n \
9253                                 osp.$ost*MDT0000.max_create_count=0"
9254
9255                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9256                         [ -f $DIR/$tdir/$idx ] && continue
9257                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9258                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9259                                 { cleanup_65k;
9260                                   error "setstripe $idx should succeed"; }
9261                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9262                 done
9263                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9264                 rmdir $DIR/$tdir
9265
9266                 do_facet $SINGLEMDS "lctl set_param -n \
9267                         osp.$ost*MDT0000.max_create_count=$max_count"
9268                 do_facet $SINGLEMDS "lctl set_param -n \
9269                         osp.$ost*MDT0000.create_count=$count"
9270                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9271                 echo $INACTIVE_OSC "is Activate"
9272
9273                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9274         done
9275 }
9276 run_test 65k "validate manual striping works properly with deactivated OSCs"
9277
9278 test_65l() { # bug 12836
9279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9280
9281         test_mkdir -p $DIR/$tdir/test_dir
9282         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9283         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9284 }
9285 run_test 65l "lfs find on -1 stripe dir ========================"
9286
9287 test_65m() {
9288         local layout=$(save_layout $MOUNT)
9289         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9290                 restore_layout $MOUNT $layout
9291                 error "setstripe should fail by non-root users"
9292         }
9293         true
9294 }
9295 run_test 65m "normal user can't set filesystem default stripe"
9296
9297 test_65n() {
9298         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9299         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9300                 skip "Need MDS version at least 2.12.50"
9301         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9302
9303         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9304         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9305         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9306
9307         save_layout_restore_at_exit $MOUNT
9308
9309         # new subdirectory under root directory should not inherit
9310         # the default layout from root
9311         local dir1=$MOUNT/$tdir-1
9312         mkdir $dir1 || error "mkdir $dir1 failed"
9313         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9314                 error "$dir1 shouldn't have LOV EA"
9315
9316         # delete the default layout on root directory
9317         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9318
9319         local dir2=$MOUNT/$tdir-2
9320         mkdir $dir2 || error "mkdir $dir2 failed"
9321         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9322                 error "$dir2 shouldn't have LOV EA"
9323
9324         # set a new striping pattern on root directory
9325         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9326         local new_def_stripe_size=$((def_stripe_size * 2))
9327         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9328                 error "set stripe size on $MOUNT failed"
9329
9330         # new file created in $dir2 should inherit the new stripe size from
9331         # the filesystem default
9332         local file2=$dir2/$tfile-2
9333         touch $file2 || error "touch $file2 failed"
9334
9335         local file2_stripe_size=$($LFS getstripe -S $file2)
9336         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9337         {
9338                 echo "file2_stripe_size: '$file2_stripe_size'"
9339                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9340                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9341         }
9342
9343         local dir3=$MOUNT/$tdir-3
9344         mkdir $dir3 || error "mkdir $dir3 failed"
9345         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9346         # the root layout, which is the actual default layout that will be used
9347         # when new files are created in $dir3.
9348         local dir3_layout=$(get_layout_param $dir3)
9349         local root_dir_layout=$(get_layout_param $MOUNT)
9350         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9351         {
9352                 echo "dir3_layout: '$dir3_layout'"
9353                 echo "root_dir_layout: '$root_dir_layout'"
9354                 error "$dir3 should show the default layout from $MOUNT"
9355         }
9356
9357         # set OST pool on root directory
9358         local pool=$TESTNAME
9359         pool_add $pool || error "add $pool failed"
9360         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9361                 error "add targets to $pool failed"
9362
9363         $LFS setstripe -p $pool $MOUNT ||
9364                 error "set OST pool on $MOUNT failed"
9365
9366         # new file created in $dir3 should inherit the pool from
9367         # the filesystem default
9368         local file3=$dir3/$tfile-3
9369         touch $file3 || error "touch $file3 failed"
9370
9371         local file3_pool=$($LFS getstripe -p $file3)
9372         [[ "$file3_pool" = "$pool" ]] ||
9373                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9374
9375         local dir4=$MOUNT/$tdir-4
9376         mkdir $dir4 || error "mkdir $dir4 failed"
9377         local dir4_layout=$(get_layout_param $dir4)
9378         root_dir_layout=$(get_layout_param $MOUNT)
9379         echo "$LFS getstripe -d $dir4"
9380         $LFS getstripe -d $dir4
9381         echo "$LFS getstripe -d $MOUNT"
9382         $LFS getstripe -d $MOUNT
9383         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9384         {
9385                 echo "dir4_layout: '$dir4_layout'"
9386                 echo "root_dir_layout: '$root_dir_layout'"
9387                 error "$dir4 should show the default layout from $MOUNT"
9388         }
9389
9390         # new file created in $dir4 should inherit the pool from
9391         # the filesystem default
9392         local file4=$dir4/$tfile-4
9393         touch $file4 || error "touch $file4 failed"
9394
9395         local file4_pool=$($LFS getstripe -p $file4)
9396         [[ "$file4_pool" = "$pool" ]] ||
9397                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9398
9399         # new subdirectory under non-root directory should inherit
9400         # the default layout from its parent directory
9401         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9402                 error "set directory layout on $dir4 failed"
9403
9404         local dir5=$dir4/$tdir-5
9405         mkdir $dir5 || error "mkdir $dir5 failed"
9406
9407         dir4_layout=$(get_layout_param $dir4)
9408         local dir5_layout=$(get_layout_param $dir5)
9409         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9410         {
9411                 echo "dir4_layout: '$dir4_layout'"
9412                 echo "dir5_layout: '$dir5_layout'"
9413                 error "$dir5 should inherit the default layout from $dir4"
9414         }
9415
9416         # though subdir under ROOT doesn't inherit default layout, but
9417         # its sub dir/file should be created with default layout.
9418         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9419         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9420                 skip "Need MDS version at least 2.12.59"
9421
9422         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9423         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9424         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9425
9426         if [ $default_lmv_hash == "none" ]; then
9427                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9428         else
9429                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9430                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9431         fi
9432
9433         $LFS setdirstripe -D -c 2 $MOUNT ||
9434                 error "setdirstripe -D -c 2 failed"
9435         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9436         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9437         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9438
9439         # $dir4 layout includes pool
9440         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9441         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9442                 error "pool lost on setstripe"
9443         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9444         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9445                 error "pool lost on compound layout setstripe"
9446 }
9447 run_test 65n "don't inherit default layout from root for new subdirectories"
9448
9449 # bug 2543 - update blocks count on client
9450 test_66() {
9451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9452
9453         COUNT=${COUNT:-8}
9454         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9455         sync; sync_all_data; sync; sync_all_data
9456         cancel_lru_locks osc
9457         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9458         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9459 }
9460 run_test 66 "update inode blocks count on client ==============="
9461
9462 meminfo() {
9463         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9464 }
9465
9466 swap_used() {
9467         swapon -s | awk '($1 == "'$1'") { print $4 }'
9468 }
9469
9470 # bug5265, obdfilter oa2dentry return -ENOENT
9471 # #define OBD_FAIL_SRV_ENOENT 0x217
9472 test_69() {
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         remote_ost_nodsh && skip "remote OST with nodsh"
9475
9476         f="$DIR/$tfile"
9477         $LFS setstripe -c 1 -i 0 $f
9478
9479         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9480
9481         do_facet ost1 lctl set_param fail_loc=0x217
9482         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9483         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9484
9485         do_facet ost1 lctl set_param fail_loc=0
9486         $DIRECTIO write $f 0 2 || error "write error"
9487
9488         cancel_lru_locks osc
9489         $DIRECTIO read $f 0 1 || error "read error"
9490
9491         do_facet ost1 lctl set_param fail_loc=0x217
9492         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9493
9494         do_facet ost1 lctl set_param fail_loc=0
9495         rm -f $f
9496 }
9497 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9498
9499 test_71() {
9500         test_mkdir $DIR/$tdir
9501         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9502         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9503 }
9504 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9505
9506 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9508         [ "$RUNAS_ID" = "$UID" ] &&
9509                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9510         # Check that testing environment is properly set up. Skip if not
9511         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9512                 skip_env "User $RUNAS_ID does not exist - skipping"
9513
9514         touch $DIR/$tfile
9515         chmod 777 $DIR/$tfile
9516         chmod ug+s $DIR/$tfile
9517         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9518                 error "$RUNAS dd $DIR/$tfile failed"
9519         # See if we are still setuid/sgid
9520         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9521                 error "S/gid is not dropped on write"
9522         # Now test that MDS is updated too
9523         cancel_lru_locks mdc
9524         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9525                 error "S/gid is not dropped on MDS"
9526         rm -f $DIR/$tfile
9527 }
9528 run_test 72a "Test that remove suid works properly (bug5695) ===="
9529
9530 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9531         local perm
9532
9533         [ "$RUNAS_ID" = "$UID" ] &&
9534                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9535         [ "$RUNAS_ID" -eq 0 ] &&
9536                 skip_env "RUNAS_ID = 0 -- skipping"
9537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9538         # Check that testing environment is properly set up. Skip if not
9539         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9540                 skip_env "User $RUNAS_ID does not exist - skipping"
9541
9542         touch $DIR/${tfile}-f{g,u}
9543         test_mkdir $DIR/${tfile}-dg
9544         test_mkdir $DIR/${tfile}-du
9545         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9546         chmod g+s $DIR/${tfile}-{f,d}g
9547         chmod u+s $DIR/${tfile}-{f,d}u
9548         for perm in 777 2777 4777; do
9549                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9550                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9551                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9552                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9553         done
9554         true
9555 }
9556 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9557
9558 # bug 3462 - multiple simultaneous MDC requests
9559 test_73() {
9560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9561
9562         test_mkdir $DIR/d73-1
9563         test_mkdir $DIR/d73-2
9564         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9565         pid1=$!
9566
9567         lctl set_param fail_loc=0x80000129
9568         $MULTIOP $DIR/d73-1/f73-2 Oc &
9569         sleep 1
9570         lctl set_param fail_loc=0
9571
9572         $MULTIOP $DIR/d73-2/f73-3 Oc &
9573         pid3=$!
9574
9575         kill -USR1 $pid1
9576         wait $pid1 || return 1
9577
9578         sleep 25
9579
9580         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9581         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9582         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9583
9584         rm -rf $DIR/d73-*
9585 }
9586 run_test 73 "multiple MDC requests (should not deadlock)"
9587
9588 test_74a() { # bug 6149, 6184
9589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9590
9591         touch $DIR/f74a
9592         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9593         #
9594         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9595         # will spin in a tight reconnection loop
9596         $LCTL set_param fail_loc=0x8000030e
9597         # get any lock that won't be difficult - lookup works.
9598         ls $DIR/f74a
9599         $LCTL set_param fail_loc=0
9600         rm -f $DIR/f74a
9601         true
9602 }
9603 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9604
9605 test_74b() { # bug 13310
9606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9607
9608         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9609         #
9610         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9611         # will spin in a tight reconnection loop
9612         $LCTL set_param fail_loc=0x8000030e
9613         # get a "difficult" lock
9614         touch $DIR/f74b
9615         $LCTL set_param fail_loc=0
9616         rm -f $DIR/f74b
9617         true
9618 }
9619 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9620
9621 test_74c() {
9622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9623
9624         #define OBD_FAIL_LDLM_NEW_LOCK
9625         $LCTL set_param fail_loc=0x319
9626         touch $DIR/$tfile && error "touch successful"
9627         $LCTL set_param fail_loc=0
9628         true
9629 }
9630 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9631
9632 slab_lic=/sys/kernel/slab/lustre_inode_cache
9633 num_objects() {
9634         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9635         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9636                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9637 }
9638
9639 test_76a() { # Now for b=20433, added originally in b=1443
9640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9641
9642         cancel_lru_locks osc
9643         # there may be some slab objects cached per core
9644         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9645         local before=$(num_objects)
9646         local count=$((512 * cpus))
9647         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9648         local margin=$((count / 10))
9649         if [[ -f $slab_lic/aliases ]]; then
9650                 local aliases=$(cat $slab_lic/aliases)
9651                 (( aliases > 0 )) && margin=$((margin * aliases))
9652         fi
9653
9654         echo "before slab objects: $before"
9655         for i in $(seq $count); do
9656                 touch $DIR/$tfile
9657                 rm -f $DIR/$tfile
9658         done
9659         cancel_lru_locks osc
9660         local after=$(num_objects)
9661         echo "created: $count, after slab objects: $after"
9662         # shared slab counts are not very accurate, allow significant margin
9663         # the main goal is that the cache growth is not permanently > $count
9664         while (( after > before + margin )); do
9665                 sleep 1
9666                 after=$(num_objects)
9667                 wait=$((wait + 1))
9668                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9669                 if (( wait > 60 )); then
9670                         error "inode slab grew from $before+$margin to $after"
9671                 fi
9672         done
9673 }
9674 run_test 76a "confirm clients recycle inodes properly ===="
9675
9676 test_76b() {
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9679
9680         local count=512
9681         local before=$(num_objects)
9682
9683         for i in $(seq $count); do
9684                 mkdir $DIR/$tdir
9685                 rmdir $DIR/$tdir
9686         done
9687
9688         local after=$(num_objects)
9689         local wait=0
9690
9691         while (( after > before )); do
9692                 sleep 1
9693                 after=$(num_objects)
9694                 wait=$((wait + 1))
9695                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9696                 if (( wait > 60 )); then
9697                         error "inode slab grew from $before to $after"
9698                 fi
9699         done
9700
9701         echo "slab objects before: $before, after: $after"
9702 }
9703 run_test 76b "confirm clients recycle directory inodes properly ===="
9704
9705 export ORIG_CSUM=""
9706 set_checksums()
9707 {
9708         # Note: in sptlrpc modes which enable its own bulk checksum, the
9709         # original crc32_le bulk checksum will be automatically disabled,
9710         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9711         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9712         # In this case set_checksums() will not be no-op, because sptlrpc
9713         # bulk checksum will be enabled all through the test.
9714
9715         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9716         lctl set_param -n osc.*.checksums $1
9717         return 0
9718 }
9719
9720 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9721                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9722 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9723                              tr -d [] | head -n1)}
9724 set_checksum_type()
9725 {
9726         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9727         rc=$?
9728         log "set checksum type to $1, rc = $rc"
9729         return $rc
9730 }
9731
9732 get_osc_checksum_type()
9733 {
9734         # arugment 1: OST name, like OST0000
9735         ost=$1
9736         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9737                         sed 's/.*\[\(.*\)\].*/\1/g')
9738         rc=$?
9739         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9740         echo $checksum_type
9741 }
9742
9743 F77_TMP=$TMP/f77-temp
9744 F77SZ=8
9745 setup_f77() {
9746         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9747                 error "error writing to $F77_TMP"
9748 }
9749
9750 test_77a() { # bug 10889
9751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9752         $GSS && skip_env "could not run with gss"
9753
9754         [ ! -f $F77_TMP ] && setup_f77
9755         set_checksums 1
9756         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9757         set_checksums 0
9758         rm -f $DIR/$tfile
9759 }
9760 run_test 77a "normal checksum read/write operation"
9761
9762 test_77b() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         [ ! -f $F77_TMP ] && setup_f77
9767         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9768         $LCTL set_param fail_loc=0x80000409
9769         set_checksums 1
9770
9771         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9772                 error "dd error: $?"
9773         $LCTL set_param fail_loc=0
9774
9775         for algo in $CKSUM_TYPES; do
9776                 cancel_lru_locks osc
9777                 set_checksum_type $algo
9778                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9779                 $LCTL set_param fail_loc=0x80000408
9780                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9781                 $LCTL set_param fail_loc=0
9782         done
9783         set_checksums 0
9784         set_checksum_type $ORIG_CSUM_TYPE
9785         rm -f $DIR/$tfile
9786 }
9787 run_test 77b "checksum error on client write, read"
9788
9789 cleanup_77c() {
9790         trap 0
9791         set_checksums 0
9792         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9793         $check_ost &&
9794                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9795         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9796         $check_ost && [ -n "$ost_file_prefix" ] &&
9797                 do_facet ost1 rm -f ${ost_file_prefix}\*
9798 }
9799
9800 test_77c() {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802         $GSS && skip_env "could not run with gss"
9803         remote_ost_nodsh && skip "remote OST with nodsh"
9804
9805         local bad1
9806         local osc_file_prefix
9807         local osc_file
9808         local check_ost=false
9809         local ost_file_prefix
9810         local ost_file
9811         local orig_cksum
9812         local dump_cksum
9813         local fid
9814
9815         # ensure corruption will occur on first OSS/OST
9816         $LFS setstripe -i 0 $DIR/$tfile
9817
9818         [ ! -f $F77_TMP ] && setup_f77
9819         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9820                 error "dd write error: $?"
9821         fid=$($LFS path2fid $DIR/$tfile)
9822
9823         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9824         then
9825                 check_ost=true
9826                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9827                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9828         else
9829                 echo "OSS do not support bulk pages dump upon error"
9830         fi
9831
9832         osc_file_prefix=$($LCTL get_param -n debug_path)
9833         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9834
9835         trap cleanup_77c EXIT
9836
9837         set_checksums 1
9838         # enable bulk pages dump upon error on Client
9839         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9840         # enable bulk pages dump upon error on OSS
9841         $check_ost &&
9842                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9843
9844         # flush Client cache to allow next read to reach OSS
9845         cancel_lru_locks osc
9846
9847         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9848         $LCTL set_param fail_loc=0x80000408
9849         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9850         $LCTL set_param fail_loc=0
9851
9852         rm -f $DIR/$tfile
9853
9854         # check cksum dump on Client
9855         osc_file=$(ls ${osc_file_prefix}*)
9856         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9857         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9858         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9859         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9860         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9861                      cksum)
9862         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9863         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9864                 error "dump content does not match on Client"
9865
9866         $check_ost || skip "No need to check cksum dump on OSS"
9867
9868         # check cksum dump on OSS
9869         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9870         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9871         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9872         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9873         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9874                 error "dump content does not match on OSS"
9875
9876         cleanup_77c
9877 }
9878 run_test 77c "checksum error on client read with debug"
9879
9880 test_77d() { # bug 10889
9881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9882         $GSS && skip_env "could not run with gss"
9883
9884         stack_trap "rm -f $DIR/$tfile"
9885         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9886         $LCTL set_param fail_loc=0x80000409
9887         set_checksums 1
9888         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9889                 error "direct write: rc=$?"
9890         $LCTL set_param fail_loc=0
9891         set_checksums 0
9892
9893         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9894         $LCTL set_param fail_loc=0x80000408
9895         set_checksums 1
9896         cancel_lru_locks osc
9897         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9898                 error "direct read: rc=$?"
9899         $LCTL set_param fail_loc=0
9900         set_checksums 0
9901 }
9902 run_test 77d "checksum error on OST direct write, read"
9903
9904 test_77f() { # bug 10889
9905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9906         $GSS && skip_env "could not run with gss"
9907
9908         set_checksums 1
9909         stack_trap "rm -f $DIR/$tfile"
9910         for algo in $CKSUM_TYPES; do
9911                 cancel_lru_locks osc
9912                 set_checksum_type $algo
9913                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9914                 $LCTL set_param fail_loc=0x409
9915                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9916                         error "direct write succeeded"
9917                 $LCTL set_param fail_loc=0
9918         done
9919         set_checksum_type $ORIG_CSUM_TYPE
9920         set_checksums 0
9921 }
9922 run_test 77f "repeat checksum error on write (expect error)"
9923
9924 test_77g() { # bug 10889
9925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9926         $GSS && skip_env "could not run with gss"
9927         remote_ost_nodsh && skip "remote OST with nodsh"
9928
9929         [ ! -f $F77_TMP ] && setup_f77
9930
9931         local file=$DIR/$tfile
9932         stack_trap "rm -f $file" EXIT
9933
9934         $LFS setstripe -c 1 -i 0 $file
9935         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9936         do_facet ost1 lctl set_param fail_loc=0x8000021a
9937         set_checksums 1
9938         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9939                 error "write error: rc=$?"
9940         do_facet ost1 lctl set_param fail_loc=0
9941         set_checksums 0
9942
9943         cancel_lru_locks osc
9944         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9945         do_facet ost1 lctl set_param fail_loc=0x8000021b
9946         set_checksums 1
9947         cmp $F77_TMP $file || error "file compare failed"
9948         do_facet ost1 lctl set_param fail_loc=0
9949         set_checksums 0
9950 }
9951 run_test 77g "checksum error on OST write, read"
9952
9953 test_77k() { # LU-10906
9954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9955         $GSS && skip_env "could not run with gss"
9956
9957         local cksum_param="osc.$FSNAME*.checksums"
9958         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9959         local checksum
9960         local i
9961
9962         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9963         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9964         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9965
9966         for i in 0 1; do
9967                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9968                         error "failed to set checksum=$i on MGS"
9969                 wait_update $HOSTNAME "$get_checksum" $i
9970                 #remount
9971                 echo "remount client, checksum should be $i"
9972                 remount_client $MOUNT || error "failed to remount client"
9973                 checksum=$(eval $get_checksum)
9974                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9975         done
9976         # remove persistent param to avoid races with checksum mountopt below
9977         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9978                 error "failed to delete checksum on MGS"
9979
9980         for opt in "checksum" "nochecksum"; do
9981                 #remount with mount option
9982                 echo "remount client with option $opt, checksum should be $i"
9983                 umount_client $MOUNT || error "failed to umount client"
9984                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9985                         error "failed to mount client with option '$opt'"
9986                 checksum=$(eval $get_checksum)
9987                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9988                 i=$((i - 1))
9989         done
9990
9991         remount_client $MOUNT || error "failed to remount client"
9992 }
9993 run_test 77k "enable/disable checksum correctly"
9994
9995 test_77l() {
9996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9997         $GSS && skip_env "could not run with gss"
9998
9999         set_checksums 1
10000         stack_trap "set_checksums $ORIG_CSUM" EXIT
10001         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10002
10003         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10004
10005         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10006         for algo in $CKSUM_TYPES; do
10007                 set_checksum_type $algo || error "fail to set checksum type $algo"
10008                 osc_algo=$(get_osc_checksum_type OST0000)
10009                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10010
10011                 # no locks, no reqs to let the connection idle
10012                 cancel_lru_locks osc
10013                 lru_resize_disable osc
10014                 wait_osc_import_state client ost1 IDLE
10015
10016                 # ensure ost1 is connected
10017                 stat $DIR/$tfile >/dev/null || error "can't stat"
10018                 wait_osc_import_state client ost1 FULL
10019
10020                 osc_algo=$(get_osc_checksum_type OST0000)
10021                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10022         done
10023         return 0
10024 }
10025 run_test 77l "preferred checksum type is remembered after reconnected"
10026
10027 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10028 rm -f $F77_TMP
10029 unset F77_TMP
10030
10031 test_77m() {
10032         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10033                 skip "Need at least version 2.14.52"
10034         local param=checksum_speed
10035
10036         $LCTL get_param $param || error "reading $param failed"
10037
10038         csum_speeds=$($LCTL get_param -n $param)
10039
10040         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10041                 error "known checksum types are missing"
10042 }
10043 run_test 77m "Verify checksum_speed is correctly read"
10044
10045 check_filefrag_77n() {
10046         local nr_ext=0
10047         local starts=()
10048         local ends=()
10049
10050         while read extidx a b start end rest; do
10051                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10052                         nr_ext=$(( $nr_ext + 1 ))
10053                         starts+=( ${start%..} )
10054                         ends+=( ${end%:} )
10055                 fi
10056         done < <( filefrag -sv $1 )
10057
10058         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10059         return 1
10060 }
10061
10062 test_77n() {
10063         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10064
10065         touch $DIR/$tfile
10066         $TRUNCATE $DIR/$tfile 0
10067         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10068         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10069         check_filefrag_77n $DIR/$tfile ||
10070                 skip "$tfile blocks not contiguous around hole"
10071
10072         set_checksums 1
10073         stack_trap "set_checksums $ORIG_CSUM" EXIT
10074         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10075         stack_trap "rm -f $DIR/$tfile"
10076
10077         for algo in $CKSUM_TYPES; do
10078                 if [[ "$algo" =~ ^t10 ]]; then
10079                         set_checksum_type $algo ||
10080                                 error "fail to set checksum type $algo"
10081                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10082                                 error "fail to read $tfile with $algo"
10083                 fi
10084         done
10085         rm -f $DIR/$tfile
10086         return 0
10087 }
10088 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10089
10090 test_77o() {
10091         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10092                 skip "Need MDS version at least 2.14.55"
10093         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10094                 skip "Need OST version at least 2.14.55"
10095         local ofd=obdfilter
10096         local mdt=mdt
10097
10098         # print OST checksum_type
10099         echo "$ofd.$FSNAME-*.checksum_type:"
10100         do_nodes $(comma_list $(osts_nodes)) \
10101                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10102
10103         # print MDT checksum_type
10104         echo "$mdt.$FSNAME-*.checksum_type:"
10105         do_nodes $(comma_list $(mdts_nodes)) \
10106                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10107
10108         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10109                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10110
10111         (( $o_count == $OSTCOUNT )) ||
10112                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10113
10114         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10115                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10116
10117         (( $m_count == $MDSCOUNT )) ||
10118                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10119 }
10120 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10121
10122 cleanup_test_78() {
10123         trap 0
10124         rm -f $DIR/$tfile
10125 }
10126
10127 test_78() { # bug 10901
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129         remote_ost || skip_env "local OST"
10130
10131         NSEQ=5
10132         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10133         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10134         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10135         echo "MemTotal: $MEMTOTAL"
10136
10137         # reserve 256MB of memory for the kernel and other running processes,
10138         # and then take 1/2 of the remaining memory for the read/write buffers.
10139         if [ $MEMTOTAL -gt 512 ] ;then
10140                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10141         else
10142                 # for those poor memory-starved high-end clusters...
10143                 MEMTOTAL=$((MEMTOTAL / 2))
10144         fi
10145         echo "Mem to use for directio: $MEMTOTAL"
10146
10147         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10148         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10149         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10150         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10151                 head -n1)
10152         echo "Smallest OST: $SMALLESTOST"
10153         [[ $SMALLESTOST -lt 10240 ]] &&
10154                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10155
10156         trap cleanup_test_78 EXIT
10157
10158         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10159                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10160
10161         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10162         echo "File size: $F78SIZE"
10163         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10164         for i in $(seq 1 $NSEQ); do
10165                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10166                 echo directIO rdwr round $i of $NSEQ
10167                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10168         done
10169
10170         cleanup_test_78
10171 }
10172 run_test 78 "handle large O_DIRECT writes correctly ============"
10173
10174 test_79() { # bug 12743
10175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10176
10177         wait_delete_completed
10178
10179         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10180         BKFREE=$(calc_osc_kbytes kbytesfree)
10181         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10182
10183         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10184         DFTOTAL=`echo $STRING | cut -d, -f1`
10185         DFUSED=`echo $STRING  | cut -d, -f2`
10186         DFAVAIL=`echo $STRING | cut -d, -f3`
10187         DFFREE=$(($DFTOTAL - $DFUSED))
10188
10189         ALLOWANCE=$((64 * $OSTCOUNT))
10190
10191         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10192            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10193                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10194         fi
10195         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10196            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10197                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10198         fi
10199         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10200            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10201                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10202         fi
10203 }
10204 run_test 79 "df report consistency check ======================="
10205
10206 test_80() { # bug 10718
10207         remote_ost_nodsh && skip "remote OST with nodsh"
10208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10209
10210         # relax strong synchronous semantics for slow backends like ZFS
10211         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10212                 local soc="obdfilter.*.sync_lock_cancel"
10213                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10214
10215                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10216                 if [ -z "$save" ]; then
10217                         soc="obdfilter.*.sync_on_lock_cancel"
10218                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10219                 fi
10220
10221                 if [ "$save" != "never" ]; then
10222                         local hosts=$(comma_list $(osts_nodes))
10223
10224                         do_nodes $hosts $LCTL set_param $soc=never
10225                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10226                 fi
10227         fi
10228
10229         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10230         sync; sleep 1; sync
10231         local before=$(date +%s)
10232         cancel_lru_locks osc
10233         local after=$(date +%s)
10234         local diff=$((after - before))
10235         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10236
10237         rm -f $DIR/$tfile
10238 }
10239 run_test 80 "Page eviction is equally fast at high offsets too"
10240
10241 test_81a() { # LU-456
10242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10243         remote_ost_nodsh && skip "remote OST with nodsh"
10244
10245         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10246         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10247         do_facet ost1 lctl set_param fail_loc=0x80000228
10248
10249         # write should trigger a retry and success
10250         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10251         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10252         RC=$?
10253         if [ $RC -ne 0 ] ; then
10254                 error "write should success, but failed for $RC"
10255         fi
10256 }
10257 run_test 81a "OST should retry write when get -ENOSPC ==============="
10258
10259 test_81b() { # LU-456
10260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10261         remote_ost_nodsh && skip "remote OST with nodsh"
10262
10263         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10264         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10265         do_facet ost1 lctl set_param fail_loc=0x228
10266
10267         # write should retry several times and return -ENOSPC finally
10268         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10269         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10270         RC=$?
10271         ENOSPC=28
10272         if [ $RC -ne $ENOSPC ] ; then
10273                 error "dd should fail for -ENOSPC, but succeed."
10274         fi
10275 }
10276 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10277
10278 test_99() {
10279         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10280
10281         test_mkdir $DIR/$tdir.cvsroot
10282         chown $RUNAS_ID $DIR/$tdir.cvsroot
10283
10284         cd $TMP
10285         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10286
10287         cd /etc/init.d
10288         # some versions of cvs import exit(1) when asked to import links or
10289         # files they can't read.  ignore those files.
10290         local toignore=$(find . -type l -printf '-I %f\n' -o \
10291                          ! -perm /4 -printf '-I %f\n')
10292         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10293                 $tdir.reposname vtag rtag
10294
10295         cd $DIR
10296         test_mkdir $DIR/$tdir.reposname
10297         chown $RUNAS_ID $DIR/$tdir.reposname
10298         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10299
10300         cd $DIR/$tdir.reposname
10301         $RUNAS touch foo99
10302         $RUNAS cvs add -m 'addmsg' foo99
10303         $RUNAS cvs update
10304         $RUNAS cvs commit -m 'nomsg' foo99
10305         rm -fr $DIR/$tdir.cvsroot
10306 }
10307 run_test 99 "cvs strange file/directory operations"
10308
10309 test_100() {
10310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10311         [[ "$NETTYPE" =~ tcp ]] ||
10312                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10313         remote_ost_nodsh && skip "remote OST with nodsh"
10314         remote_mds_nodsh && skip "remote MDS with nodsh"
10315         remote_servers ||
10316                 skip "useless for local single node setup"
10317
10318         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10319                 [ "$PROT" != "tcp" ] && continue
10320                 RPORT=$(echo $REMOTE | cut -d: -f2)
10321                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10322
10323                 rc=0
10324                 LPORT=`echo $LOCAL | cut -d: -f2`
10325                 if [ $LPORT -ge 1024 ]; then
10326                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10327                         netstat -tna
10328                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10329                 fi
10330         done
10331         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10332 }
10333 run_test 100 "check local port using privileged port ==========="
10334
10335 function get_named_value()
10336 {
10337     local tag=$1
10338
10339     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10340 }
10341
10342 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10343                    awk '/^max_cached_mb/ { print $2 }')
10344
10345 cleanup_101a() {
10346         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10347         trap 0
10348 }
10349
10350 test_101a() {
10351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10352
10353         local s
10354         local discard
10355         local nreads=10000
10356         local cache_limit=32
10357
10358         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10359         trap cleanup_101a EXIT
10360         $LCTL set_param -n llite.*.read_ahead_stats=0
10361         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10362
10363         #
10364         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10365         #
10366         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10367         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10368
10369         discard=0
10370         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10371                    get_named_value 'read.but.discarded'); do
10372                         discard=$(($discard + $s))
10373         done
10374         cleanup_101a
10375
10376         $LCTL get_param osc.*-osc*.rpc_stats
10377         $LCTL get_param llite.*.read_ahead_stats
10378
10379         # Discard is generally zero, but sometimes a few random reads line up
10380         # and trigger larger readahead, which is wasted & leads to discards.
10381         if [[ $(($discard)) -gt $nreads ]]; then
10382                 error "too many ($discard) discarded pages"
10383         fi
10384         rm -f $DIR/$tfile || true
10385 }
10386 run_test 101a "check read-ahead for random reads"
10387
10388 setup_test101bc() {
10389         test_mkdir $DIR/$tdir
10390         local ssize=$1
10391         local FILE_LENGTH=$2
10392         STRIPE_OFFSET=0
10393
10394         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10395
10396         local list=$(comma_list $(osts_nodes))
10397         set_osd_param $list '' read_cache_enable 0
10398         set_osd_param $list '' writethrough_cache_enable 0
10399
10400         trap cleanup_test101bc EXIT
10401         # prepare the read-ahead file
10402         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10403
10404         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10405                                 count=$FILE_SIZE_MB 2> /dev/null
10406
10407 }
10408
10409 cleanup_test101bc() {
10410         trap 0
10411         rm -rf $DIR/$tdir
10412         rm -f $DIR/$tfile
10413
10414         local list=$(comma_list $(osts_nodes))
10415         set_osd_param $list '' read_cache_enable 1
10416         set_osd_param $list '' writethrough_cache_enable 1
10417 }
10418
10419 calc_total() {
10420         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10421 }
10422
10423 ra_check_101() {
10424         local read_size=$1
10425         local stripe_size=$2
10426         local stride_length=$((stripe_size / read_size))
10427         local stride_width=$((stride_length * OSTCOUNT))
10428         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10429                                 (stride_width - stride_length) ))
10430         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10431                   get_named_value 'read.but.discarded' | calc_total)
10432
10433         if [[ $discard -gt $discard_limit ]]; then
10434                 $LCTL get_param llite.*.read_ahead_stats
10435                 error "($discard) discarded pages with size (${read_size})"
10436         else
10437                 echo "Read-ahead success for size ${read_size}"
10438         fi
10439 }
10440
10441 test_101b() {
10442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10443         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10444
10445         local STRIPE_SIZE=1048576
10446         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10447
10448         if [ $SLOW == "yes" ]; then
10449                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10450         else
10451                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10452         fi
10453
10454         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10455
10456         # prepare the read-ahead file
10457         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10458         cancel_lru_locks osc
10459         for BIDX in 2 4 8 16 32 64 128 256
10460         do
10461                 local BSIZE=$((BIDX*4096))
10462                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10463                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10464                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10465                 $LCTL set_param -n llite.*.read_ahead_stats=0
10466                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10467                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10468                 cancel_lru_locks osc
10469                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10470         done
10471         cleanup_test101bc
10472         true
10473 }
10474 run_test 101b "check stride-io mode read-ahead ================="
10475
10476 test_101c() {
10477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10478
10479         local STRIPE_SIZE=1048576
10480         local FILE_LENGTH=$((STRIPE_SIZE*100))
10481         local nreads=10000
10482         local rsize=65536
10483         local osc_rpc_stats
10484
10485         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10486
10487         cancel_lru_locks osc
10488         $LCTL set_param osc.*.rpc_stats=0
10489         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10490         $LCTL get_param osc.*.rpc_stats
10491         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10492                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10493                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10494                 local size
10495
10496                 if [ $lines -le 20 ]; then
10497                         echo "continue debug"
10498                         continue
10499                 fi
10500                 for size in 1 2 4 8; do
10501                         local rpc=$(echo "$stats" |
10502                                     awk '($1 == "'$size':") {print $2; exit; }')
10503                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10504                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10505                 done
10506                 echo "$osc_rpc_stats check passed!"
10507         done
10508         cleanup_test101bc
10509         true
10510 }
10511 run_test 101c "check stripe_size aligned read-ahead"
10512
10513 test_101d() {
10514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10515
10516         local file=$DIR/$tfile
10517         local sz_MB=${FILESIZE_101d:-80}
10518         local ra_MB=${READAHEAD_MB:-40}
10519
10520         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10521         [ $free_MB -lt $sz_MB ] &&
10522                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10523
10524         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10525         $LFS setstripe -c -1 $file || error "setstripe failed"
10526
10527         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10528         echo Cancel LRU locks on lustre client to flush the client cache
10529         cancel_lru_locks osc
10530
10531         echo Disable read-ahead
10532         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10533         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10534         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10535         $LCTL get_param -n llite.*.max_read_ahead_mb
10536
10537         echo "Reading the test file $file with read-ahead disabled"
10538         local sz_KB=$((sz_MB * 1024 / 4))
10539         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10540         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10541         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10542                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10543
10544         echo "Cancel LRU locks on lustre client to flush the client cache"
10545         cancel_lru_locks osc
10546         echo Enable read-ahead with ${ra_MB}MB
10547         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10548
10549         echo "Reading the test file $file with read-ahead enabled"
10550         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10551                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10552
10553         echo "read-ahead disabled time read $raOFF"
10554         echo "read-ahead enabled time read $raON"
10555
10556         rm -f $file
10557         wait_delete_completed
10558
10559         # use awk for this check instead of bash because it handles decimals
10560         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10561                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10562 }
10563 run_test 101d "file read with and without read-ahead enabled"
10564
10565 test_101e() {
10566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10567
10568         local file=$DIR/$tfile
10569         local size_KB=500  #KB
10570         local count=100
10571         local bsize=1024
10572
10573         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10574         local need_KB=$((count * size_KB))
10575         [[ $free_KB -le $need_KB ]] &&
10576                 skip_env "Need free space $need_KB, have $free_KB"
10577
10578         echo "Creating $count ${size_KB}K test files"
10579         for ((i = 0; i < $count; i++)); do
10580                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10581         done
10582
10583         echo "Cancel LRU locks on lustre client to flush the client cache"
10584         cancel_lru_locks $OSC
10585
10586         echo "Reset readahead stats"
10587         $LCTL set_param -n llite.*.read_ahead_stats=0
10588
10589         for ((i = 0; i < $count; i++)); do
10590                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10591         done
10592
10593         $LCTL get_param llite.*.max_cached_mb
10594         $LCTL get_param llite.*.read_ahead_stats
10595         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10596                      get_named_value 'misses' | calc_total)
10597
10598         for ((i = 0; i < $count; i++)); do
10599                 rm -rf $file.$i 2>/dev/null
10600         done
10601
10602         #10000 means 20% reads are missing in readahead
10603         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10604 }
10605 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10606
10607 test_101f() {
10608         which iozone || skip_env "no iozone installed"
10609
10610         local old_debug=$($LCTL get_param debug)
10611         old_debug=${old_debug#*=}
10612         $LCTL set_param debug="reada mmap"
10613
10614         # create a test file
10615         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10616
10617         echo Cancel LRU locks on lustre client to flush the client cache
10618         cancel_lru_locks osc
10619
10620         echo Reset readahead stats
10621         $LCTL set_param -n llite.*.read_ahead_stats=0
10622
10623         echo mmap read the file with small block size
10624         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10625                 > /dev/null 2>&1
10626
10627         echo checking missing pages
10628         $LCTL get_param llite.*.read_ahead_stats
10629         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10630                         get_named_value 'misses' | calc_total)
10631
10632         $LCTL set_param debug="$old_debug"
10633         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10634         rm -f $DIR/$tfile
10635 }
10636 run_test 101f "check mmap read performance"
10637
10638 test_101g_brw_size_test() {
10639         local mb=$1
10640         local pages=$((mb * 1048576 / PAGE_SIZE))
10641         local file=$DIR/$tfile
10642
10643         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10644                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10645         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10646                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10647                         return 2
10648         done
10649
10650         stack_trap "rm -f $file" EXIT
10651         $LCTL set_param -n osc.*.rpc_stats=0
10652
10653         # 10 RPCs should be enough for the test
10654         local count=10
10655         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10656                 { error "dd write ${mb} MB blocks failed"; return 3; }
10657         cancel_lru_locks osc
10658         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10659                 { error "dd write ${mb} MB blocks failed"; return 4; }
10660
10661         # calculate number of full-sized read and write RPCs
10662         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10663                 sed -n '/pages per rpc/,/^$/p' |
10664                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10665                 END { print reads,writes }'))
10666         # allow one extra full-sized read RPC for async readahead
10667         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10668                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10669         [[ ${rpcs[1]} == $count ]] ||
10670                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10671 }
10672
10673 test_101g() {
10674         remote_ost_nodsh && skip "remote OST with nodsh"
10675
10676         local rpcs
10677         local osts=$(get_facets OST)
10678         local list=$(comma_list $(osts_nodes))
10679         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10680         local brw_size="obdfilter.*.brw_size"
10681
10682         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10683
10684         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10685
10686         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10687                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10688                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10689            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10690                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10691                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10692
10693                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10694                         suffix="M"
10695
10696                 if [[ $orig_mb -lt 16 ]]; then
10697                         save_lustre_params $osts "$brw_size" > $p
10698                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10699                                 error "set 16MB RPC size failed"
10700
10701                         echo "remount client to enable new RPC size"
10702                         remount_client $MOUNT || error "remount_client failed"
10703                 fi
10704
10705                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10706                 # should be able to set brw_size=12, but no rpc_stats for that
10707                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10708         fi
10709
10710         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10711
10712         if [[ $orig_mb -lt 16 ]]; then
10713                 restore_lustre_params < $p
10714                 remount_client $MOUNT || error "remount_client restore failed"
10715         fi
10716
10717         rm -f $p $DIR/$tfile
10718 }
10719 run_test 101g "Big bulk(4/16 MiB) readahead"
10720
10721 test_101h() {
10722         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10723
10724         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10725                 error "dd 70M file failed"
10726         echo Cancel LRU locks on lustre client to flush the client cache
10727         cancel_lru_locks osc
10728
10729         echo "Reset readahead stats"
10730         $LCTL set_param -n llite.*.read_ahead_stats 0
10731
10732         echo "Read 10M of data but cross 64M bundary"
10733         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10734         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10735                      get_named_value 'misses' | calc_total)
10736         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10737         rm -f $p $DIR/$tfile
10738 }
10739 run_test 101h "Readahead should cover current read window"
10740
10741 test_101i() {
10742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10743                 error "dd 10M file failed"
10744
10745         local max_per_file_mb=$($LCTL get_param -n \
10746                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10747         cancel_lru_locks osc
10748         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10749         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10750                 error "set max_read_ahead_per_file_mb to 1 failed"
10751
10752         echo "Reset readahead stats"
10753         $LCTL set_param llite.*.read_ahead_stats=0
10754
10755         dd if=$DIR/$tfile of=/dev/null bs=2M
10756
10757         $LCTL get_param llite.*.read_ahead_stats
10758         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10759                      awk '/misses/ { print $2 }')
10760         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10761         rm -f $DIR/$tfile
10762 }
10763 run_test 101i "allow current readahead to exceed reservation"
10764
10765 test_101j() {
10766         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10767                 error "setstripe $DIR/$tfile failed"
10768         local file_size=$((1048576 * 16))
10769         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10770         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10771
10772         echo Disable read-ahead
10773         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10774
10775         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10776         for blk in $PAGE_SIZE 1048576 $file_size; do
10777                 cancel_lru_locks osc
10778                 echo "Reset readahead stats"
10779                 $LCTL set_param -n llite.*.read_ahead_stats=0
10780                 local count=$(($file_size / $blk))
10781                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10782                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10783                              get_named_value 'failed.to.fast.read' | calc_total)
10784                 $LCTL get_param -n llite.*.read_ahead_stats
10785                 [ $miss -eq $count ] || error "expected $count got $miss"
10786         done
10787
10788         rm -f $p $DIR/$tfile
10789 }
10790 run_test 101j "A complete read block should be submitted when no RA"
10791
10792 setup_test102() {
10793         test_mkdir $DIR/$tdir
10794         chown $RUNAS_ID $DIR/$tdir
10795         STRIPE_SIZE=65536
10796         STRIPE_OFFSET=1
10797         STRIPE_COUNT=$OSTCOUNT
10798         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10799
10800         trap cleanup_test102 EXIT
10801         cd $DIR
10802         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10803         cd $DIR/$tdir
10804         for num in 1 2 3 4; do
10805                 for count in $(seq 1 $STRIPE_COUNT); do
10806                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10807                                 local size=`expr $STRIPE_SIZE \* $num`
10808                                 local file=file"$num-$idx-$count"
10809                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10810                         done
10811                 done
10812         done
10813
10814         cd $DIR
10815         $1 tar cf $TMP/f102.tar $tdir --xattrs
10816 }
10817
10818 cleanup_test102() {
10819         trap 0
10820         rm -f $TMP/f102.tar
10821         rm -rf $DIR/d0.sanity/d102
10822 }
10823
10824 test_102a() {
10825         [ "$UID" != 0 ] && skip "must run as root"
10826         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10827                 skip_env "must have user_xattr"
10828
10829         [ -z "$(which setfattr 2>/dev/null)" ] &&
10830                 skip_env "could not find setfattr"
10831
10832         local testfile=$DIR/$tfile
10833
10834         touch $testfile
10835         echo "set/get xattr..."
10836         setfattr -n trusted.name1 -v value1 $testfile ||
10837                 error "setfattr -n trusted.name1=value1 $testfile failed"
10838         getfattr -n trusted.name1 $testfile 2> /dev/null |
10839           grep "trusted.name1=.value1" ||
10840                 error "$testfile missing trusted.name1=value1"
10841
10842         setfattr -n user.author1 -v author1 $testfile ||
10843                 error "setfattr -n user.author1=author1 $testfile failed"
10844         getfattr -n user.author1 $testfile 2> /dev/null |
10845           grep "user.author1=.author1" ||
10846                 error "$testfile missing trusted.author1=author1"
10847
10848         echo "listxattr..."
10849         setfattr -n trusted.name2 -v value2 $testfile ||
10850                 error "$testfile unable to set trusted.name2"
10851         setfattr -n trusted.name3 -v value3 $testfile ||
10852                 error "$testfile unable to set trusted.name3"
10853         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10854             grep "trusted.name" | wc -l) -eq 3 ] ||
10855                 error "$testfile missing 3 trusted.name xattrs"
10856
10857         setfattr -n user.author2 -v author2 $testfile ||
10858                 error "$testfile unable to set user.author2"
10859         setfattr -n user.author3 -v author3 $testfile ||
10860                 error "$testfile unable to set user.author3"
10861         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10862             grep "user.author" | wc -l) -eq 3 ] ||
10863                 error "$testfile missing 3 user.author xattrs"
10864
10865         echo "remove xattr..."
10866         setfattr -x trusted.name1 $testfile ||
10867                 error "$testfile error deleting trusted.name1"
10868         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10869                 error "$testfile did not delete trusted.name1 xattr"
10870
10871         setfattr -x user.author1 $testfile ||
10872                 error "$testfile error deleting user.author1"
10873         echo "set lustre special xattr ..."
10874         $LFS setstripe -c1 $testfile
10875         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10876                 awk -F "=" '/trusted.lov/ { print $2 }' )
10877         setfattr -n "trusted.lov" -v $lovea $testfile ||
10878                 error "$testfile doesn't ignore setting trusted.lov again"
10879         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10880                 error "$testfile allow setting invalid trusted.lov"
10881         rm -f $testfile
10882 }
10883 run_test 102a "user xattr test =================================="
10884
10885 check_102b_layout() {
10886         local layout="$*"
10887         local testfile=$DIR/$tfile
10888
10889         echo "test layout '$layout'"
10890         $LFS setstripe $layout $testfile || error "setstripe failed"
10891         $LFS getstripe -y $testfile
10892
10893         echo "get/set/list trusted.lov xattr ..." # b=10930
10894         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10895         [[ "$value" =~ "trusted.lov" ]] ||
10896                 error "can't get trusted.lov from $testfile"
10897         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10898                 error "getstripe failed"
10899
10900         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10901
10902         value=$(cut -d= -f2 <<<$value)
10903         # LU-13168: truncated xattr should fail if short lov_user_md header
10904         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10905                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10906         for len in $lens; do
10907                 echo "setfattr $len $testfile.2"
10908                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10909                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10910         done
10911         local stripe_size=$($LFS getstripe -S $testfile.2)
10912         local stripe_count=$($LFS getstripe -c $testfile.2)
10913         [[ $stripe_size -eq 65536 ]] ||
10914                 error "stripe size $stripe_size != 65536"
10915         [[ $stripe_count -eq $stripe_count_orig ]] ||
10916                 error "stripe count $stripe_count != $stripe_count_orig"
10917         rm $testfile $testfile.2
10918 }
10919
10920 test_102b() {
10921         [ -z "$(which setfattr 2>/dev/null)" ] &&
10922                 skip_env "could not find setfattr"
10923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10924
10925         # check plain layout
10926         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10927
10928         # and also check composite layout
10929         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10930
10931 }
10932 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10933
10934 test_102c() {
10935         [ -z "$(which setfattr 2>/dev/null)" ] &&
10936                 skip_env "could not find setfattr"
10937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10938
10939         # b10930: get/set/list lustre.lov xattr
10940         echo "get/set/list lustre.lov xattr ..."
10941         test_mkdir $DIR/$tdir
10942         chown $RUNAS_ID $DIR/$tdir
10943         local testfile=$DIR/$tdir/$tfile
10944         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10945                 error "setstripe failed"
10946         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10947                 error "getstripe failed"
10948         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10949         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10950
10951         local testfile2=${testfile}2
10952         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10953                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10954
10955         $RUNAS $MCREATE $testfile2
10956         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10957         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10958         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10959         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10960         [ $stripe_count -eq $STRIPECOUNT ] ||
10961                 error "stripe count $stripe_count != $STRIPECOUNT"
10962 }
10963 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10964
10965 compare_stripe_info1() {
10966         local stripe_index_all_zero=true
10967
10968         for num in 1 2 3 4; do
10969                 for count in $(seq 1 $STRIPE_COUNT); do
10970                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10971                                 local size=$((STRIPE_SIZE * num))
10972                                 local file=file"$num-$offset-$count"
10973                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10974                                 [[ $stripe_size -ne $size ]] &&
10975                                     error "$file: size $stripe_size != $size"
10976                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10977                                 # allow fewer stripes to be created, ORI-601
10978                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10979                                     error "$file: count $stripe_count != $count"
10980                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10981                                 [[ $stripe_index -ne 0 ]] &&
10982                                         stripe_index_all_zero=false
10983                         done
10984                 done
10985         done
10986         $stripe_index_all_zero &&
10987                 error "all files are being extracted starting from OST index 0"
10988         return 0
10989 }
10990
10991 have_xattrs_include() {
10992         tar --help | grep -q xattrs-include &&
10993                 echo --xattrs-include="lustre.*"
10994 }
10995
10996 test_102d() {
10997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10998         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10999
11000         XINC=$(have_xattrs_include)
11001         setup_test102
11002         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11003         cd $DIR/$tdir/$tdir
11004         compare_stripe_info1
11005 }
11006 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11007
11008 test_102f() {
11009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11011
11012         XINC=$(have_xattrs_include)
11013         setup_test102
11014         test_mkdir $DIR/$tdir.restore
11015         cd $DIR
11016         tar cf - --xattrs $tdir | tar xf - \
11017                 -C $DIR/$tdir.restore --xattrs $XINC
11018         cd $DIR/$tdir.restore/$tdir
11019         compare_stripe_info1
11020 }
11021 run_test 102f "tar copy files, not keep osts"
11022
11023 grow_xattr() {
11024         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11025                 skip "must have user_xattr"
11026         [ -z "$(which setfattr 2>/dev/null)" ] &&
11027                 skip_env "could not find setfattr"
11028         [ -z "$(which getfattr 2>/dev/null)" ] &&
11029                 skip_env "could not find getfattr"
11030
11031         local xsize=${1:-1024}  # in bytes
11032         local file=$DIR/$tfile
11033         local value="$(generate_string $xsize)"
11034         local xbig=trusted.big
11035         local toobig=$2
11036
11037         touch $file
11038         log "save $xbig on $file"
11039         if [ -z "$toobig" ]
11040         then
11041                 setfattr -n $xbig -v $value $file ||
11042                         error "saving $xbig on $file failed"
11043         else
11044                 setfattr -n $xbig -v $value $file &&
11045                         error "saving $xbig on $file succeeded"
11046                 return 0
11047         fi
11048
11049         local orig=$(get_xattr_value $xbig $file)
11050         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11051
11052         local xsml=trusted.sml
11053         log "save $xsml on $file"
11054         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11055
11056         local new=$(get_xattr_value $xbig $file)
11057         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11058
11059         log "grow $xsml on $file"
11060         setfattr -n $xsml -v "$value" $file ||
11061                 error "growing $xsml on $file failed"
11062
11063         new=$(get_xattr_value $xbig $file)
11064         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11065         log "$xbig still valid after growing $xsml"
11066
11067         rm -f $file
11068 }
11069
11070 test_102h() { # bug 15777
11071         grow_xattr 1024
11072 }
11073 run_test 102h "grow xattr from inside inode to external block"
11074
11075 test_102ha() {
11076         large_xattr_enabled || skip_env "ea_inode feature disabled"
11077
11078         echo "setting xattr of max xattr size: $(max_xattr_size)"
11079         grow_xattr $(max_xattr_size)
11080
11081         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11082         echo "This should fail:"
11083         grow_xattr $(($(max_xattr_size) + 10)) 1
11084 }
11085 run_test 102ha "grow xattr from inside inode to external inode"
11086
11087 test_102i() { # bug 17038
11088         [ -z "$(which getfattr 2>/dev/null)" ] &&
11089                 skip "could not find getfattr"
11090
11091         touch $DIR/$tfile
11092         ln -s $DIR/$tfile $DIR/${tfile}link
11093         getfattr -n trusted.lov $DIR/$tfile ||
11094                 error "lgetxattr on $DIR/$tfile failed"
11095         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11096                 grep -i "no such attr" ||
11097                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11098         rm -f $DIR/$tfile $DIR/${tfile}link
11099 }
11100 run_test 102i "lgetxattr test on symbolic link ============"
11101
11102 test_102j() {
11103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11104         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11105
11106         XINC=$(have_xattrs_include)
11107         setup_test102 "$RUNAS"
11108         chown $RUNAS_ID $DIR/$tdir
11109         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11110         cd $DIR/$tdir/$tdir
11111         compare_stripe_info1 "$RUNAS"
11112 }
11113 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11114
11115 test_102k() {
11116         [ -z "$(which setfattr 2>/dev/null)" ] &&
11117                 skip "could not find setfattr"
11118
11119         touch $DIR/$tfile
11120         # b22187 just check that does not crash for regular file.
11121         setfattr -n trusted.lov $DIR/$tfile
11122         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11123         local test_kdir=$DIR/$tdir
11124         test_mkdir $test_kdir
11125         local default_size=$($LFS getstripe -S $test_kdir)
11126         local default_count=$($LFS getstripe -c $test_kdir)
11127         local default_offset=$($LFS getstripe -i $test_kdir)
11128         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11129                 error 'dir setstripe failed'
11130         setfattr -n trusted.lov $test_kdir
11131         local stripe_size=$($LFS getstripe -S $test_kdir)
11132         local stripe_count=$($LFS getstripe -c $test_kdir)
11133         local stripe_offset=$($LFS getstripe -i $test_kdir)
11134         [ $stripe_size -eq $default_size ] ||
11135                 error "stripe size $stripe_size != $default_size"
11136         [ $stripe_count -eq $default_count ] ||
11137                 error "stripe count $stripe_count != $default_count"
11138         [ $stripe_offset -eq $default_offset ] ||
11139                 error "stripe offset $stripe_offset != $default_offset"
11140         rm -rf $DIR/$tfile $test_kdir
11141 }
11142 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11143
11144 test_102l() {
11145         [ -z "$(which getfattr 2>/dev/null)" ] &&
11146                 skip "could not find getfattr"
11147
11148         # LU-532 trusted. xattr is invisible to non-root
11149         local testfile=$DIR/$tfile
11150
11151         touch $testfile
11152
11153         echo "listxattr as user..."
11154         chown $RUNAS_ID $testfile
11155         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11156             grep -q "trusted" &&
11157                 error "$testfile trusted xattrs are user visible"
11158
11159         return 0;
11160 }
11161 run_test 102l "listxattr size test =================================="
11162
11163 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11164         local path=$DIR/$tfile
11165         touch $path
11166
11167         listxattr_size_check $path || error "listattr_size_check $path failed"
11168 }
11169 run_test 102m "Ensure listxattr fails on small bufffer ========"
11170
11171 cleanup_test102
11172
11173 getxattr() { # getxattr path name
11174         # Return the base64 encoding of the value of xattr name on path.
11175         local path=$1
11176         local name=$2
11177
11178         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11179         # file: $path
11180         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11181         #
11182         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11183
11184         getfattr --absolute-names --encoding=base64 --name=$name $path |
11185                 awk -F= -v name=$name '$1 == name {
11186                         print substr($0, index($0, "=") + 1);
11187         }'
11188 }
11189
11190 test_102n() { # LU-4101 mdt: protect internal xattrs
11191         [ -z "$(which setfattr 2>/dev/null)" ] &&
11192                 skip "could not find setfattr"
11193         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11194         then
11195                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11196         fi
11197
11198         local file0=$DIR/$tfile.0
11199         local file1=$DIR/$tfile.1
11200         local xattr0=$TMP/$tfile.0
11201         local xattr1=$TMP/$tfile.1
11202         local namelist="lov lma lmv link fid version som hsm"
11203         local name
11204         local value
11205
11206         rm -rf $file0 $file1 $xattr0 $xattr1
11207         touch $file0 $file1
11208
11209         # Get 'before' xattrs of $file1.
11210         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11211
11212         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11213                 namelist+=" lfsck_namespace"
11214         for name in $namelist; do
11215                 # Try to copy xattr from $file0 to $file1.
11216                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11217
11218                 setfattr --name=trusted.$name --value="$value" $file1 ||
11219                         error "setxattr 'trusted.$name' failed"
11220
11221                 # Try to set a garbage xattr.
11222                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11223
11224                 if [[ x$name == "xlov" ]]; then
11225                         setfattr --name=trusted.lov --value="$value" $file1 &&
11226                         error "setxattr invalid 'trusted.lov' success"
11227                 else
11228                         setfattr --name=trusted.$name --value="$value" $file1 ||
11229                                 error "setxattr invalid 'trusted.$name' failed"
11230                 fi
11231
11232                 # Try to remove the xattr from $file1. We don't care if this
11233                 # appears to succeed or fail, we just don't want there to be
11234                 # any changes or crashes.
11235                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11236         done
11237
11238         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11239         then
11240                 name="lfsck_ns"
11241                 # Try to copy xattr from $file0 to $file1.
11242                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11243
11244                 setfattr --name=trusted.$name --value="$value" $file1 ||
11245                         error "setxattr 'trusted.$name' failed"
11246
11247                 # Try to set a garbage xattr.
11248                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11249
11250                 setfattr --name=trusted.$name --value="$value" $file1 ||
11251                         error "setxattr 'trusted.$name' failed"
11252
11253                 # Try to remove the xattr from $file1. We don't care if this
11254                 # appears to succeed or fail, we just don't want there to be
11255                 # any changes or crashes.
11256                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11257         fi
11258
11259         # Get 'after' xattrs of file1.
11260         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11261
11262         if ! diff $xattr0 $xattr1; then
11263                 error "before and after xattrs of '$file1' differ"
11264         fi
11265
11266         rm -rf $file0 $file1 $xattr0 $xattr1
11267
11268         return 0
11269 }
11270 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11271
11272 test_102p() { # LU-4703 setxattr did not check ownership
11273         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11274                 skip "MDS needs to be at least 2.5.56"
11275
11276         local testfile=$DIR/$tfile
11277
11278         touch $testfile
11279
11280         echo "setfacl as user..."
11281         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11282         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11283
11284         echo "setfattr as user..."
11285         setfacl -m "u:$RUNAS_ID:---" $testfile
11286         $RUNAS setfattr -x system.posix_acl_access $testfile
11287         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11288 }
11289 run_test 102p "check setxattr(2) correctly fails without permission"
11290
11291 test_102q() {
11292         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11293                 skip "MDS needs to be at least 2.6.92"
11294
11295         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11296 }
11297 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11298
11299 test_102r() {
11300         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11301                 skip "MDS needs to be at least 2.6.93"
11302
11303         touch $DIR/$tfile || error "touch"
11304         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11305         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11306         rm $DIR/$tfile || error "rm"
11307
11308         #normal directory
11309         mkdir -p $DIR/$tdir || error "mkdir"
11310         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11311         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11312         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11313                 error "$testfile error deleting user.author1"
11314         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11315                 grep "user.$(basename $tdir)" &&
11316                 error "$tdir did not delete user.$(basename $tdir)"
11317         rmdir $DIR/$tdir || error "rmdir"
11318
11319         #striped directory
11320         test_mkdir $DIR/$tdir
11321         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11322         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11323         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11324                 error "$testfile error deleting user.author1"
11325         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11326                 grep "user.$(basename $tdir)" &&
11327                 error "$tdir did not delete user.$(basename $tdir)"
11328         rmdir $DIR/$tdir || error "rm striped dir"
11329 }
11330 run_test 102r "set EAs with empty values"
11331
11332 test_102s() {
11333         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11334                 skip "MDS needs to be at least 2.11.52"
11335
11336         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11337
11338         save_lustre_params client "llite.*.xattr_cache" > $save
11339
11340         for cache in 0 1; do
11341                 lctl set_param llite.*.xattr_cache=$cache
11342
11343                 rm -f $DIR/$tfile
11344                 touch $DIR/$tfile || error "touch"
11345                 for prefix in lustre security system trusted user; do
11346                         # Note getxattr() may fail with 'Operation not
11347                         # supported' or 'No such attribute' depending
11348                         # on prefix and cache.
11349                         getfattr -n $prefix.n102s $DIR/$tfile &&
11350                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11351                 done
11352         done
11353
11354         restore_lustre_params < $save
11355 }
11356 run_test 102s "getting nonexistent xattrs should fail"
11357
11358 test_102t() {
11359         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11360                 skip "MDS needs to be at least 2.11.52"
11361
11362         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11363
11364         save_lustre_params client "llite.*.xattr_cache" > $save
11365
11366         for cache in 0 1; do
11367                 lctl set_param llite.*.xattr_cache=$cache
11368
11369                 for buf_size in 0 256; do
11370                         rm -f $DIR/$tfile
11371                         touch $DIR/$tfile || error "touch"
11372                         setfattr -n user.multiop $DIR/$tfile
11373                         $MULTIOP $DIR/$tfile oa$buf_size ||
11374                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11375                 done
11376         done
11377
11378         restore_lustre_params < $save
11379 }
11380 run_test 102t "zero length xattr values handled correctly"
11381
11382 run_acl_subtest()
11383 {
11384     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11385     return $?
11386 }
11387
11388 test_103a() {
11389         [ "$UID" != 0 ] && skip "must run as root"
11390         $GSS && skip_env "could not run under gss"
11391         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11392                 skip_env "must have acl enabled"
11393         [ -z "$(which setfacl 2>/dev/null)" ] &&
11394                 skip_env "could not find setfacl"
11395         remote_mds_nodsh && skip "remote MDS with nodsh"
11396
11397         gpasswd -a daemon bin                           # LU-5641
11398         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11399
11400         declare -a identity_old
11401
11402         for num in $(seq $MDSCOUNT); do
11403                 switch_identity $num true || identity_old[$num]=$?
11404         done
11405
11406         SAVE_UMASK=$(umask)
11407         umask 0022
11408         mkdir -p $DIR/$tdir
11409         cd $DIR/$tdir
11410
11411         echo "performing cp ..."
11412         run_acl_subtest cp || error "run_acl_subtest cp failed"
11413         echo "performing getfacl-noacl..."
11414         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11415         echo "performing misc..."
11416         run_acl_subtest misc || error  "misc test failed"
11417         echo "performing permissions..."
11418         run_acl_subtest permissions || error "permissions failed"
11419         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11420         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11421                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11422                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11423         then
11424                 echo "performing permissions xattr..."
11425                 run_acl_subtest permissions_xattr ||
11426                         error "permissions_xattr failed"
11427         fi
11428         echo "performing setfacl..."
11429         run_acl_subtest setfacl || error  "setfacl test failed"
11430
11431         # inheritance test got from HP
11432         echo "performing inheritance..."
11433         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11434         chmod +x make-tree || error "chmod +x failed"
11435         run_acl_subtest inheritance || error "inheritance test failed"
11436         rm -f make-tree
11437
11438         echo "LU-974 ignore umask when acl is enabled..."
11439         run_acl_subtest 974 || error "LU-974 umask test failed"
11440         if [ $MDSCOUNT -ge 2 ]; then
11441                 run_acl_subtest 974_remote ||
11442                         error "LU-974 umask test failed under remote dir"
11443         fi
11444
11445         echo "LU-2561 newly created file is same size as directory..."
11446         if [ "$mds1_FSTYPE" != "zfs" ]; then
11447                 run_acl_subtest 2561 || error "LU-2561 test failed"
11448         else
11449                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11450         fi
11451
11452         run_acl_subtest 4924 || error "LU-4924 test failed"
11453
11454         cd $SAVE_PWD
11455         umask $SAVE_UMASK
11456
11457         for num in $(seq $MDSCOUNT); do
11458                 if [ "${identity_old[$num]}" = 1 ]; then
11459                         switch_identity $num false || identity_old[$num]=$?
11460                 fi
11461         done
11462 }
11463 run_test 103a "acl test"
11464
11465 test_103b() {
11466         declare -a pids
11467         local U
11468
11469         for U in {0..511}; do
11470                 {
11471                 local O=$(printf "%04o" $U)
11472
11473                 umask $(printf "%04o" $((511 ^ $O)))
11474                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11475                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11476
11477                 (( $S == ($O & 0666) )) ||
11478                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11479
11480                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11481                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11482                 (( $S == ($O & 0666) )) ||
11483                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11484
11485                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11486                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11487                 (( $S == ($O & 0666) )) ||
11488                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11489                 rm -f $DIR/$tfile.[smp]$0
11490                 } &
11491                 local pid=$!
11492
11493                 # limit the concurrently running threads to 64. LU-11878
11494                 local idx=$((U % 64))
11495                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11496                 pids[idx]=$pid
11497         done
11498         wait
11499 }
11500 run_test 103b "umask lfs setstripe"
11501
11502 test_103c() {
11503         mkdir -p $DIR/$tdir
11504         cp -rp $DIR/$tdir $DIR/$tdir.bak
11505
11506         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11507                 error "$DIR/$tdir shouldn't contain default ACL"
11508         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11509                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11510         true
11511 }
11512 run_test 103c "'cp -rp' won't set empty acl"
11513
11514 test_103e() {
11515         local numacl
11516         local fileacl
11517         local saved_debug=$($LCTL get_param -n debug)
11518
11519         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11520                 skip "MDS needs to be at least 2.14.52"
11521
11522         large_xattr_enabled || skip_env "ea_inode feature disabled"
11523
11524         mkdir -p $DIR/$tdir
11525         # add big LOV EA to cause reply buffer overflow earlier
11526         $LFS setstripe -C 1000 $DIR/$tdir
11527         lctl set_param mdc.*-mdc*.stats=clear
11528
11529         $LCTL set_param debug=0
11530         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11531         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11532
11533         # add a large number of default ACLs (expect 8000+ for 2.13+)
11534         for U in {2..7000}; do
11535                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11536                         error "Able to add just $U default ACLs"
11537         done
11538         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11539         echo "$numacl default ACLs created"
11540
11541         stat $DIR/$tdir || error "Cannot stat directory"
11542         # check file creation
11543         touch $DIR/$tdir/$tfile ||
11544                 error "failed to create $tfile with $numacl default ACLs"
11545         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11546         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11547         echo "$fileacl ACLs were inherited"
11548         (( $fileacl == $numacl )) ||
11549                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11550         # check that new ACLs creation adds new ACLs to inherited ACLs
11551         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11552                 error "Cannot set new ACL"
11553         numacl=$((numacl + 1))
11554         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11555         (( $fileacl == $numacl )) ||
11556                 error "failed to add new ACL: $fileacl != $numacl as expected"
11557         # adds more ACLs to a file to reach their maximum at 8000+
11558         numacl=0
11559         for U in {20000..25000}; do
11560                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11561                 numacl=$((numacl + 1))
11562         done
11563         echo "Added $numacl more ACLs to the file"
11564         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11565         echo "Total $fileacl ACLs in file"
11566         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11567         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11568         rmdir $DIR/$tdir || error "Cannot remove directory"
11569 }
11570 run_test 103e "inheritance of big amount of default ACLs"
11571
11572 test_103f() {
11573         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11574                 skip "MDS needs to be at least 2.14.51"
11575
11576         large_xattr_enabled || skip_env "ea_inode feature disabled"
11577
11578         # enable changelog to consume more internal MDD buffers
11579         changelog_register
11580
11581         mkdir -p $DIR/$tdir
11582         # add big LOV EA
11583         $LFS setstripe -C 1000 $DIR/$tdir
11584         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11585         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11586         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11587         rmdir $DIR/$tdir || error "Cannot remove directory"
11588 }
11589 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11590
11591 test_104a() {
11592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11593
11594         touch $DIR/$tfile
11595         lfs df || error "lfs df failed"
11596         lfs df -ih || error "lfs df -ih failed"
11597         lfs df -h $DIR || error "lfs df -h $DIR failed"
11598         lfs df -i $DIR || error "lfs df -i $DIR failed"
11599         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11600         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11601
11602         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11603         lctl --device %$OSC deactivate
11604         lfs df || error "lfs df with deactivated OSC failed"
11605         lctl --device %$OSC activate
11606         # wait the osc back to normal
11607         wait_osc_import_ready client ost
11608
11609         lfs df || error "lfs df with reactivated OSC failed"
11610         rm -f $DIR/$tfile
11611 }
11612 run_test 104a "lfs df [-ih] [path] test ========================="
11613
11614 test_104b() {
11615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11616         [ $RUNAS_ID -eq $UID ] &&
11617                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11618
11619         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11620                         grep "Permission denied" | wc -l)))
11621         if [ $denied_cnt -ne 0 ]; then
11622                 error "lfs check servers test failed"
11623         fi
11624 }
11625 run_test 104b "$RUNAS lfs check servers test ===================="
11626
11627 #
11628 # Verify $1 is within range of $2.
11629 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11630 # $1 is <= 2% of $2. Else Fail.
11631 #
11632 value_in_range() {
11633         # Strip all units (M, G, T)
11634         actual=$(echo $1 | tr -d A-Z)
11635         expect=$(echo $2 | tr -d A-Z)
11636
11637         expect_lo=$(($expect * 98 / 100)) # 2% below
11638         expect_hi=$(($expect * 102 / 100)) # 2% above
11639
11640         # permit 2% drift above and below
11641         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11642 }
11643
11644 test_104c() {
11645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11646         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11647
11648         local ost_param="osd-zfs.$FSNAME-OST0000."
11649         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11650         local ofacets=$(get_facets OST)
11651         local mfacets=$(get_facets MDS)
11652         local saved_ost_blocks=
11653         local saved_mdt_blocks=
11654
11655         echo "Before recordsize change"
11656         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11657         df=($(df -h | grep "$MOUNT"$))
11658
11659         # For checking.
11660         echo "lfs output : ${lfs_df[*]}"
11661         echo "df  output : ${df[*]}"
11662
11663         for facet in ${ofacets//,/ }; do
11664                 if [ -z $saved_ost_blocks ]; then
11665                         saved_ost_blocks=$(do_facet $facet \
11666                                 lctl get_param -n $ost_param.blocksize)
11667                         echo "OST Blocksize: $saved_ost_blocks"
11668                 fi
11669                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11670                 do_facet $facet zfs set recordsize=32768 $ost
11671         done
11672
11673         # BS too small. Sufficient for functional testing.
11674         for facet in ${mfacets//,/ }; do
11675                 if [ -z $saved_mdt_blocks ]; then
11676                         saved_mdt_blocks=$(do_facet $facet \
11677                                 lctl get_param -n $mdt_param.blocksize)
11678                         echo "MDT Blocksize: $saved_mdt_blocks"
11679                 fi
11680                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11681                 do_facet $facet zfs set recordsize=32768 $mdt
11682         done
11683
11684         # Give new values chance to reflect change
11685         sleep 2
11686
11687         echo "After recordsize change"
11688         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11689         df_after=($(df -h | grep "$MOUNT"$))
11690
11691         # For checking.
11692         echo "lfs output : ${lfs_df_after[*]}"
11693         echo "df  output : ${df_after[*]}"
11694
11695         # Verify lfs df
11696         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11697                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11698         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11699                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11700         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11701                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11702
11703         # Verify df
11704         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11705                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11706         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11707                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11708         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11709                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11710
11711         # Restore MDT recordize back to original
11712         for facet in ${mfacets//,/ }; do
11713                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11714                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11715         done
11716
11717         # Restore OST recordize back to original
11718         for facet in ${ofacets//,/ }; do
11719                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11720                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11721         done
11722
11723         return 0
11724 }
11725 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11726
11727 test_105a() {
11728         # doesn't work on 2.4 kernels
11729         touch $DIR/$tfile
11730         if $(flock_is_enabled); then
11731                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11732         else
11733                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11734         fi
11735         rm -f $DIR/$tfile
11736 }
11737 run_test 105a "flock when mounted without -o flock test ========"
11738
11739 test_105b() {
11740         touch $DIR/$tfile
11741         if $(flock_is_enabled); then
11742                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11743         else
11744                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11745         fi
11746         rm -f $DIR/$tfile
11747 }
11748 run_test 105b "fcntl when mounted without -o flock test ========"
11749
11750 test_105c() {
11751         touch $DIR/$tfile
11752         if $(flock_is_enabled); then
11753                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11754         else
11755                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11756         fi
11757         rm -f $DIR/$tfile
11758 }
11759 run_test 105c "lockf when mounted without -o flock test"
11760
11761 test_105d() { # bug 15924
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763
11764         test_mkdir $DIR/$tdir
11765         flock_is_enabled || skip_env "mount w/o flock enabled"
11766         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11767         $LCTL set_param fail_loc=0x80000315
11768         flocks_test 2 $DIR/$tdir
11769 }
11770 run_test 105d "flock race (should not freeze) ========"
11771
11772 test_105e() { # bug 22660 && 22040
11773         flock_is_enabled || skip_env "mount w/o flock enabled"
11774
11775         touch $DIR/$tfile
11776         flocks_test 3 $DIR/$tfile
11777 }
11778 run_test 105e "Two conflicting flocks from same process"
11779
11780 test_106() { #bug 10921
11781         test_mkdir $DIR/$tdir
11782         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11783         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11784 }
11785 run_test 106 "attempt exec of dir followed by chown of that dir"
11786
11787 test_107() {
11788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11789
11790         CDIR=`pwd`
11791         local file=core
11792
11793         cd $DIR
11794         rm -f $file
11795
11796         local save_pattern=$(sysctl -n kernel.core_pattern)
11797         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11798         sysctl -w kernel.core_pattern=$file
11799         sysctl -w kernel.core_uses_pid=0
11800
11801         ulimit -c unlimited
11802         sleep 60 &
11803         SLEEPPID=$!
11804
11805         sleep 1
11806
11807         kill -s 11 $SLEEPPID
11808         wait $SLEEPPID
11809         if [ -e $file ]; then
11810                 size=`stat -c%s $file`
11811                 [ $size -eq 0 ] && error "Fail to create core file $file"
11812         else
11813                 error "Fail to create core file $file"
11814         fi
11815         rm -f $file
11816         sysctl -w kernel.core_pattern=$save_pattern
11817         sysctl -w kernel.core_uses_pid=$save_uses_pid
11818         cd $CDIR
11819 }
11820 run_test 107 "Coredump on SIG"
11821
11822 test_110() {
11823         test_mkdir $DIR/$tdir
11824         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11825         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11826                 error "mkdir with 256 char should fail, but did not"
11827         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11828                 error "create with 255 char failed"
11829         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11830                 error "create with 256 char should fail, but did not"
11831
11832         ls -l $DIR/$tdir
11833         rm -rf $DIR/$tdir
11834 }
11835 run_test 110 "filename length checking"
11836
11837 #
11838 # Purpose: To verify dynamic thread (OSS) creation.
11839 #
11840 test_115() {
11841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11842         remote_ost_nodsh && skip "remote OST with nodsh"
11843
11844         # Lustre does not stop service threads once they are started.
11845         # Reset number of running threads to default.
11846         stopall
11847         setupall
11848
11849         local OSTIO_pre
11850         local save_params="$TMP/sanity-$TESTNAME.parameters"
11851
11852         # Get ll_ost_io count before I/O
11853         OSTIO_pre=$(do_facet ost1 \
11854                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11855         # Exit if lustre is not running (ll_ost_io not running).
11856         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11857
11858         echo "Starting with $OSTIO_pre threads"
11859         local thread_max=$((OSTIO_pre * 2))
11860         local rpc_in_flight=$((thread_max * 2))
11861         # this is limited to OSC_MAX_RIF_MAX (256)
11862         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11863         thread_max=$((rpc_in_flight / 2))
11864         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11865                 return
11866
11867         # Number of I/O Process proposed to be started.
11868         local nfiles
11869         local facets=$(get_facets OST)
11870
11871         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11872         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11873
11874         # Set in_flight to $rpc_in_flight
11875         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11876                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11877         nfiles=${rpc_in_flight}
11878         # Set ost thread_max to $thread_max
11879         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11880
11881         # 5 Minutes should be sufficient for max number of OSS
11882         # threads(thread_max) to be created.
11883         local timeout=300
11884
11885         # Start I/O.
11886         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11887         test_mkdir $DIR/$tdir
11888         for i in $(seq $nfiles); do
11889                 local file=$DIR/$tdir/${tfile}-$i
11890                 $LFS setstripe -c -1 -i 0 $file
11891                 ($WTL $file $timeout)&
11892         done
11893
11894         # I/O Started - Wait for thread_started to reach thread_max or report
11895         # error if thread_started is more than thread_max.
11896         echo "Waiting for thread_started to reach thread_max"
11897         local thread_started=0
11898         local end_time=$((SECONDS + timeout))
11899
11900         while [ $SECONDS -le $end_time ] ; do
11901                 echo -n "."
11902                 # Get ost i/o thread_started count.
11903                 thread_started=$(do_facet ost1 \
11904                         "$LCTL get_param \
11905                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11906                 # Break out if thread_started is equal/greater than thread_max
11907                 if [[ $thread_started -ge $thread_max ]]; then
11908                         echo ll_ost_io thread_started $thread_started, \
11909                                 equal/greater than thread_max $thread_max
11910                         break
11911                 fi
11912                 sleep 1
11913         done
11914
11915         # Cleanup - We have the numbers, Kill i/o jobs if running.
11916         jobcount=($(jobs -p))
11917         for i in $(seq 0 $((${#jobcount[@]}-1)))
11918         do
11919                 kill -9 ${jobcount[$i]}
11920                 if [ $? -ne 0 ] ; then
11921                         echo Warning: \
11922                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11923                 fi
11924         done
11925
11926         # Cleanup files left by WTL binary.
11927         for i in $(seq $nfiles); do
11928                 local file=$DIR/$tdir/${tfile}-$i
11929                 rm -rf $file
11930                 if [ $? -ne 0 ] ; then
11931                         echo "Warning: Failed to delete file $file"
11932                 fi
11933         done
11934
11935         restore_lustre_params <$save_params
11936         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11937
11938         # Error out if no new thread has started or Thread started is greater
11939         # than thread max.
11940         if [[ $thread_started -le $OSTIO_pre ||
11941                         $thread_started -gt $thread_max ]]; then
11942                 error "ll_ost_io: thread_started $thread_started" \
11943                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11944                       "No new thread started or thread started greater " \
11945                       "than thread_max."
11946         fi
11947 }
11948 run_test 115 "verify dynamic thread creation===================="
11949
11950 test_116a() { # was previously test_116()
11951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11953         remote_mds_nodsh && skip "remote MDS with nodsh"
11954
11955         echo -n "Free space priority "
11956         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11957                 head -n1
11958         declare -a AVAIL
11959         free_min_max
11960
11961         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11962         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11963         stack_trap simple_cleanup_common
11964
11965         # Check if we need to generate uneven OSTs
11966         test_mkdir -p $DIR/$tdir/OST${MINI}
11967         local FILL=$((MINV / 4))
11968         local DIFF=$((MAXV - MINV))
11969         local DIFF2=$((DIFF * 100 / MINV))
11970
11971         local threshold=$(do_facet $SINGLEMDS \
11972                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11973         threshold=${threshold%%%}
11974         echo -n "Check for uneven OSTs: "
11975         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11976
11977         if [[ $DIFF2 -gt $threshold ]]; then
11978                 echo "ok"
11979                 echo "Don't need to fill OST$MINI"
11980         else
11981                 # generate uneven OSTs. Write 2% over the QOS threshold value
11982                 echo "no"
11983                 DIFF=$((threshold - DIFF2 + 2))
11984                 DIFF2=$((MINV * DIFF / 100))
11985                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11986                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11987                         error "setstripe failed"
11988                 DIFF=$((DIFF2 / 2048))
11989                 i=0
11990                 while [ $i -lt $DIFF ]; do
11991                         i=$((i + 1))
11992                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11993                                 bs=2M count=1 2>/dev/null
11994                         echo -n .
11995                 done
11996                 echo .
11997                 sync
11998                 sleep_maxage
11999                 free_min_max
12000         fi
12001
12002         DIFF=$((MAXV - MINV))
12003         DIFF2=$((DIFF * 100 / MINV))
12004         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12005         if [ $DIFF2 -gt $threshold ]; then
12006                 echo "ok"
12007         else
12008                 skip "QOS imbalance criteria not met"
12009         fi
12010
12011         MINI1=$MINI
12012         MINV1=$MINV
12013         MAXI1=$MAXI
12014         MAXV1=$MAXV
12015
12016         # now fill using QOS
12017         $LFS setstripe -c 1 $DIR/$tdir
12018         FILL=$((FILL / 200))
12019         if [ $FILL -gt 600 ]; then
12020                 FILL=600
12021         fi
12022         echo "writing $FILL files to QOS-assigned OSTs"
12023         i=0
12024         while [ $i -lt $FILL ]; do
12025                 i=$((i + 1))
12026                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12027                         count=1 2>/dev/null
12028                 echo -n .
12029         done
12030         echo "wrote $i 200k files"
12031         sync
12032         sleep_maxage
12033
12034         echo "Note: free space may not be updated, so measurements might be off"
12035         free_min_max
12036         DIFF2=$((MAXV - MINV))
12037         echo "free space delta: orig $DIFF final $DIFF2"
12038         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12039         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12040         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12041         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12042         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12043         if [[ $DIFF -gt 0 ]]; then
12044                 FILL=$((DIFF2 * 100 / DIFF - 100))
12045                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12046         fi
12047
12048         # Figure out which files were written where
12049         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12050                awk '/'$MINI1': / {print $2; exit}')
12051         echo $UUID
12052         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12053         echo "$MINC files created on smaller OST $MINI1"
12054         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12055                awk '/'$MAXI1': / {print $2; exit}')
12056         echo $UUID
12057         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12058         echo "$MAXC files created on larger OST $MAXI1"
12059         if [[ $MINC -gt 0 ]]; then
12060                 FILL=$((MAXC * 100 / MINC - 100))
12061                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12062         fi
12063         [[ $MAXC -gt $MINC ]] ||
12064                 error_ignore LU-9 "stripe QOS didn't balance free space"
12065 }
12066 run_test 116a "stripe QOS: free space balance ==================="
12067
12068 test_116b() { # LU-2093
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070         remote_mds_nodsh && skip "remote MDS with nodsh"
12071
12072 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12073         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12074                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12075         [ -z "$old_rr" ] && skip "no QOS"
12076         do_facet $SINGLEMDS lctl set_param \
12077                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12078         mkdir -p $DIR/$tdir
12079         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12080         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12081         do_facet $SINGLEMDS lctl set_param fail_loc=0
12082         rm -rf $DIR/$tdir
12083         do_facet $SINGLEMDS lctl set_param \
12084                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12085 }
12086 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12087
12088 test_117() # bug 10891
12089 {
12090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12091
12092         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12093         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12094         lctl set_param fail_loc=0x21e
12095         > $DIR/$tfile || error "truncate failed"
12096         lctl set_param fail_loc=0
12097         echo "Truncate succeeded."
12098         rm -f $DIR/$tfile
12099 }
12100 run_test 117 "verify osd extend =========="
12101
12102 NO_SLOW_RESENDCOUNT=4
12103 export OLD_RESENDCOUNT=""
12104 set_resend_count () {
12105         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12106         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12107         lctl set_param -n $PROC_RESENDCOUNT $1
12108         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12109 }
12110
12111 # for reduce test_118* time (b=14842)
12112 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12113
12114 # Reset async IO behavior after error case
12115 reset_async() {
12116         FILE=$DIR/reset_async
12117
12118         # Ensure all OSCs are cleared
12119         $LFS setstripe -c -1 $FILE
12120         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12121         sync
12122         rm $FILE
12123 }
12124
12125 test_118a() #bug 11710
12126 {
12127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12128
12129         reset_async
12130
12131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12132         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12133         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12134
12135         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12136                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12137                 return 1;
12138         fi
12139         rm -f $DIR/$tfile
12140 }
12141 run_test 118a "verify O_SYNC works =========="
12142
12143 test_118b()
12144 {
12145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12146         remote_ost_nodsh && skip "remote OST with nodsh"
12147
12148         reset_async
12149
12150         #define OBD_FAIL_SRV_ENOENT 0x217
12151         set_nodes_failloc "$(osts_nodes)" 0x217
12152         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12153         RC=$?
12154         set_nodes_failloc "$(osts_nodes)" 0
12155         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12156         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12157                     grep -c writeback)
12158
12159         if [[ $RC -eq 0 ]]; then
12160                 error "Must return error due to dropped pages, rc=$RC"
12161                 return 1;
12162         fi
12163
12164         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12165                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12166                 return 1;
12167         fi
12168
12169         echo "Dirty pages not leaked on ENOENT"
12170
12171         # Due to the above error the OSC will issue all RPCs syncronously
12172         # until a subsequent RPC completes successfully without error.
12173         $MULTIOP $DIR/$tfile Ow4096yc
12174         rm -f $DIR/$tfile
12175
12176         return 0
12177 }
12178 run_test 118b "Reclaim dirty pages on fatal error =========="
12179
12180 test_118c()
12181 {
12182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12183
12184         # for 118c, restore the original resend count, LU-1940
12185         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12186                                 set_resend_count $OLD_RESENDCOUNT
12187         remote_ost_nodsh && skip "remote OST with nodsh"
12188
12189         reset_async
12190
12191         #define OBD_FAIL_OST_EROFS               0x216
12192         set_nodes_failloc "$(osts_nodes)" 0x216
12193
12194         # multiop should block due to fsync until pages are written
12195         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12196         MULTIPID=$!
12197         sleep 1
12198
12199         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12200                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12201         fi
12202
12203         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12204                     grep -c writeback)
12205         if [[ $WRITEBACK -eq 0 ]]; then
12206                 error "No page in writeback, writeback=$WRITEBACK"
12207         fi
12208
12209         set_nodes_failloc "$(osts_nodes)" 0
12210         wait $MULTIPID
12211         RC=$?
12212         if [[ $RC -ne 0 ]]; then
12213                 error "Multiop fsync failed, rc=$RC"
12214         fi
12215
12216         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12217         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12218                     grep -c writeback)
12219         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12220                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12221         fi
12222
12223         rm -f $DIR/$tfile
12224         echo "Dirty pages flushed via fsync on EROFS"
12225         return 0
12226 }
12227 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12228
12229 # continue to use small resend count to reduce test_118* time (b=14842)
12230 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12231
12232 test_118d()
12233 {
12234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12235         remote_ost_nodsh && skip "remote OST with nodsh"
12236
12237         reset_async
12238
12239         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12240         set_nodes_failloc "$(osts_nodes)" 0x214
12241         # multiop should block due to fsync until pages are written
12242         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12243         MULTIPID=$!
12244         sleep 1
12245
12246         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12247                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12248         fi
12249
12250         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12251                     grep -c writeback)
12252         if [[ $WRITEBACK -eq 0 ]]; then
12253                 error "No page in writeback, writeback=$WRITEBACK"
12254         fi
12255
12256         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12257         set_nodes_failloc "$(osts_nodes)" 0
12258
12259         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12260         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12261                     grep -c writeback)
12262         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12263                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12264         fi
12265
12266         rm -f $DIR/$tfile
12267         echo "Dirty pages gaurenteed flushed via fsync"
12268         return 0
12269 }
12270 run_test 118d "Fsync validation inject a delay of the bulk =========="
12271
12272 test_118f() {
12273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12274
12275         reset_async
12276
12277         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12278         lctl set_param fail_loc=0x8000040a
12279
12280         # Should simulate EINVAL error which is fatal
12281         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12282         RC=$?
12283         if [[ $RC -eq 0 ]]; then
12284                 error "Must return error due to dropped pages, rc=$RC"
12285         fi
12286
12287         lctl set_param fail_loc=0x0
12288
12289         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12290         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12291         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12292                     grep -c writeback)
12293         if [[ $LOCKED -ne 0 ]]; then
12294                 error "Locked pages remain in cache, locked=$LOCKED"
12295         fi
12296
12297         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12298                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12299         fi
12300
12301         rm -f $DIR/$tfile
12302         echo "No pages locked after fsync"
12303
12304         reset_async
12305         return 0
12306 }
12307 run_test 118f "Simulate unrecoverable OSC side error =========="
12308
12309 test_118g() {
12310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12311
12312         reset_async
12313
12314         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12315         lctl set_param fail_loc=0x406
12316
12317         # simulate local -ENOMEM
12318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12319         RC=$?
12320
12321         lctl set_param fail_loc=0
12322         if [[ $RC -eq 0 ]]; then
12323                 error "Must return error due to dropped pages, rc=$RC"
12324         fi
12325
12326         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12329                         grep -c writeback)
12330         if [[ $LOCKED -ne 0 ]]; then
12331                 error "Locked pages remain in cache, locked=$LOCKED"
12332         fi
12333
12334         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12335                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12336         fi
12337
12338         rm -f $DIR/$tfile
12339         echo "No pages locked after fsync"
12340
12341         reset_async
12342         return 0
12343 }
12344 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12345
12346 test_118h() {
12347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12348         remote_ost_nodsh && skip "remote OST with nodsh"
12349
12350         reset_async
12351
12352         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12353         set_nodes_failloc "$(osts_nodes)" 0x20e
12354         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12355         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12356         RC=$?
12357
12358         set_nodes_failloc "$(osts_nodes)" 0
12359         if [[ $RC -eq 0 ]]; then
12360                 error "Must return error due to dropped pages, rc=$RC"
12361         fi
12362
12363         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12364         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12365         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12366                     grep -c writeback)
12367         if [[ $LOCKED -ne 0 ]]; then
12368                 error "Locked pages remain in cache, locked=$LOCKED"
12369         fi
12370
12371         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12372                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12373         fi
12374
12375         rm -f $DIR/$tfile
12376         echo "No pages locked after fsync"
12377
12378         return 0
12379 }
12380 run_test 118h "Verify timeout in handling recoverables errors  =========="
12381
12382 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12383
12384 test_118i() {
12385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12386         remote_ost_nodsh && skip "remote OST with nodsh"
12387
12388         reset_async
12389
12390         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12391         set_nodes_failloc "$(osts_nodes)" 0x20e
12392
12393         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12394         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12395         PID=$!
12396         sleep 5
12397         set_nodes_failloc "$(osts_nodes)" 0
12398
12399         wait $PID
12400         RC=$?
12401         if [[ $RC -ne 0 ]]; then
12402                 error "got error, but should be not, rc=$RC"
12403         fi
12404
12405         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12406         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12407         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12408         if [[ $LOCKED -ne 0 ]]; then
12409                 error "Locked pages remain in cache, locked=$LOCKED"
12410         fi
12411
12412         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12413                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12414         fi
12415
12416         rm -f $DIR/$tfile
12417         echo "No pages locked after fsync"
12418
12419         return 0
12420 }
12421 run_test 118i "Fix error before timeout in recoverable error  =========="
12422
12423 [ "$SLOW" = "no" ] && set_resend_count 4
12424
12425 test_118j() {
12426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12427         remote_ost_nodsh && skip "remote OST with nodsh"
12428
12429         reset_async
12430
12431         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12432         set_nodes_failloc "$(osts_nodes)" 0x220
12433
12434         # return -EIO from OST
12435         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12436         RC=$?
12437         set_nodes_failloc "$(osts_nodes)" 0x0
12438         if [[ $RC -eq 0 ]]; then
12439                 error "Must return error due to dropped pages, rc=$RC"
12440         fi
12441
12442         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12443         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12444         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12445         if [[ $LOCKED -ne 0 ]]; then
12446                 error "Locked pages remain in cache, locked=$LOCKED"
12447         fi
12448
12449         # in recoverable error on OST we want resend and stay until it finished
12450         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12451                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12452         fi
12453
12454         rm -f $DIR/$tfile
12455         echo "No pages locked after fsync"
12456
12457         return 0
12458 }
12459 run_test 118j "Simulate unrecoverable OST side error =========="
12460
12461 test_118k()
12462 {
12463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12464         remote_ost_nodsh && skip "remote OSTs with nodsh"
12465
12466         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12467         set_nodes_failloc "$(osts_nodes)" 0x20e
12468         test_mkdir $DIR/$tdir
12469
12470         for ((i=0;i<10;i++)); do
12471                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12472                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12473                 SLEEPPID=$!
12474                 sleep 0.500s
12475                 kill $SLEEPPID
12476                 wait $SLEEPPID
12477         done
12478
12479         set_nodes_failloc "$(osts_nodes)" 0
12480         rm -rf $DIR/$tdir
12481 }
12482 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12483
12484 test_118l() # LU-646
12485 {
12486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12487
12488         test_mkdir $DIR/$tdir
12489         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12490         rm -rf $DIR/$tdir
12491 }
12492 run_test 118l "fsync dir"
12493
12494 test_118m() # LU-3066
12495 {
12496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12497
12498         test_mkdir $DIR/$tdir
12499         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12500         rm -rf $DIR/$tdir
12501 }
12502 run_test 118m "fdatasync dir ========="
12503
12504 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12505
12506 test_118n()
12507 {
12508         local begin
12509         local end
12510
12511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12512         remote_ost_nodsh && skip "remote OSTs with nodsh"
12513
12514         # Sleep to avoid a cached response.
12515         #define OBD_STATFS_CACHE_SECONDS 1
12516         sleep 2
12517
12518         # Inject a 10 second delay in the OST_STATFS handler.
12519         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12520         set_nodes_failloc "$(osts_nodes)" 0x242
12521
12522         begin=$SECONDS
12523         stat --file-system $MOUNT > /dev/null
12524         end=$SECONDS
12525
12526         set_nodes_failloc "$(osts_nodes)" 0
12527
12528         if ((end - begin > 20)); then
12529             error "statfs took $((end - begin)) seconds, expected 10"
12530         fi
12531 }
12532 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12533
12534 test_119a() # bug 11737
12535 {
12536         BSIZE=$((512 * 1024))
12537         directio write $DIR/$tfile 0 1 $BSIZE
12538         # We ask to read two blocks, which is more than a file size.
12539         # directio will indicate an error when requested and actual
12540         # sizes aren't equeal (a normal situation in this case) and
12541         # print actual read amount.
12542         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12543         if [ "$NOB" != "$BSIZE" ]; then
12544                 error "read $NOB bytes instead of $BSIZE"
12545         fi
12546         rm -f $DIR/$tfile
12547 }
12548 run_test 119a "Short directIO read must return actual read amount"
12549
12550 test_119b() # bug 11737
12551 {
12552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12553
12554         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12556         sync
12557         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12558                 error "direct read failed"
12559         rm -f $DIR/$tfile
12560 }
12561 run_test 119b "Sparse directIO read must return actual read amount"
12562
12563 test_119c() # bug 13099
12564 {
12565         BSIZE=1048576
12566         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12567         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12568         rm -f $DIR/$tfile
12569 }
12570 run_test 119c "Testing for direct read hitting hole"
12571
12572 test_119d() # bug 15950
12573 {
12574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12575
12576         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12577         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12578         BSIZE=1048576
12579         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12580         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12581         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12582         lctl set_param fail_loc=0x40d
12583         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12584         pid_dio=$!
12585         sleep 1
12586         cat $DIR/$tfile > /dev/null &
12587         lctl set_param fail_loc=0
12588         pid_reads=$!
12589         wait $pid_dio
12590         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12591         sleep 2
12592         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12593         error "the read rpcs have not completed in 2s"
12594         rm -f $DIR/$tfile
12595         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12596 }
12597 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12598
12599 test_120a() {
12600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12601         remote_mds_nodsh && skip "remote MDS with nodsh"
12602         test_mkdir -i0 -c1 $DIR/$tdir
12603         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12604                 skip_env "no early lock cancel on server"
12605
12606         lru_resize_disable mdc
12607         lru_resize_disable osc
12608         cancel_lru_locks mdc
12609         # asynchronous object destroy at MDT could cause bl ast to client
12610         cancel_lru_locks osc
12611
12612         stat $DIR/$tdir > /dev/null
12613         can1=$(do_facet mds1 \
12614                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12615                awk '/ldlm_cancel/ {print $2}')
12616         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12617                awk '/ldlm_bl_callback/ {print $2}')
12618         test_mkdir -i0 -c1 $DIR/$tdir/d1
12619         can2=$(do_facet mds1 \
12620                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12621                awk '/ldlm_cancel/ {print $2}')
12622         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12623                awk '/ldlm_bl_callback/ {print $2}')
12624         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12625         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12626         lru_resize_enable mdc
12627         lru_resize_enable osc
12628 }
12629 run_test 120a "Early Lock Cancel: mkdir test"
12630
12631 test_120b() {
12632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12633         remote_mds_nodsh && skip "remote MDS with nodsh"
12634         test_mkdir $DIR/$tdir
12635         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12636                 skip_env "no early lock cancel on server"
12637
12638         lru_resize_disable mdc
12639         lru_resize_disable osc
12640         cancel_lru_locks mdc
12641         stat $DIR/$tdir > /dev/null
12642         can1=$(do_facet $SINGLEMDS \
12643                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12644                awk '/ldlm_cancel/ {print $2}')
12645         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12646                awk '/ldlm_bl_callback/ {print $2}')
12647         touch $DIR/$tdir/f1
12648         can2=$(do_facet $SINGLEMDS \
12649                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12650                awk '/ldlm_cancel/ {print $2}')
12651         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12652                awk '/ldlm_bl_callback/ {print $2}')
12653         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12654         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12655         lru_resize_enable mdc
12656         lru_resize_enable osc
12657 }
12658 run_test 120b "Early Lock Cancel: create test"
12659
12660 test_120c() {
12661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12662         remote_mds_nodsh && skip "remote MDS with nodsh"
12663         test_mkdir -i0 -c1 $DIR/$tdir
12664         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12665                 skip "no early lock cancel on server"
12666
12667         lru_resize_disable mdc
12668         lru_resize_disable osc
12669         test_mkdir -i0 -c1 $DIR/$tdir/d1
12670         test_mkdir -i0 -c1 $DIR/$tdir/d2
12671         touch $DIR/$tdir/d1/f1
12672         cancel_lru_locks mdc
12673         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12674         can1=$(do_facet mds1 \
12675                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12676                awk '/ldlm_cancel/ {print $2}')
12677         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12678                awk '/ldlm_bl_callback/ {print $2}')
12679         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12680         can2=$(do_facet mds1 \
12681                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12682                awk '/ldlm_cancel/ {print $2}')
12683         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12684                awk '/ldlm_bl_callback/ {print $2}')
12685         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12686         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12687         lru_resize_enable mdc
12688         lru_resize_enable osc
12689 }
12690 run_test 120c "Early Lock Cancel: link test"
12691
12692 test_120d() {
12693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12694         remote_mds_nodsh && skip "remote MDS with nodsh"
12695         test_mkdir -i0 -c1 $DIR/$tdir
12696         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12697                 skip_env "no early lock cancel on server"
12698
12699         lru_resize_disable mdc
12700         lru_resize_disable osc
12701         touch $DIR/$tdir
12702         cancel_lru_locks mdc
12703         stat $DIR/$tdir > /dev/null
12704         can1=$(do_facet mds1 \
12705                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12706                awk '/ldlm_cancel/ {print $2}')
12707         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12708                awk '/ldlm_bl_callback/ {print $2}')
12709         chmod a+x $DIR/$tdir
12710         can2=$(do_facet mds1 \
12711                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12712                awk '/ldlm_cancel/ {print $2}')
12713         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12714                awk '/ldlm_bl_callback/ {print $2}')
12715         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12716         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12717         lru_resize_enable mdc
12718         lru_resize_enable osc
12719 }
12720 run_test 120d "Early Lock Cancel: setattr test"
12721
12722 test_120e() {
12723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12724         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12725                 skip_env "no early lock cancel on server"
12726         remote_mds_nodsh && skip "remote MDS with nodsh"
12727
12728         local dlmtrace_set=false
12729
12730         test_mkdir -i0 -c1 $DIR/$tdir
12731         lru_resize_disable mdc
12732         lru_resize_disable osc
12733         ! $LCTL get_param debug | grep -q dlmtrace &&
12734                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12735         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12736         cancel_lru_locks mdc
12737         cancel_lru_locks osc
12738         dd if=$DIR/$tdir/f1 of=/dev/null
12739         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12740         # XXX client can not do early lock cancel of OST lock
12741         # during unlink (LU-4206), so cancel osc lock now.
12742         sleep 2
12743         cancel_lru_locks osc
12744         can1=$(do_facet mds1 \
12745                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12746                awk '/ldlm_cancel/ {print $2}')
12747         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12748                awk '/ldlm_bl_callback/ {print $2}')
12749         unlink $DIR/$tdir/f1
12750         sleep 5
12751         can2=$(do_facet mds1 \
12752                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12753                awk '/ldlm_cancel/ {print $2}')
12754         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12755                awk '/ldlm_bl_callback/ {print $2}')
12756         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12757                 $LCTL dk $TMP/cancel.debug.txt
12758         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12759                 $LCTL dk $TMP/blocking.debug.txt
12760         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12761         lru_resize_enable mdc
12762         lru_resize_enable osc
12763 }
12764 run_test 120e "Early Lock Cancel: unlink test"
12765
12766 test_120f() {
12767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12768         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12769                 skip_env "no early lock cancel on server"
12770         remote_mds_nodsh && skip "remote MDS with nodsh"
12771
12772         test_mkdir -i0 -c1 $DIR/$tdir
12773         lru_resize_disable mdc
12774         lru_resize_disable osc
12775         test_mkdir -i0 -c1 $DIR/$tdir/d1
12776         test_mkdir -i0 -c1 $DIR/$tdir/d2
12777         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12778         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12779         cancel_lru_locks mdc
12780         cancel_lru_locks osc
12781         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12782         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12783         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12784         # XXX client can not do early lock cancel of OST lock
12785         # during rename (LU-4206), so cancel osc lock now.
12786         sleep 2
12787         cancel_lru_locks osc
12788         can1=$(do_facet mds1 \
12789                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12790                awk '/ldlm_cancel/ {print $2}')
12791         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12792                awk '/ldlm_bl_callback/ {print $2}')
12793         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12794         sleep 5
12795         can2=$(do_facet mds1 \
12796                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12797                awk '/ldlm_cancel/ {print $2}')
12798         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12799                awk '/ldlm_bl_callback/ {print $2}')
12800         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12801         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12802         lru_resize_enable mdc
12803         lru_resize_enable osc
12804 }
12805 run_test 120f "Early Lock Cancel: rename test"
12806
12807 test_120g() {
12808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12809         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12810                 skip_env "no early lock cancel on server"
12811         remote_mds_nodsh && skip "remote MDS with nodsh"
12812
12813         lru_resize_disable mdc
12814         lru_resize_disable osc
12815         count=10000
12816         echo create $count files
12817         test_mkdir $DIR/$tdir
12818         cancel_lru_locks mdc
12819         cancel_lru_locks osc
12820         t0=$(date +%s)
12821
12822         can0=$(do_facet $SINGLEMDS \
12823                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12824                awk '/ldlm_cancel/ {print $2}')
12825         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12826                awk '/ldlm_bl_callback/ {print $2}')
12827         createmany -o $DIR/$tdir/f $count
12828         sync
12829         can1=$(do_facet $SINGLEMDS \
12830                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12831                awk '/ldlm_cancel/ {print $2}')
12832         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12833                awk '/ldlm_bl_callback/ {print $2}')
12834         t1=$(date +%s)
12835         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12836         echo rm $count files
12837         rm -r $DIR/$tdir
12838         sync
12839         can2=$(do_facet $SINGLEMDS \
12840                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12841                awk '/ldlm_cancel/ {print $2}')
12842         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12843                awk '/ldlm_bl_callback/ {print $2}')
12844         t2=$(date +%s)
12845         echo total: $count removes in $((t2-t1))
12846         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12847         sleep 2
12848         # wait for commitment of removal
12849         lru_resize_enable mdc
12850         lru_resize_enable osc
12851 }
12852 run_test 120g "Early Lock Cancel: performance test"
12853
12854 test_121() { #bug #10589
12855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12856
12857         rm -rf $DIR/$tfile
12858         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12859 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12860         lctl set_param fail_loc=0x310
12861         cancel_lru_locks osc > /dev/null
12862         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12863         lctl set_param fail_loc=0
12864         [[ $reads -eq $writes ]] ||
12865                 error "read $reads blocks, must be $writes blocks"
12866 }
12867 run_test 121 "read cancel race ========="
12868
12869 test_123a_base() { # was test 123, statahead(bug 11401)
12870         local lsx="$1"
12871
12872         SLOWOK=0
12873         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12874                 log "testing UP system. Performance may be lower than expected."
12875                 SLOWOK=1
12876         fi
12877         running_in_vm && SLOWOK=1
12878
12879         rm -rf $DIR/$tdir
12880         test_mkdir $DIR/$tdir
12881         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12882         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12883         MULT=10
12884         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12885                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12886
12887                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12888                 lctl set_param -n llite.*.statahead_max 0
12889                 lctl get_param llite.*.statahead_max
12890                 cancel_lru_locks mdc
12891                 cancel_lru_locks osc
12892                 stime=$(date +%s)
12893                 time $lsx $DIR/$tdir | wc -l
12894                 etime=$(date +%s)
12895                 delta=$((etime - stime))
12896                 log "$lsx $i files without statahead: $delta sec"
12897                 lctl set_param llite.*.statahead_max=$max
12898
12899                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12900                         grep "statahead wrong:" | awk '{print $3}')
12901                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12902                 cancel_lru_locks mdc
12903                 cancel_lru_locks osc
12904                 stime=$(date +%s)
12905                 time $lsx $DIR/$tdir | wc -l
12906                 etime=$(date +%s)
12907                 delta_sa=$((etime - stime))
12908                 log "$lsx $i files with statahead: $delta_sa sec"
12909                 lctl get_param -n llite.*.statahead_stats
12910                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12911                         grep "statahead wrong:" | awk '{print $3}')
12912
12913                 [[ $swrong -lt $ewrong ]] &&
12914                         log "statahead was stopped, maybe too many locks held!"
12915                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12916
12917                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12918                         max=$(lctl get_param -n llite.*.statahead_max |
12919                                 head -n 1)
12920                         lctl set_param -n llite.*.statahead_max 0
12921                         lctl get_param llite.*.statahead_max
12922                         cancel_lru_locks mdc
12923                         cancel_lru_locks osc
12924                         stime=$(date +%s)
12925                         time $lsx $DIR/$tdir | wc -l
12926                         etime=$(date +%s)
12927                         delta=$((etime - stime))
12928                         log "$lsx $i files again without statahead: $delta sec"
12929                         lctl set_param llite.*.statahead_max=$max
12930                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12931                                 if [  $SLOWOK -eq 0 ]; then
12932                                         error "$lsx $i files is slower with statahead!"
12933                                 else
12934                                         log "$lsx $i files is slower with statahead!"
12935                                 fi
12936                                 break
12937                         fi
12938                 fi
12939
12940                 [ $delta -gt 20 ] && break
12941                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12942                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12943         done
12944         log "$lsx done"
12945
12946         stime=$(date +%s)
12947         rm -r $DIR/$tdir
12948         sync
12949         etime=$(date +%s)
12950         delta=$((etime - stime))
12951         log "rm -r $DIR/$tdir/: $delta seconds"
12952         log "rm done"
12953         lctl get_param -n llite.*.statahead_stats
12954 }
12955
12956 test_123aa() {
12957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12958
12959         test_123a_base "ls -l"
12960 }
12961 run_test 123aa "verify statahead work"
12962
12963 test_123ab() {
12964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12965
12966         statx_supported || skip_env "Test must be statx() syscall supported"
12967
12968         test_123a_base "$STATX -l"
12969 }
12970 run_test 123ab "verify statahead work by using statx"
12971
12972 test_123ac() {
12973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12974
12975         statx_supported || skip_env "Test must be statx() syscall supported"
12976
12977         local rpcs_before
12978         local rpcs_after
12979         local agl_before
12980         local agl_after
12981
12982         cancel_lru_locks $OSC
12983         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12984         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12985                 awk '/agl.total:/ {print $3}')
12986         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12987         test_123a_base "$STATX --cached=always -D"
12988         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12989                 awk '/agl.total:/ {print $3}')
12990         [ $agl_before -eq $agl_after ] ||
12991                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12992         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12993         [ $rpcs_after -eq $rpcs_before ] ||
12994                 error "$STATX should not send glimpse RPCs to $OSC"
12995 }
12996 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12997
12998 test_123b () { # statahead(bug 15027)
12999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13000
13001         test_mkdir $DIR/$tdir
13002         createmany -o $DIR/$tdir/$tfile-%d 1000
13003
13004         cancel_lru_locks mdc
13005         cancel_lru_locks osc
13006
13007 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13008         lctl set_param fail_loc=0x80000803
13009         ls -lR $DIR/$tdir > /dev/null
13010         log "ls done"
13011         lctl set_param fail_loc=0x0
13012         lctl get_param -n llite.*.statahead_stats
13013         rm -r $DIR/$tdir
13014         sync
13015
13016 }
13017 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13018
13019 test_123c() {
13020         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13021
13022         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13023         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13024         touch $DIR/$tdir.1/{1..3}
13025         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13026
13027         remount_client $MOUNT
13028
13029         $MULTIOP $DIR/$tdir.0 Q
13030
13031         # let statahead to complete
13032         ls -l $DIR/$tdir.0 > /dev/null
13033
13034         testid=$(echo $TESTNAME | tr '_' ' ')
13035         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13036                 error "statahead warning" || true
13037 }
13038 run_test 123c "Can not initialize inode warning on DNE statahead"
13039
13040 test_124a() {
13041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13042         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13043                 skip_env "no lru resize on server"
13044
13045         local NR=2000
13046
13047         test_mkdir $DIR/$tdir
13048
13049         log "create $NR files at $DIR/$tdir"
13050         createmany -o $DIR/$tdir/f $NR ||
13051                 error "failed to create $NR files in $DIR/$tdir"
13052
13053         cancel_lru_locks mdc
13054         ls -l $DIR/$tdir > /dev/null
13055
13056         local NSDIR=""
13057         local LRU_SIZE=0
13058         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13059                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13060                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13061                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13062                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13063                         log "NSDIR=$NSDIR"
13064                         log "NS=$(basename $NSDIR)"
13065                         break
13066                 fi
13067         done
13068
13069         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13070                 skip "Not enough cached locks created!"
13071         fi
13072         log "LRU=$LRU_SIZE"
13073
13074         local SLEEP=30
13075
13076         # We know that lru resize allows one client to hold $LIMIT locks
13077         # for 10h. After that locks begin to be killed by client.
13078         local MAX_HRS=10
13079         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13080         log "LIMIT=$LIMIT"
13081         if [ $LIMIT -lt $LRU_SIZE ]; then
13082                 skip "Limit is too small $LIMIT"
13083         fi
13084
13085         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13086         # killing locks. Some time was spent for creating locks. This means
13087         # that up to the moment of sleep finish we must have killed some of
13088         # them (10-100 locks). This depends on how fast ther were created.
13089         # Many of them were touched in almost the same moment and thus will
13090         # be killed in groups.
13091         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13092
13093         # Use $LRU_SIZE_B here to take into account real number of locks
13094         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13095         local LRU_SIZE_B=$LRU_SIZE
13096         log "LVF=$LVF"
13097         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13098         log "OLD_LVF=$OLD_LVF"
13099         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13100
13101         # Let's make sure that we really have some margin. Client checks
13102         # cached locks every 10 sec.
13103         SLEEP=$((SLEEP+20))
13104         log "Sleep ${SLEEP} sec"
13105         local SEC=0
13106         while ((SEC<$SLEEP)); do
13107                 echo -n "..."
13108                 sleep 5
13109                 SEC=$((SEC+5))
13110                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13111                 echo -n "$LRU_SIZE"
13112         done
13113         echo ""
13114         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13115         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13116
13117         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13118                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13119                 unlinkmany $DIR/$tdir/f $NR
13120                 return
13121         }
13122
13123         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13124         log "unlink $NR files at $DIR/$tdir"
13125         unlinkmany $DIR/$tdir/f $NR
13126 }
13127 run_test 124a "lru resize ======================================="
13128
13129 get_max_pool_limit()
13130 {
13131         local limit=$($LCTL get_param \
13132                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13133         local max=0
13134         for l in $limit; do
13135                 if [[ $l -gt $max ]]; then
13136                         max=$l
13137                 fi
13138         done
13139         echo $max
13140 }
13141
13142 test_124b() {
13143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13144         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13145                 skip_env "no lru resize on server"
13146
13147         LIMIT=$(get_max_pool_limit)
13148
13149         NR=$(($(default_lru_size)*20))
13150         if [[ $NR -gt $LIMIT ]]; then
13151                 log "Limit lock number by $LIMIT locks"
13152                 NR=$LIMIT
13153         fi
13154
13155         IFree=$(mdsrate_inodes_available)
13156         if [ $IFree -lt $NR ]; then
13157                 log "Limit lock number by $IFree inodes"
13158                 NR=$IFree
13159         fi
13160
13161         lru_resize_disable mdc
13162         test_mkdir -p $DIR/$tdir/disable_lru_resize
13163
13164         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13165         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13166         cancel_lru_locks mdc
13167         stime=`date +%s`
13168         PID=""
13169         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13170         PID="$PID $!"
13171         sleep 2
13172         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13173         PID="$PID $!"
13174         sleep 2
13175         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13176         PID="$PID $!"
13177         wait $PID
13178         etime=`date +%s`
13179         nolruresize_delta=$((etime-stime))
13180         log "ls -la time: $nolruresize_delta seconds"
13181         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13182         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13183
13184         lru_resize_enable mdc
13185         test_mkdir -p $DIR/$tdir/enable_lru_resize
13186
13187         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13188         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13189         cancel_lru_locks mdc
13190         stime=`date +%s`
13191         PID=""
13192         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13193         PID="$PID $!"
13194         sleep 2
13195         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13196         PID="$PID $!"
13197         sleep 2
13198         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13199         PID="$PID $!"
13200         wait $PID
13201         etime=`date +%s`
13202         lruresize_delta=$((etime-stime))
13203         log "ls -la time: $lruresize_delta seconds"
13204         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13205
13206         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13207                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13208         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13209                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13210         else
13211                 log "lru resize performs the same with no lru resize"
13212         fi
13213         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13214 }
13215 run_test 124b "lru resize (performance test) ======================="
13216
13217 test_124c() {
13218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13219         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13220                 skip_env "no lru resize on server"
13221
13222         # cache ununsed locks on client
13223         local nr=100
13224         cancel_lru_locks mdc
13225         test_mkdir $DIR/$tdir
13226         createmany -o $DIR/$tdir/f $nr ||
13227                 error "failed to create $nr files in $DIR/$tdir"
13228         ls -l $DIR/$tdir > /dev/null
13229
13230         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13231         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13232         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13233         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13234         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13235
13236         # set lru_max_age to 1 sec
13237         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13238         echo "sleep $((recalc_p * 2)) seconds..."
13239         sleep $((recalc_p * 2))
13240
13241         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13242         # restore lru_max_age
13243         $LCTL set_param -n $nsdir.lru_max_age $max_age
13244         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13245         unlinkmany $DIR/$tdir/f $nr
13246 }
13247 run_test 124c "LRUR cancel very aged locks"
13248
13249 test_124d() {
13250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13251         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13252                 skip_env "no lru resize on server"
13253
13254         # cache ununsed locks on client
13255         local nr=100
13256
13257         lru_resize_disable mdc
13258         stack_trap "lru_resize_enable mdc" EXIT
13259
13260         cancel_lru_locks mdc
13261
13262         # asynchronous object destroy at MDT could cause bl ast to client
13263         test_mkdir $DIR/$tdir
13264         createmany -o $DIR/$tdir/f $nr ||
13265                 error "failed to create $nr files in $DIR/$tdir"
13266         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13267
13268         ls -l $DIR/$tdir > /dev/null
13269
13270         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13271         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13272         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13273         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13274
13275         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13276
13277         # set lru_max_age to 1 sec
13278         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13279         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13280
13281         echo "sleep $((recalc_p * 2)) seconds..."
13282         sleep $((recalc_p * 2))
13283
13284         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13285
13286         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13287 }
13288 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13289
13290 test_125() { # 13358
13291         $LCTL get_param -n llite.*.client_type | grep -q local ||
13292                 skip "must run as local client"
13293         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13294                 skip_env "must have acl enabled"
13295         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13296
13297         test_mkdir $DIR/$tdir
13298         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13299         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13300         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13301 }
13302 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13303
13304 test_126() { # bug 12829/13455
13305         $GSS && skip_env "must run as gss disabled"
13306         $LCTL get_param -n llite.*.client_type | grep -q local ||
13307                 skip "must run as local client"
13308         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13309
13310         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13311         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13312         rm -f $DIR/$tfile
13313         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13314 }
13315 run_test 126 "check that the fsgid provided by the client is taken into account"
13316
13317 test_127a() { # bug 15521
13318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13319         local name count samp unit min max sum sumsq
13320
13321         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13322         echo "stats before reset"
13323         $LCTL get_param osc.*.stats
13324         $LCTL set_param osc.*.stats=0
13325         local fsize=$((2048 * 1024))
13326
13327         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13328         cancel_lru_locks osc
13329         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13330
13331         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13332         stack_trap "rm -f $TMP/$tfile.tmp"
13333         while read name count samp unit min max sum sumsq; do
13334                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13335                 [ ! $min ] && error "Missing min value for $name proc entry"
13336                 eval $name=$count || error "Wrong proc format"
13337
13338                 case $name in
13339                 read_bytes|write_bytes)
13340                         [[ "$unit" =~ "bytes" ]] ||
13341                                 error "unit is not 'bytes': $unit"
13342                         (( $min >= 4096 )) || error "min is too small: $min"
13343                         (( $min <= $fsize )) || error "min is too big: $min"
13344                         (( $max >= 4096 )) || error "max is too small: $max"
13345                         (( $max <= $fsize )) || error "max is too big: $max"
13346                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13347                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13348                                 error "sumsquare is too small: $sumsq"
13349                         (( $sumsq <= $fsize * $fsize )) ||
13350                                 error "sumsquare is too big: $sumsq"
13351                         ;;
13352                 ost_read|ost_write)
13353                         [[ "$unit" =~ "usec" ]] ||
13354                                 error "unit is not 'usec': $unit"
13355                         ;;
13356                 *)      ;;
13357                 esac
13358         done < $DIR/$tfile.tmp
13359
13360         #check that we actually got some stats
13361         [ "$read_bytes" ] || error "Missing read_bytes stats"
13362         [ "$write_bytes" ] || error "Missing write_bytes stats"
13363         [ "$read_bytes" != 0 ] || error "no read done"
13364         [ "$write_bytes" != 0 ] || error "no write done"
13365 }
13366 run_test 127a "verify the client stats are sane"
13367
13368 test_127b() { # bug LU-333
13369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13370         local name count samp unit min max sum sumsq
13371
13372         echo "stats before reset"
13373         $LCTL get_param llite.*.stats
13374         $LCTL set_param llite.*.stats=0
13375
13376         # perform 2 reads and writes so MAX is different from SUM.
13377         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13378         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13379         cancel_lru_locks osc
13380         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13381         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13382
13383         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13384         stack_trap "rm -f $TMP/$tfile.tmp"
13385         while read name count samp unit min max sum sumsq; do
13386                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13387                 eval $name=$count || error "Wrong proc format"
13388
13389                 case $name in
13390                 read_bytes|write_bytes)
13391                         [[ "$unit" =~ "bytes" ]] ||
13392                                 error "unit is not 'bytes': $unit"
13393                         (( $count == 2 )) || error "count is not 2: $count"
13394                         (( $min == $PAGE_SIZE )) ||
13395                                 error "min is not $PAGE_SIZE: $min"
13396                         (( $max == $PAGE_SIZE )) ||
13397                                 error "max is not $PAGE_SIZE: $max"
13398                         (( $sum == $PAGE_SIZE * 2 )) ||
13399                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13400                         ;;
13401                 read|write)
13402                         [[ "$unit" =~ "usec" ]] ||
13403                                 error "unit is not 'usec': $unit"
13404                         ;;
13405                 *)      ;;
13406                 esac
13407         done < $TMP/$tfile.tmp
13408
13409         #check that we actually got some stats
13410         [ "$read_bytes" ] || error "Missing read_bytes stats"
13411         [ "$write_bytes" ] || error "Missing write_bytes stats"
13412         [ "$read_bytes" != 0 ] || error "no read done"
13413         [ "$write_bytes" != 0 ] || error "no write done"
13414 }
13415 run_test 127b "verify the llite client stats are sane"
13416
13417 test_127c() { # LU-12394
13418         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13419         local size
13420         local bsize
13421         local reads
13422         local writes
13423         local count
13424
13425         $LCTL set_param llite.*.extents_stats=1
13426         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13427
13428         # Use two stripes so there is enough space in default config
13429         $LFS setstripe -c 2 $DIR/$tfile
13430
13431         # Extent stats start at 0-4K and go in power of two buckets
13432         # LL_HIST_START = 12 --> 2^12 = 4K
13433         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13434         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13435         # small configs
13436         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13437                 do
13438                 # Write and read, 2x each, second time at a non-zero offset
13439                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13440                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13441                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13442                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13443                 rm -f $DIR/$tfile
13444         done
13445
13446         $LCTL get_param llite.*.extents_stats
13447
13448         count=2
13449         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13450                 do
13451                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13452                                 grep -m 1 $bsize)
13453                 reads=$(echo $bucket | awk '{print $5}')
13454                 writes=$(echo $bucket | awk '{print $9}')
13455                 [ "$reads" -eq $count ] ||
13456                         error "$reads reads in < $bsize bucket, expect $count"
13457                 [ "$writes" -eq $count ] ||
13458                         error "$writes writes in < $bsize bucket, expect $count"
13459         done
13460
13461         # Test mmap write and read
13462         $LCTL set_param llite.*.extents_stats=c
13463         size=512
13464         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13465         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13466         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13467
13468         $LCTL get_param llite.*.extents_stats
13469
13470         count=$(((size*1024) / PAGE_SIZE))
13471
13472         bsize=$((2 * PAGE_SIZE / 1024))K
13473
13474         bucket=$($LCTL get_param -n llite.*.extents_stats |
13475                         grep -m 1 $bsize)
13476         reads=$(echo $bucket | awk '{print $5}')
13477         writes=$(echo $bucket | awk '{print $9}')
13478         # mmap writes fault in the page first, creating an additonal read
13479         [ "$reads" -eq $((2 * count)) ] ||
13480                 error "$reads reads in < $bsize bucket, expect $count"
13481         [ "$writes" -eq $count ] ||
13482                 error "$writes writes in < $bsize bucket, expect $count"
13483 }
13484 run_test 127c "test llite extent stats with regular & mmap i/o"
13485
13486 test_128() { # bug 15212
13487         touch $DIR/$tfile
13488         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13489                 find $DIR/$tfile
13490                 find $DIR/$tfile
13491         EOF
13492
13493         result=$(grep error $TMP/$tfile.log)
13494         rm -f $DIR/$tfile $TMP/$tfile.log
13495         [ -z "$result" ] ||
13496                 error "consecutive find's under interactive lfs failed"
13497 }
13498 run_test 128 "interactive lfs for 2 consecutive find's"
13499
13500 set_dir_limits () {
13501         local mntdev
13502         local canondev
13503         local node
13504
13505         local ldproc=/proc/fs/ldiskfs
13506         local facets=$(get_facets MDS)
13507
13508         for facet in ${facets//,/ }; do
13509                 canondev=$(ldiskfs_canon \
13510                            *.$(convert_facet2label $facet).mntdev $facet)
13511                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13512                         ldproc=/sys/fs/ldiskfs
13513                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13514                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13515         done
13516 }
13517
13518 check_mds_dmesg() {
13519         local facets=$(get_facets MDS)
13520         for facet in ${facets//,/ }; do
13521                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13522         done
13523         return 1
13524 }
13525
13526 test_129() {
13527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13528         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13529                 skip "Need MDS version with at least 2.5.56"
13530         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13531                 skip_env "ldiskfs only test"
13532         fi
13533         remote_mds_nodsh && skip "remote MDS with nodsh"
13534
13535         local ENOSPC=28
13536         local has_warning=false
13537
13538         rm -rf $DIR/$tdir
13539         mkdir -p $DIR/$tdir
13540
13541         # block size of mds1
13542         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13543         set_dir_limits $maxsize $((maxsize * 6 / 8))
13544         stack_trap "set_dir_limits 0 0"
13545         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13546         local dirsize=$(stat -c%s "$DIR/$tdir")
13547         local nfiles=0
13548         while (( $dirsize <= $maxsize )); do
13549                 $MCREATE $DIR/$tdir/file_base_$nfiles
13550                 rc=$?
13551                 # check two errors:
13552                 # ENOSPC for ext4 max_dir_size, which has been used since
13553                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13554                 if (( rc == ENOSPC )); then
13555                         set_dir_limits 0 0
13556                         echo "rc=$rc returned as expected after $nfiles files"
13557
13558                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13559                                 error "create failed w/o dir size limit"
13560
13561                         # messages may be rate limited if test is run repeatedly
13562                         check_mds_dmesg '"is approaching max"' ||
13563                                 echo "warning message should be output"
13564                         check_mds_dmesg '"has reached max"' ||
13565                                 echo "reached message should be output"
13566
13567                         dirsize=$(stat -c%s "$DIR/$tdir")
13568
13569                         [[ $dirsize -ge $maxsize ]] && return 0
13570                         error "dirsize $dirsize < $maxsize after $nfiles files"
13571                 elif (( rc != 0 )); then
13572                         break
13573                 fi
13574                 nfiles=$((nfiles + 1))
13575                 dirsize=$(stat -c%s "$DIR/$tdir")
13576         done
13577
13578         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13579 }
13580 run_test 129 "test directory size limit ========================"
13581
13582 OLDIFS="$IFS"
13583 cleanup_130() {
13584         trap 0
13585         IFS="$OLDIFS"
13586 }
13587
13588 test_130a() {
13589         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13590         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13591
13592         trap cleanup_130 EXIT RETURN
13593
13594         local fm_file=$DIR/$tfile
13595         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13596         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13597                 error "dd failed for $fm_file"
13598
13599         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13600         filefrag -ves $fm_file
13601         RC=$?
13602         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13603                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13604         [ $RC != 0 ] && error "filefrag $fm_file failed"
13605
13606         filefrag_op=$(filefrag -ve -k $fm_file |
13607                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13608         lun=$($LFS getstripe -i $fm_file)
13609
13610         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13611         IFS=$'\n'
13612         tot_len=0
13613         for line in $filefrag_op
13614         do
13615                 frag_lun=`echo $line | cut -d: -f5`
13616                 ext_len=`echo $line | cut -d: -f4`
13617                 if (( $frag_lun != $lun )); then
13618                         cleanup_130
13619                         error "FIEMAP on 1-stripe file($fm_file) failed"
13620                         return
13621                 fi
13622                 (( tot_len += ext_len ))
13623         done
13624
13625         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13626                 cleanup_130
13627                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13628                 return
13629         fi
13630
13631         cleanup_130
13632
13633         echo "FIEMAP on single striped file succeeded"
13634 }
13635 run_test 130a "FIEMAP (1-stripe file)"
13636
13637 test_130b() {
13638         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13639
13640         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13641         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13642
13643         trap cleanup_130 EXIT RETURN
13644
13645         local fm_file=$DIR/$tfile
13646         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13647                         error "setstripe on $fm_file"
13648         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13649                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13650
13651         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13652                 error "dd failed on $fm_file"
13653
13654         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13655         filefrag_op=$(filefrag -ve -k $fm_file |
13656                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13657
13658         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13659                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13660
13661         IFS=$'\n'
13662         tot_len=0
13663         num_luns=1
13664         for line in $filefrag_op
13665         do
13666                 frag_lun=$(echo $line | cut -d: -f5 |
13667                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13668                 ext_len=$(echo $line | cut -d: -f4)
13669                 if (( $frag_lun != $last_lun )); then
13670                         if (( tot_len != 1024 )); then
13671                                 cleanup_130
13672                                 error "FIEMAP on $fm_file failed; returned " \
13673                                 "len $tot_len for OST $last_lun instead of 1024"
13674                                 return
13675                         else
13676                                 (( num_luns += 1 ))
13677                                 tot_len=0
13678                         fi
13679                 fi
13680                 (( tot_len += ext_len ))
13681                 last_lun=$frag_lun
13682         done
13683         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13684                 cleanup_130
13685                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13686                         "luns or wrong len for OST $last_lun"
13687                 return
13688         fi
13689
13690         cleanup_130
13691
13692         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13693 }
13694 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13695
13696 test_130c() {
13697         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13698
13699         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13700         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13701
13702         trap cleanup_130 EXIT RETURN
13703
13704         local fm_file=$DIR/$tfile
13705         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13706         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13707                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13708
13709         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13710                         error "dd failed on $fm_file"
13711
13712         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13713         filefrag_op=$(filefrag -ve -k $fm_file |
13714                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13715
13716         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13717                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13718
13719         IFS=$'\n'
13720         tot_len=0
13721         num_luns=1
13722         for line in $filefrag_op
13723         do
13724                 frag_lun=$(echo $line | cut -d: -f5 |
13725                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13726                 ext_len=$(echo $line | cut -d: -f4)
13727                 if (( $frag_lun != $last_lun )); then
13728                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13729                         if (( logical != 512 )); then
13730                                 cleanup_130
13731                                 error "FIEMAP on $fm_file failed; returned " \
13732                                 "logical start for lun $logical instead of 512"
13733                                 return
13734                         fi
13735                         if (( tot_len != 512 )); then
13736                                 cleanup_130
13737                                 error "FIEMAP on $fm_file failed; returned " \
13738                                 "len $tot_len for OST $last_lun instead of 1024"
13739                                 return
13740                         else
13741                                 (( num_luns += 1 ))
13742                                 tot_len=0
13743                         fi
13744                 fi
13745                 (( tot_len += ext_len ))
13746                 last_lun=$frag_lun
13747         done
13748         if (( num_luns != 2 || tot_len != 512 )); then
13749                 cleanup_130
13750                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13751                         "luns or wrong len for OST $last_lun"
13752                 return
13753         fi
13754
13755         cleanup_130
13756
13757         echo "FIEMAP on 2-stripe file with hole succeeded"
13758 }
13759 run_test 130c "FIEMAP (2-stripe file with hole)"
13760
13761 test_130d() {
13762         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13763
13764         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13765         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13766
13767         trap cleanup_130 EXIT RETURN
13768
13769         local fm_file=$DIR/$tfile
13770         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13771                         error "setstripe on $fm_file"
13772         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13773                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13774
13775         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13776         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13777                 error "dd failed on $fm_file"
13778
13779         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13780         filefrag_op=$(filefrag -ve -k $fm_file |
13781                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13782
13783         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13784                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13785
13786         IFS=$'\n'
13787         tot_len=0
13788         num_luns=1
13789         for line in $filefrag_op
13790         do
13791                 frag_lun=$(echo $line | cut -d: -f5 |
13792                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13793                 ext_len=$(echo $line | cut -d: -f4)
13794                 if (( $frag_lun != $last_lun )); then
13795                         if (( tot_len != 1024 )); then
13796                                 cleanup_130
13797                                 error "FIEMAP on $fm_file failed; returned " \
13798                                 "len $tot_len for OST $last_lun instead of 1024"
13799                                 return
13800                         else
13801                                 (( num_luns += 1 ))
13802                                 tot_len=0
13803                         fi
13804                 fi
13805                 (( tot_len += ext_len ))
13806                 last_lun=$frag_lun
13807         done
13808         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13809                 cleanup_130
13810                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13811                         "luns or wrong len for OST $last_lun"
13812                 return
13813         fi
13814
13815         cleanup_130
13816
13817         echo "FIEMAP on N-stripe file succeeded"
13818 }
13819 run_test 130d "FIEMAP (N-stripe file)"
13820
13821 test_130e() {
13822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13823
13824         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13825         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13826
13827         trap cleanup_130 EXIT RETURN
13828
13829         local fm_file=$DIR/$tfile
13830         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13831
13832         NUM_BLKS=512
13833         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13834         for ((i = 0; i < $NUM_BLKS; i++)); do
13835                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13836                         conv=notrunc > /dev/null 2>&1
13837         done
13838
13839         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13840         filefrag_op=$(filefrag -ve -k $fm_file |
13841                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13842
13843         last_lun=$(echo $filefrag_op | cut -d: -f5)
13844
13845         IFS=$'\n'
13846         tot_len=0
13847         num_luns=1
13848         for line in $filefrag_op; do
13849                 frag_lun=$(echo $line | cut -d: -f5)
13850                 ext_len=$(echo $line | cut -d: -f4)
13851                 if [[ "$frag_lun" != "$last_lun" ]]; then
13852                         if (( tot_len != $EXPECTED_LEN )); then
13853                                 cleanup_130
13854                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13855                         else
13856                                 (( num_luns += 1 ))
13857                                 tot_len=0
13858                         fi
13859                 fi
13860                 (( tot_len += ext_len ))
13861                 last_lun=$frag_lun
13862         done
13863         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13864                 cleanup_130
13865                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13866         fi
13867
13868         echo "FIEMAP with continuation calls succeeded"
13869 }
13870 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13871
13872 test_130f() {
13873         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13874         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13875
13876         local fm_file=$DIR/$tfile
13877         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13878                 error "multiop create with lov_delay_create on $fm_file"
13879
13880         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13881         filefrag_extents=$(filefrag -vek $fm_file |
13882                            awk '/extents? found/ { print $2 }')
13883         if [[ "$filefrag_extents" != "0" ]]; then
13884                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13885         fi
13886
13887         rm -f $fm_file
13888 }
13889 run_test 130f "FIEMAP (unstriped file)"
13890
13891 test_130g() {
13892         local file=$DIR/$tfile
13893         local nr=$((OSTCOUNT * 100))
13894
13895         $LFS setstripe -C $nr $file ||
13896                 error "failed to setstripe -C $nr $file"
13897
13898         dd if=/dev/zero of=$file count=$nr bs=1M
13899         sync
13900         nr=$($LFS getstripe -c $file)
13901
13902         local extents=$(filefrag -v $file |
13903                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13904
13905         echo "filefrag list $extents extents in file with stripecount $nr"
13906         if (( extents < nr )); then
13907                 $LFS getstripe $file
13908                 filefrag -v $file
13909                 error "filefrag printed $extents < $nr extents"
13910         fi
13911
13912         rm -f $file
13913 }
13914 run_test 130g "FIEMAP (overstripe file)"
13915
13916 # Test for writev/readv
13917 test_131a() {
13918         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13919                 error "writev test failed"
13920         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13921                 error "readv failed"
13922         rm -f $DIR/$tfile
13923 }
13924 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13925
13926 test_131b() {
13927         local fsize=$((524288 + 1048576 + 1572864))
13928         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13929                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13930                         error "append writev test failed"
13931
13932         ((fsize += 1572864 + 1048576))
13933         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13934                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13935                         error "append writev test failed"
13936         rm -f $DIR/$tfile
13937 }
13938 run_test 131b "test append writev"
13939
13940 test_131c() {
13941         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13942         error "NOT PASS"
13943 }
13944 run_test 131c "test read/write on file w/o objects"
13945
13946 test_131d() {
13947         rwv -f $DIR/$tfile -w -n 1 1572864
13948         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13949         if [ "$NOB" != 1572864 ]; then
13950                 error "Short read filed: read $NOB bytes instead of 1572864"
13951         fi
13952         rm -f $DIR/$tfile
13953 }
13954 run_test 131d "test short read"
13955
13956 test_131e() {
13957         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13958         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13959         error "read hitting hole failed"
13960         rm -f $DIR/$tfile
13961 }
13962 run_test 131e "test read hitting hole"
13963
13964 check_stats() {
13965         local facet=$1
13966         local op=$2
13967         local want=${3:-0}
13968         local res
13969
13970         case $facet in
13971         mds*) res=$(do_facet $facet \
13972                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13973                  ;;
13974         ost*) res=$(do_facet $facet \
13975                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13976                  ;;
13977         *) error "Wrong facet '$facet'" ;;
13978         esac
13979         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13980         # if the argument $3 is zero, it means any stat increment is ok.
13981         if [[ $want -gt 0 ]]; then
13982                 local count=$(echo $res | awk '{ print $2 }')
13983                 [[ $count -ne $want ]] &&
13984                         error "The $op counter on $facet is $count, not $want"
13985         fi
13986 }
13987
13988 test_133a() {
13989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13990         remote_ost_nodsh && skip "remote OST with nodsh"
13991         remote_mds_nodsh && skip "remote MDS with nodsh"
13992         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13993                 skip_env "MDS doesn't support rename stats"
13994
13995         local testdir=$DIR/${tdir}/stats_testdir
13996
13997         mkdir -p $DIR/${tdir}
13998
13999         # clear stats.
14000         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14001         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14002
14003         # verify mdt stats first.
14004         mkdir ${testdir} || error "mkdir failed"
14005         check_stats $SINGLEMDS "mkdir" 1
14006         touch ${testdir}/${tfile} || error "touch failed"
14007         check_stats $SINGLEMDS "open" 1
14008         check_stats $SINGLEMDS "close" 1
14009         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14010                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14011                 check_stats $SINGLEMDS "mknod" 2
14012         }
14013         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14014         check_stats $SINGLEMDS "unlink" 1
14015         rm -f ${testdir}/${tfile} || error "file remove failed"
14016         check_stats $SINGLEMDS "unlink" 2
14017
14018         # remove working dir and check mdt stats again.
14019         rmdir ${testdir} || error "rmdir failed"
14020         check_stats $SINGLEMDS "rmdir" 1
14021
14022         local testdir1=$DIR/${tdir}/stats_testdir1
14023         mkdir -p ${testdir}
14024         mkdir -p ${testdir1}
14025         touch ${testdir1}/test1
14026         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14027         check_stats $SINGLEMDS "crossdir_rename" 1
14028
14029         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14030         check_stats $SINGLEMDS "samedir_rename" 1
14031
14032         rm -rf $DIR/${tdir}
14033 }
14034 run_test 133a "Verifying MDT stats ========================================"
14035
14036 test_133b() {
14037         local res
14038
14039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14040         remote_ost_nodsh && skip "remote OST with nodsh"
14041         remote_mds_nodsh && skip "remote MDS with nodsh"
14042
14043         local testdir=$DIR/${tdir}/stats_testdir
14044
14045         mkdir -p ${testdir} || error "mkdir failed"
14046         touch ${testdir}/${tfile} || error "touch failed"
14047         cancel_lru_locks mdc
14048
14049         # clear stats.
14050         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14051         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14052
14053         # extra mdt stats verification.
14054         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14055         check_stats $SINGLEMDS "setattr" 1
14056         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14057         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14058         then            # LU-1740
14059                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14060                 check_stats $SINGLEMDS "getattr" 1
14061         fi
14062         rm -rf $DIR/${tdir}
14063
14064         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14065         # so the check below is not reliable
14066         [ $MDSCOUNT -eq 1 ] || return 0
14067
14068         # Sleep to avoid a cached response.
14069         #define OBD_STATFS_CACHE_SECONDS 1
14070         sleep 2
14071         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14072         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14073         $LFS df || error "lfs failed"
14074         check_stats $SINGLEMDS "statfs" 1
14075
14076         # check aggregated statfs (LU-10018)
14077         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14078                 return 0
14079         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14080                 return 0
14081         sleep 2
14082         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14083         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14084         df $DIR
14085         check_stats $SINGLEMDS "statfs" 1
14086
14087         # We want to check that the client didn't send OST_STATFS to
14088         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14089         # extra care is needed here.
14090         if remote_mds; then
14091                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14092                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14093
14094                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14095                 [ "$res" ] && error "OST got STATFS"
14096         fi
14097
14098         return 0
14099 }
14100 run_test 133b "Verifying extra MDT stats =================================="
14101
14102 test_133c() {
14103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14104         remote_ost_nodsh && skip "remote OST with nodsh"
14105         remote_mds_nodsh && skip "remote MDS with nodsh"
14106
14107         local testdir=$DIR/$tdir/stats_testdir
14108
14109         test_mkdir -p $testdir
14110
14111         # verify obdfilter stats.
14112         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14113         sync
14114         cancel_lru_locks osc
14115         wait_delete_completed
14116
14117         # clear stats.
14118         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14119         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14120
14121         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14122                 error "dd failed"
14123         sync
14124         cancel_lru_locks osc
14125         check_stats ost1 "write" 1
14126
14127         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14128         check_stats ost1 "read" 1
14129
14130         > $testdir/$tfile || error "truncate failed"
14131         check_stats ost1 "punch" 1
14132
14133         rm -f $testdir/$tfile || error "file remove failed"
14134         wait_delete_completed
14135         check_stats ost1 "destroy" 1
14136
14137         rm -rf $DIR/$tdir
14138 }
14139 run_test 133c "Verifying OST stats ========================================"
14140
14141 order_2() {
14142         local value=$1
14143         local orig=$value
14144         local order=1
14145
14146         while [ $value -ge 2 ]; do
14147                 order=$((order*2))
14148                 value=$((value/2))
14149         done
14150
14151         if [ $orig -gt $order ]; then
14152                 order=$((order*2))
14153         fi
14154         echo $order
14155 }
14156
14157 size_in_KMGT() {
14158     local value=$1
14159     local size=('K' 'M' 'G' 'T');
14160     local i=0
14161     local size_string=$value
14162
14163     while [ $value -ge 1024 ]; do
14164         if [ $i -gt 3 ]; then
14165             #T is the biggest unit we get here, if that is bigger,
14166             #just return XXXT
14167             size_string=${value}T
14168             break
14169         fi
14170         value=$((value >> 10))
14171         if [ $value -lt 1024 ]; then
14172             size_string=${value}${size[$i]}
14173             break
14174         fi
14175         i=$((i + 1))
14176     done
14177
14178     echo $size_string
14179 }
14180
14181 get_rename_size() {
14182         local size=$1
14183         local context=${2:-.}
14184         local sample=$(do_facet $SINGLEMDS $LCTL \
14185                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14186                 grep -A1 $context |
14187                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14188         echo $sample
14189 }
14190
14191 test_133d() {
14192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14193         remote_ost_nodsh && skip "remote OST with nodsh"
14194         remote_mds_nodsh && skip "remote MDS with nodsh"
14195         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14196                 skip_env "MDS doesn't support rename stats"
14197
14198         local testdir1=$DIR/${tdir}/stats_testdir1
14199         local testdir2=$DIR/${tdir}/stats_testdir2
14200         mkdir -p $DIR/${tdir}
14201
14202         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14203
14204         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14205         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14206
14207         createmany -o $testdir1/test 512 || error "createmany failed"
14208
14209         # check samedir rename size
14210         mv ${testdir1}/test0 ${testdir1}/test_0
14211
14212         local testdir1_size=$(ls -l $DIR/${tdir} |
14213                 awk '/stats_testdir1/ {print $5}')
14214         local testdir2_size=$(ls -l $DIR/${tdir} |
14215                 awk '/stats_testdir2/ {print $5}')
14216
14217         testdir1_size=$(order_2 $testdir1_size)
14218         testdir2_size=$(order_2 $testdir2_size)
14219
14220         testdir1_size=$(size_in_KMGT $testdir1_size)
14221         testdir2_size=$(size_in_KMGT $testdir2_size)
14222
14223         echo "source rename dir size: ${testdir1_size}"
14224         echo "target rename dir size: ${testdir2_size}"
14225
14226         local cmd="do_facet $SINGLEMDS $LCTL "
14227         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14228
14229         eval $cmd || error "$cmd failed"
14230         local samedir=$($cmd | grep 'same_dir')
14231         local same_sample=$(get_rename_size $testdir1_size)
14232         [ -z "$samedir" ] && error "samedir_rename_size count error"
14233         [[ $same_sample -eq 1 ]] ||
14234                 error "samedir_rename_size error $same_sample"
14235         echo "Check same dir rename stats success"
14236
14237         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14238
14239         # check crossdir rename size
14240         mv ${testdir1}/test_0 ${testdir2}/test_0
14241
14242         testdir1_size=$(ls -l $DIR/${tdir} |
14243                 awk '/stats_testdir1/ {print $5}')
14244         testdir2_size=$(ls -l $DIR/${tdir} |
14245                 awk '/stats_testdir2/ {print $5}')
14246
14247         testdir1_size=$(order_2 $testdir1_size)
14248         testdir2_size=$(order_2 $testdir2_size)
14249
14250         testdir1_size=$(size_in_KMGT $testdir1_size)
14251         testdir2_size=$(size_in_KMGT $testdir2_size)
14252
14253         echo "source rename dir size: ${testdir1_size}"
14254         echo "target rename dir size: ${testdir2_size}"
14255
14256         eval $cmd || error "$cmd failed"
14257         local crossdir=$($cmd | grep 'crossdir')
14258         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14259         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14260         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14261         [[ $src_sample -eq 1 ]] ||
14262                 error "crossdir_rename_size error $src_sample"
14263         [[ $tgt_sample -eq 1 ]] ||
14264                 error "crossdir_rename_size error $tgt_sample"
14265         echo "Check cross dir rename stats success"
14266         rm -rf $DIR/${tdir}
14267 }
14268 run_test 133d "Verifying rename_stats ========================================"
14269
14270 test_133e() {
14271         remote_mds_nodsh && skip "remote MDS with nodsh"
14272         remote_ost_nodsh && skip "remote OST with nodsh"
14273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14274
14275         local testdir=$DIR/${tdir}/stats_testdir
14276         local ctr f0 f1 bs=32768 count=42 sum
14277
14278         mkdir -p ${testdir} || error "mkdir failed"
14279
14280         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14281
14282         for ctr in {write,read}_bytes; do
14283                 sync
14284                 cancel_lru_locks osc
14285
14286                 do_facet ost1 $LCTL set_param -n \
14287                         "obdfilter.*.exports.clear=clear"
14288
14289                 if [ $ctr = write_bytes ]; then
14290                         f0=/dev/zero
14291                         f1=${testdir}/${tfile}
14292                 else
14293                         f0=${testdir}/${tfile}
14294                         f1=/dev/null
14295                 fi
14296
14297                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14298                         error "dd failed"
14299                 sync
14300                 cancel_lru_locks osc
14301
14302                 sum=$(do_facet ost1 $LCTL get_param \
14303                         "obdfilter.*.exports.*.stats" |
14304                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14305                                 $1 == ctr { sum += $7 }
14306                                 END { printf("%0.0f", sum) }')
14307
14308                 if ((sum != bs * count)); then
14309                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14310                 fi
14311         done
14312
14313         rm -rf $DIR/${tdir}
14314 }
14315 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14316
14317 test_133f() {
14318         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14319                 skip "too old lustre for get_param -R ($facet_ver)"
14320
14321         # verifying readability.
14322         $LCTL get_param -R '*' &> /dev/null
14323
14324         # Verifing writability with badarea_io.
14325         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14326         local skipped_params='force_lbug|changelog_mask|daemon_file'
14327         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14328                 egrep -v "$skipped_params" |
14329                 xargs -n 1 find $proc_dirs -name |
14330                 xargs -n 1 badarea_io ||
14331                 error "client badarea_io failed"
14332
14333         # remount the FS in case writes/reads /proc break the FS
14334         cleanup || error "failed to unmount"
14335         setup || error "failed to setup"
14336 }
14337 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14338
14339 test_133g() {
14340         remote_mds_nodsh && skip "remote MDS with nodsh"
14341         remote_ost_nodsh && skip "remote OST with nodsh"
14342
14343         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14344         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14345         local facet
14346         for facet in mds1 ost1; do
14347                 local facet_ver=$(lustre_version_code $facet)
14348                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14349                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14350                 else
14351                         log "$facet: too old lustre for get_param -R"
14352                 fi
14353                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14354                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14355                                 tr -d = | egrep -v $skipped_params |
14356                                 xargs -n 1 find $proc_dirs -name |
14357                                 xargs -n 1 badarea_io" ||
14358                                         error "$facet badarea_io failed"
14359                 else
14360                         skip_noexit "$facet: too old lustre for get_param -R"
14361                 fi
14362         done
14363
14364         # remount the FS in case writes/reads /proc break the FS
14365         cleanup || error "failed to unmount"
14366         setup || error "failed to setup"
14367 }
14368 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14369
14370 test_133h() {
14371         remote_mds_nodsh && skip "remote MDS with nodsh"
14372         remote_ost_nodsh && skip "remote OST with nodsh"
14373         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14374                 skip "Need MDS version at least 2.9.54"
14375
14376         local facet
14377         for facet in client mds1 ost1; do
14378                 # Get the list of files that are missing the terminating newline
14379                 local plist=$(do_facet $facet
14380                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14381                 local ent
14382                 for ent in $plist; do
14383                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14384                                 awk -v FS='\v' -v RS='\v\v' \
14385                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14386                                         print FILENAME}'" 2>/dev/null)
14387                         [ -z $missing ] || {
14388                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14389                                 error "file does not end with newline: $facet-$ent"
14390                         }
14391                 done
14392         done
14393 }
14394 run_test 133h "Proc files should end with newlines"
14395
14396 test_134a() {
14397         remote_mds_nodsh && skip "remote MDS with nodsh"
14398         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14399                 skip "Need MDS version at least 2.7.54"
14400
14401         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14402         cancel_lru_locks mdc
14403
14404         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14405         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14406         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14407
14408         local nr=1000
14409         createmany -o $DIR/$tdir/f $nr ||
14410                 error "failed to create $nr files in $DIR/$tdir"
14411         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14412
14413         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14414         do_facet mds1 $LCTL set_param fail_loc=0x327
14415         do_facet mds1 $LCTL set_param fail_val=500
14416         touch $DIR/$tdir/m
14417
14418         echo "sleep 10 seconds ..."
14419         sleep 10
14420         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14421
14422         do_facet mds1 $LCTL set_param fail_loc=0
14423         do_facet mds1 $LCTL set_param fail_val=0
14424         [ $lck_cnt -lt $unused ] ||
14425                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14426
14427         rm $DIR/$tdir/m
14428         unlinkmany $DIR/$tdir/f $nr
14429 }
14430 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14431
14432 test_134b() {
14433         remote_mds_nodsh && skip "remote MDS with nodsh"
14434         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14435                 skip "Need MDS version at least 2.7.54"
14436
14437         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14438         cancel_lru_locks mdc
14439
14440         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14441                         ldlm.lock_reclaim_threshold_mb)
14442         # disable reclaim temporarily
14443         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14444
14445         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14446         do_facet mds1 $LCTL set_param fail_loc=0x328
14447         do_facet mds1 $LCTL set_param fail_val=500
14448
14449         $LCTL set_param debug=+trace
14450
14451         local nr=600
14452         createmany -o $DIR/$tdir/f $nr &
14453         local create_pid=$!
14454
14455         echo "Sleep $TIMEOUT seconds ..."
14456         sleep $TIMEOUT
14457         if ! ps -p $create_pid  > /dev/null 2>&1; then
14458                 do_facet mds1 $LCTL set_param fail_loc=0
14459                 do_facet mds1 $LCTL set_param fail_val=0
14460                 do_facet mds1 $LCTL set_param \
14461                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14462                 error "createmany finished incorrectly!"
14463         fi
14464         do_facet mds1 $LCTL set_param fail_loc=0
14465         do_facet mds1 $LCTL set_param fail_val=0
14466         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14467         wait $create_pid || return 1
14468
14469         unlinkmany $DIR/$tdir/f $nr
14470 }
14471 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14472
14473 test_135() {
14474         remote_mds_nodsh && skip "remote MDS with nodsh"
14475         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14476                 skip "Need MDS version at least 2.13.50"
14477         local fname
14478
14479         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14480
14481 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14482         #set only one record at plain llog
14483         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14484
14485         #fill already existed plain llog each 64767
14486         #wrapping whole catalog
14487         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14488
14489         createmany -o $DIR/$tdir/$tfile_ 64700
14490         for (( i = 0; i < 64700; i = i + 2 ))
14491         do
14492                 rm $DIR/$tdir/$tfile_$i &
14493                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14494                 local pid=$!
14495                 wait $pid
14496         done
14497
14498         #waiting osp synchronization
14499         wait_delete_completed
14500 }
14501 run_test 135 "Race catalog processing"
14502
14503 test_136() {
14504         remote_mds_nodsh && skip "remote MDS with nodsh"
14505         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14506                 skip "Need MDS version at least 2.13.50"
14507         local fname
14508
14509         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14510         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14511         #set only one record at plain llog
14512 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14513         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14514
14515         #fill already existed 2 plain llogs each 64767
14516         #wrapping whole catalog
14517         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14518         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14519         wait_delete_completed
14520
14521         createmany -o $DIR/$tdir/$tfile_ 10
14522         sleep 25
14523
14524         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14525         for (( i = 0; i < 10; i = i + 3 ))
14526         do
14527                 rm $DIR/$tdir/$tfile_$i &
14528                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14529                 local pid=$!
14530                 wait $pid
14531                 sleep 7
14532                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14533         done
14534
14535         #waiting osp synchronization
14536         wait_delete_completed
14537 }
14538 run_test 136 "Race catalog processing 2"
14539
14540 test_140() { #bug-17379
14541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14542
14543         test_mkdir $DIR/$tdir
14544         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14545         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14546
14547         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14548         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14549         local i=0
14550         while i=$((i + 1)); do
14551                 test_mkdir $i
14552                 cd $i || error "Changing to $i"
14553                 ln -s ../stat stat || error "Creating stat symlink"
14554                 # Read the symlink until ELOOP present,
14555                 # not LBUGing the system is considered success,
14556                 # we didn't overrun the stack.
14557                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14558                 if [ $ret -ne 0 ]; then
14559                         if [ $ret -eq 40 ]; then
14560                                 break  # -ELOOP
14561                         else
14562                                 error "Open stat symlink"
14563                                         return
14564                         fi
14565                 fi
14566         done
14567         i=$((i - 1))
14568         echo "The symlink depth = $i"
14569         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14570                 error "Invalid symlink depth"
14571
14572         # Test recursive symlink
14573         ln -s symlink_self symlink_self
14574         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14575         echo "open symlink_self returns $ret"
14576         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14577 }
14578 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14579
14580 test_150a() {
14581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14582
14583         local TF="$TMP/$tfile"
14584
14585         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14586         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14587         cp $TF $DIR/$tfile
14588         cancel_lru_locks $OSC
14589         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14590         remount_client $MOUNT
14591         df -P $MOUNT
14592         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14593
14594         $TRUNCATE $TF 6000
14595         $TRUNCATE $DIR/$tfile 6000
14596         cancel_lru_locks $OSC
14597         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14598
14599         echo "12345" >>$TF
14600         echo "12345" >>$DIR/$tfile
14601         cancel_lru_locks $OSC
14602         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14603
14604         echo "12345" >>$TF
14605         echo "12345" >>$DIR/$tfile
14606         cancel_lru_locks $OSC
14607         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14608 }
14609 run_test 150a "truncate/append tests"
14610
14611 test_150b() {
14612         check_set_fallocate_or_skip
14613
14614         touch $DIR/$tfile
14615         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14616         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14617 }
14618 run_test 150b "Verify fallocate (prealloc) functionality"
14619
14620 test_150bb() {
14621         check_set_fallocate_or_skip
14622
14623         touch $DIR/$tfile
14624         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14625         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14626         > $DIR/$tfile
14627         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14628         # precomputed md5sum for 20MB of zeroes
14629         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14630         local sum=($(md5sum $DIR/$tfile))
14631
14632         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14633
14634         check_set_fallocate 1
14635
14636         > $DIR/$tfile
14637         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14638         sum=($(md5sum $DIR/$tfile))
14639
14640         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14641 }
14642 run_test 150bb "Verify fallocate modes both zero space"
14643
14644 test_150c() {
14645         check_set_fallocate_or_skip
14646         local striping="-c2"
14647
14648         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14649         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14650         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14651         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14652         local want=$((OSTCOUNT * 1048576))
14653
14654         # Must allocate all requested space, not more than 5% extra
14655         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14656                 error "bytes $bytes is not $want"
14657
14658         rm -f $DIR/$tfile
14659
14660         echo "verify fallocate on PFL file"
14661
14662         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14663
14664         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14665                 error "Create $DIR/$tfile failed"
14666         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14667         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14668         want=$((512 * 1048576))
14669
14670         # Must allocate all requested space, not more than 5% extra
14671         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14672                 error "bytes $bytes is not $want"
14673 }
14674 run_test 150c "Verify fallocate Size and Blocks"
14675
14676 test_150d() {
14677         check_set_fallocate_or_skip
14678         local striping="-c2"
14679
14680         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14681
14682         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14683         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14684                 error "setstripe failed"
14685         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14686         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14687         local want=$((OSTCOUNT * 1048576))
14688
14689         # Must allocate all requested space, not more than 5% extra
14690         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14691                 error "bytes $bytes is not $want"
14692 }
14693 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14694
14695 test_150e() {
14696         check_set_fallocate_or_skip
14697
14698         echo "df before:"
14699         $LFS df
14700         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14701         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14702                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14703
14704         # Find OST with Minimum Size
14705         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14706                        sort -un | head -1)
14707
14708         # Get 100MB per OST of the available space to reduce run time
14709         # else 60% of the available space if we are running SLOW tests
14710         if [ $SLOW == "no" ]; then
14711                 local space=$((1024 * 100 * OSTCOUNT))
14712         else
14713                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14714         fi
14715
14716         fallocate -l${space}k $DIR/$tfile ||
14717                 error "fallocate ${space}k $DIR/$tfile failed"
14718         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14719
14720         # get size immediately after fallocate. This should be correctly
14721         # updated
14722         local size=$(stat -c '%s' $DIR/$tfile)
14723         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14724
14725         # Sleep for a while for statfs to get updated. And not pull from cache.
14726         sleep 2
14727
14728         echo "df after fallocate:"
14729         $LFS df
14730
14731         (( size / 1024 == space )) || error "size $size != requested $space"
14732         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14733                 error "used $used < space $space"
14734
14735         rm $DIR/$tfile || error "rm failed"
14736         sync
14737         wait_delete_completed
14738
14739         echo "df after unlink:"
14740         $LFS df
14741 }
14742 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14743
14744 test_150f() {
14745         local size
14746         local blocks
14747         local want_size_before=20480 # in bytes
14748         local want_blocks_before=40 # 512 sized blocks
14749         local want_blocks_after=24  # 512 sized blocks
14750         local length=$(((want_blocks_before - want_blocks_after) * 512))
14751
14752         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14753                 skip "need at least 2.14.0 for fallocate punch"
14754
14755         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14756                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14757         fi
14758
14759         check_set_fallocate_or_skip
14760         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14761
14762         [[ "x$DOM" == "xyes" ]] &&
14763                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14764
14765         echo "Verify fallocate punch: Range within the file range"
14766         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14767                 error "dd failed for bs 4096 and count 5"
14768
14769         # Call fallocate with punch range which is within the file range
14770         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14771                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14772         # client must see changes immediately after fallocate
14773         size=$(stat -c '%s' $DIR/$tfile)
14774         blocks=$(stat -c '%b' $DIR/$tfile)
14775
14776         # Verify punch worked.
14777         (( blocks == want_blocks_after )) ||
14778                 error "punch failed: blocks $blocks != $want_blocks_after"
14779
14780         (( size == want_size_before )) ||
14781                 error "punch failed: size $size != $want_size_before"
14782
14783         # Verify there is hole in file
14784         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14785         # precomputed md5sum
14786         local expect="4a9a834a2db02452929c0a348273b4aa"
14787
14788         cksum=($(md5sum $DIR/$tfile))
14789         [[ "${cksum[0]}" == "$expect" ]] ||
14790                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14791
14792         # Start second sub-case for fallocate punch.
14793         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14794         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14795                 error "dd failed for bs 4096 and count 5"
14796
14797         # Punch range less than block size will have no change in block count
14798         want_blocks_after=40  # 512 sized blocks
14799
14800         # Punch overlaps two blocks and less than blocksize
14801         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14802                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14803         size=$(stat -c '%s' $DIR/$tfile)
14804         blocks=$(stat -c '%b' $DIR/$tfile)
14805
14806         # Verify punch worked.
14807         (( blocks == want_blocks_after )) ||
14808                 error "punch failed: blocks $blocks != $want_blocks_after"
14809
14810         (( size == want_size_before )) ||
14811                 error "punch failed: size $size != $want_size_before"
14812
14813         # Verify if range is really zero'ed out. We expect Zeros.
14814         # precomputed md5sum
14815         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14816         cksum=($(md5sum $DIR/$tfile))
14817         [[ "${cksum[0]}" == "$expect" ]] ||
14818                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14819 }
14820 run_test 150f "Verify fallocate punch functionality"
14821
14822 test_150g() {
14823         local space
14824         local size
14825         local blocks
14826         local blocks_after
14827         local size_after
14828         local BS=4096 # Block size in bytes
14829
14830         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14831                 skip "need at least 2.14.0 for fallocate punch"
14832
14833         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14834                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14835         fi
14836
14837         check_set_fallocate_or_skip
14838         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14839
14840         if [[ "x$DOM" == "xyes" ]]; then
14841                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14842                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14843         else
14844                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14845                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14846         fi
14847
14848         # Get 100MB per OST of the available space to reduce run time
14849         # else 60% of the available space if we are running SLOW tests
14850         if [ $SLOW == "no" ]; then
14851                 space=$((1024 * 100 * OSTCOUNT))
14852         else
14853                 # Find OST with Minimum Size
14854                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14855                         sort -un | head -1)
14856                 echo "min size OST: $space"
14857                 space=$(((space * 60)/100 * OSTCOUNT))
14858         fi
14859         # space in 1k units, round to 4k blocks
14860         local blkcount=$((space * 1024 / $BS))
14861
14862         echo "Verify fallocate punch: Very large Range"
14863         fallocate -l${space}k $DIR/$tfile ||
14864                 error "fallocate ${space}k $DIR/$tfile failed"
14865         # write 1M at the end, start and in the middle
14866         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14867                 error "dd failed: bs $BS count 256"
14868         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14869                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14870         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14871                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14872
14873         # Gather stats.
14874         size=$(stat -c '%s' $DIR/$tfile)
14875
14876         # gather punch length.
14877         local punch_size=$((size - (BS * 2)))
14878
14879         echo "punch_size = $punch_size"
14880         echo "size - punch_size: $((size - punch_size))"
14881         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14882
14883         # Call fallocate to punch all except 2 blocks. We leave the
14884         # first and the last block
14885         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14886         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14887                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14888
14889         size_after=$(stat -c '%s' $DIR/$tfile)
14890         blocks_after=$(stat -c '%b' $DIR/$tfile)
14891
14892         # Verify punch worked.
14893         # Size should be kept
14894         (( size == size_after )) ||
14895                 error "punch failed: size $size != $size_after"
14896
14897         # two 4k data blocks to remain plus possible 1 extra extent block
14898         (( blocks_after <= ((BS / 512) * 3) )) ||
14899                 error "too many blocks remains: $blocks_after"
14900
14901         # Verify that file has hole between the first and the last blocks
14902         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14903         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14904
14905         echo "Hole at [$hole_start, $hole_end)"
14906         (( hole_start == BS )) ||
14907                 error "no hole at offset $BS after punch"
14908
14909         (( hole_end == BS + punch_size )) ||
14910                 error "data at offset $hole_end < $((BS + punch_size))"
14911 }
14912 run_test 150g "Verify fallocate punch on large range"
14913
14914 #LU-2902 roc_hit was not able to read all values from lproc
14915 function roc_hit_init() {
14916         local list=$(comma_list $(osts_nodes))
14917         local dir=$DIR/$tdir-check
14918         local file=$dir/$tfile
14919         local BEFORE
14920         local AFTER
14921         local idx
14922
14923         test_mkdir $dir
14924         #use setstripe to do a write to every ost
14925         for i in $(seq 0 $((OSTCOUNT-1))); do
14926                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14927                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14928                 idx=$(printf %04x $i)
14929                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14930                         awk '$1 == "cache_access" {sum += $7}
14931                                 END { printf("%0.0f", sum) }')
14932
14933                 cancel_lru_locks osc
14934                 cat $file >/dev/null
14935
14936                 AFTER=$(get_osd_param $list *OST*$idx stats |
14937                         awk '$1 == "cache_access" {sum += $7}
14938                                 END { printf("%0.0f", sum) }')
14939
14940                 echo BEFORE:$BEFORE AFTER:$AFTER
14941                 if ! let "AFTER - BEFORE == 4"; then
14942                         rm -rf $dir
14943                         error "roc_hit is not safe to use"
14944                 fi
14945                 rm $file
14946         done
14947
14948         rm -rf $dir
14949 }
14950
14951 function roc_hit() {
14952         local list=$(comma_list $(osts_nodes))
14953         echo $(get_osd_param $list '' stats |
14954                 awk '$1 == "cache_hit" {sum += $7}
14955                         END { printf("%0.0f", sum) }')
14956 }
14957
14958 function set_cache() {
14959         local on=1
14960
14961         if [ "$2" == "off" ]; then
14962                 on=0;
14963         fi
14964         local list=$(comma_list $(osts_nodes))
14965         set_osd_param $list '' $1_cache_enable $on
14966
14967         cancel_lru_locks osc
14968 }
14969
14970 test_151() {
14971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14972         remote_ost_nodsh && skip "remote OST with nodsh"
14973
14974         local CPAGES=3
14975         local list=$(comma_list $(osts_nodes))
14976
14977         # check whether obdfilter is cache capable at all
14978         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14979                 skip "not cache-capable obdfilter"
14980         fi
14981
14982         # check cache is enabled on all obdfilters
14983         if get_osd_param $list '' read_cache_enable | grep 0; then
14984                 skip "oss cache is disabled"
14985         fi
14986
14987         set_osd_param $list '' writethrough_cache_enable 1
14988
14989         # check write cache is enabled on all obdfilters
14990         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14991                 skip "oss write cache is NOT enabled"
14992         fi
14993
14994         roc_hit_init
14995
14996         #define OBD_FAIL_OBD_NO_LRU  0x609
14997         do_nodes $list $LCTL set_param fail_loc=0x609
14998
14999         # pages should be in the case right after write
15000         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15001                 error "dd failed"
15002
15003         local BEFORE=$(roc_hit)
15004         cancel_lru_locks osc
15005         cat $DIR/$tfile >/dev/null
15006         local AFTER=$(roc_hit)
15007
15008         do_nodes $list $LCTL set_param fail_loc=0
15009
15010         if ! let "AFTER - BEFORE == CPAGES"; then
15011                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15012         fi
15013
15014         cancel_lru_locks osc
15015         # invalidates OST cache
15016         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15017         set_osd_param $list '' read_cache_enable 0
15018         cat $DIR/$tfile >/dev/null
15019
15020         # now data shouldn't be found in the cache
15021         BEFORE=$(roc_hit)
15022         cancel_lru_locks osc
15023         cat $DIR/$tfile >/dev/null
15024         AFTER=$(roc_hit)
15025         if let "AFTER - BEFORE != 0"; then
15026                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15027         fi
15028
15029         set_osd_param $list '' read_cache_enable 1
15030         rm -f $DIR/$tfile
15031 }
15032 run_test 151 "test cache on oss and controls ==============================="
15033
15034 test_152() {
15035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15036
15037         local TF="$TMP/$tfile"
15038
15039         # simulate ENOMEM during write
15040 #define OBD_FAIL_OST_NOMEM      0x226
15041         lctl set_param fail_loc=0x80000226
15042         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15043         cp $TF $DIR/$tfile
15044         sync || error "sync failed"
15045         lctl set_param fail_loc=0
15046
15047         # discard client's cache
15048         cancel_lru_locks osc
15049
15050         # simulate ENOMEM during read
15051         lctl set_param fail_loc=0x80000226
15052         cmp $TF $DIR/$tfile || error "cmp failed"
15053         lctl set_param fail_loc=0
15054
15055         rm -f $TF
15056 }
15057 run_test 152 "test read/write with enomem ============================"
15058
15059 test_153() {
15060         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15061 }
15062 run_test 153 "test if fdatasync does not crash ======================="
15063
15064 dot_lustre_fid_permission_check() {
15065         local fid=$1
15066         local ffid=$MOUNT/.lustre/fid/$fid
15067         local test_dir=$2
15068
15069         echo "stat fid $fid"
15070         stat $ffid > /dev/null || error "stat $ffid failed."
15071         echo "touch fid $fid"
15072         touch $ffid || error "touch $ffid failed."
15073         echo "write to fid $fid"
15074         cat /etc/hosts > $ffid || error "write $ffid failed."
15075         echo "read fid $fid"
15076         diff /etc/hosts $ffid || error "read $ffid failed."
15077         echo "append write to fid $fid"
15078         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15079         echo "rename fid $fid"
15080         mv $ffid $test_dir/$tfile.1 &&
15081                 error "rename $ffid to $tfile.1 should fail."
15082         touch $test_dir/$tfile.1
15083         mv $test_dir/$tfile.1 $ffid &&
15084                 error "rename $tfile.1 to $ffid should fail."
15085         rm -f $test_dir/$tfile.1
15086         echo "truncate fid $fid"
15087         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15088         echo "link fid $fid"
15089         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15090         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15091                 echo "setfacl fid $fid"
15092                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15093                 echo "getfacl fid $fid"
15094                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15095         fi
15096         echo "unlink fid $fid"
15097         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15098         echo "mknod fid $fid"
15099         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15100
15101         fid=[0xf00000400:0x1:0x0]
15102         ffid=$MOUNT/.lustre/fid/$fid
15103
15104         echo "stat non-exist fid $fid"
15105         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15106         echo "write to non-exist fid $fid"
15107         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15108         echo "link new fid $fid"
15109         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15110
15111         mkdir -p $test_dir/$tdir
15112         touch $test_dir/$tdir/$tfile
15113         fid=$($LFS path2fid $test_dir/$tdir)
15114         rc=$?
15115         [ $rc -ne 0 ] &&
15116                 error "error: could not get fid for $test_dir/$dir/$tfile."
15117
15118         ffid=$MOUNT/.lustre/fid/$fid
15119
15120         echo "ls $fid"
15121         ls $ffid > /dev/null || error "ls $ffid failed."
15122         echo "touch $fid/$tfile.1"
15123         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15124
15125         echo "touch $MOUNT/.lustre/fid/$tfile"
15126         touch $MOUNT/.lustre/fid/$tfile && \
15127                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15128
15129         echo "setxattr to $MOUNT/.lustre/fid"
15130         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15131
15132         echo "listxattr for $MOUNT/.lustre/fid"
15133         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15134
15135         echo "delxattr from $MOUNT/.lustre/fid"
15136         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15137
15138         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15139         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15140                 error "touch invalid fid should fail."
15141
15142         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15143         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15144                 error "touch non-normal fid should fail."
15145
15146         echo "rename $tdir to $MOUNT/.lustre/fid"
15147         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15148                 error "rename to $MOUNT/.lustre/fid should fail."
15149
15150         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15151         then            # LU-3547
15152                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15153                 local new_obf_mode=777
15154
15155                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15156                 chmod $new_obf_mode $DIR/.lustre/fid ||
15157                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15158
15159                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15160                 [ $obf_mode -eq $new_obf_mode ] ||
15161                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15162
15163                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15164                 chmod $old_obf_mode $DIR/.lustre/fid ||
15165                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15166         fi
15167
15168         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15169         fid=$($LFS path2fid $test_dir/$tfile-2)
15170
15171         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15172         then # LU-5424
15173                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15174                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15175                         error "create lov data thru .lustre failed"
15176         fi
15177         echo "cp /etc/passwd $test_dir/$tfile-2"
15178         cp /etc/passwd $test_dir/$tfile-2 ||
15179                 error "copy to $test_dir/$tfile-2 failed."
15180         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15181         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15182                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15183
15184         rm -rf $test_dir/tfile.lnk
15185         rm -rf $test_dir/$tfile-2
15186 }
15187
15188 test_154A() {
15189         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15190                 skip "Need MDS version at least 2.4.1"
15191
15192         local tf=$DIR/$tfile
15193         touch $tf
15194
15195         local fid=$($LFS path2fid $tf)
15196         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15197
15198         # check that we get the same pathname back
15199         local rootpath
15200         local found
15201         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15202                 echo "$rootpath $fid"
15203                 found=$($LFS fid2path $rootpath "$fid")
15204                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15205                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15206         done
15207
15208         # check wrong root path format
15209         rootpath=$MOUNT"_wrong"
15210         found=$($LFS fid2path $rootpath "$fid")
15211         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15212 }
15213 run_test 154A "lfs path2fid and fid2path basic checks"
15214
15215 test_154B() {
15216         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15217                 skip "Need MDS version at least 2.4.1"
15218
15219         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15220         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15221         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15222         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15223
15224         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15225         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15226
15227         # check that we get the same pathname
15228         echo "PFID: $PFID, name: $name"
15229         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15230         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15231         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15232                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15233
15234         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15235 }
15236 run_test 154B "verify the ll_decode_linkea tool"
15237
15238 test_154a() {
15239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15240         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15241         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15242                 skip "Need MDS version at least 2.2.51"
15243         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15244
15245         cp /etc/hosts $DIR/$tfile
15246
15247         fid=$($LFS path2fid $DIR/$tfile)
15248         rc=$?
15249         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15250
15251         dot_lustre_fid_permission_check "$fid" $DIR ||
15252                 error "dot lustre permission check $fid failed"
15253
15254         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15255
15256         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15257
15258         touch $MOUNT/.lustre/file &&
15259                 error "creation is not allowed under .lustre"
15260
15261         mkdir $MOUNT/.lustre/dir &&
15262                 error "mkdir is not allowed under .lustre"
15263
15264         rm -rf $DIR/$tfile
15265 }
15266 run_test 154a "Open-by-FID"
15267
15268 test_154b() {
15269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15270         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15272         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15273                 skip "Need MDS version at least 2.2.51"
15274
15275         local remote_dir=$DIR/$tdir/remote_dir
15276         local MDTIDX=1
15277         local rc=0
15278
15279         mkdir -p $DIR/$tdir
15280         $LFS mkdir -i $MDTIDX $remote_dir ||
15281                 error "create remote directory failed"
15282
15283         cp /etc/hosts $remote_dir/$tfile
15284
15285         fid=$($LFS path2fid $remote_dir/$tfile)
15286         rc=$?
15287         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15288
15289         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15290                 error "dot lustre permission check $fid failed"
15291         rm -rf $DIR/$tdir
15292 }
15293 run_test 154b "Open-by-FID for remote directory"
15294
15295 test_154c() {
15296         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15297                 skip "Need MDS version at least 2.4.1"
15298
15299         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15300         local FID1=$($LFS path2fid $DIR/$tfile.1)
15301         local FID2=$($LFS path2fid $DIR/$tfile.2)
15302         local FID3=$($LFS path2fid $DIR/$tfile.3)
15303
15304         local N=1
15305         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15306                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15307                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15308                 local want=FID$N
15309                 [ "$FID" = "${!want}" ] ||
15310                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15311                 N=$((N + 1))
15312         done
15313
15314         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15315         do
15316                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15317                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15318                 N=$((N + 1))
15319         done
15320 }
15321 run_test 154c "lfs path2fid and fid2path multiple arguments"
15322
15323 test_154d() {
15324         remote_mds_nodsh && skip "remote MDS with nodsh"
15325         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15326                 skip "Need MDS version at least 2.5.53"
15327
15328         if remote_mds; then
15329                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15330         else
15331                 nid="0@lo"
15332         fi
15333         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15334         local fd
15335         local cmd
15336
15337         rm -f $DIR/$tfile
15338         touch $DIR/$tfile
15339
15340         local fid=$($LFS path2fid $DIR/$tfile)
15341         # Open the file
15342         fd=$(free_fd)
15343         cmd="exec $fd<$DIR/$tfile"
15344         eval $cmd
15345         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15346         echo "$fid_list" | grep "$fid"
15347         rc=$?
15348
15349         cmd="exec $fd>/dev/null"
15350         eval $cmd
15351         if [ $rc -ne 0 ]; then
15352                 error "FID $fid not found in open files list $fid_list"
15353         fi
15354 }
15355 run_test 154d "Verify open file fid"
15356
15357 test_154e()
15358 {
15359         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15360                 skip "Need MDS version at least 2.6.50"
15361
15362         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15363                 error ".lustre returned by readdir"
15364         fi
15365 }
15366 run_test 154e ".lustre is not returned by readdir"
15367
15368 test_154f() {
15369         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15370
15371         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15372         mkdir_on_mdt0 $DIR/$tdir
15373         # test dirs inherit from its stripe
15374         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15375         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15376         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15377         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15378         touch $DIR/f
15379
15380         # get fid of parents
15381         local FID0=$($LFS path2fid $DIR/$tdir)
15382         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15383         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15384         local FID3=$($LFS path2fid $DIR)
15385
15386         # check that path2fid --parents returns expected <parent_fid>/name
15387         # 1) test for a directory (single parent)
15388         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15389         [ "$parent" == "$FID0/foo1" ] ||
15390                 error "expected parent: $FID0/foo1, got: $parent"
15391
15392         # 2) test for a file with nlink > 1 (multiple parents)
15393         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15394         echo "$parent" | grep -F "$FID1/$tfile" ||
15395                 error "$FID1/$tfile not returned in parent list"
15396         echo "$parent" | grep -F "$FID2/link" ||
15397                 error "$FID2/link not returned in parent list"
15398
15399         # 3) get parent by fid
15400         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15401         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15402         echo "$parent" | grep -F "$FID1/$tfile" ||
15403                 error "$FID1/$tfile not returned in parent list (by fid)"
15404         echo "$parent" | grep -F "$FID2/link" ||
15405                 error "$FID2/link not returned in parent list (by fid)"
15406
15407         # 4) test for entry in root directory
15408         parent=$($LFS path2fid --parents $DIR/f)
15409         echo "$parent" | grep -F "$FID3/f" ||
15410                 error "$FID3/f not returned in parent list"
15411
15412         # 5) test it on root directory
15413         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15414                 error "$MOUNT should not have parents"
15415
15416         # enable xattr caching and check that linkea is correctly updated
15417         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15418         save_lustre_params client "llite.*.xattr_cache" > $save
15419         lctl set_param llite.*.xattr_cache 1
15420
15421         # 6.1) linkea update on rename
15422         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15423
15424         # get parents by fid
15425         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15426         # foo1 should no longer be returned in parent list
15427         echo "$parent" | grep -F "$FID1" &&
15428                 error "$FID1 should no longer be in parent list"
15429         # the new path should appear
15430         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15431                 error "$FID2/$tfile.moved is not in parent list"
15432
15433         # 6.2) linkea update on unlink
15434         rm -f $DIR/$tdir/foo2/link
15435         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15436         # foo2/link should no longer be returned in parent list
15437         echo "$parent" | grep -F "$FID2/link" &&
15438                 error "$FID2/link should no longer be in parent list"
15439         true
15440
15441         rm -f $DIR/f
15442         restore_lustre_params < $save
15443         rm -f $save
15444 }
15445 run_test 154f "get parent fids by reading link ea"
15446
15447 test_154g()
15448 {
15449         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15450         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15451            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15452                 skip "Need MDS version at least 2.6.92"
15453
15454         mkdir_on_mdt0 $DIR/$tdir
15455         llapi_fid_test -d $DIR/$tdir
15456 }
15457 run_test 154g "various llapi FID tests"
15458
15459 test_155_small_load() {
15460     local temp=$TMP/$tfile
15461     local file=$DIR/$tfile
15462
15463     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15464         error "dd of=$temp bs=6096 count=1 failed"
15465     cp $temp $file
15466     cancel_lru_locks $OSC
15467     cmp $temp $file || error "$temp $file differ"
15468
15469     $TRUNCATE $temp 6000
15470     $TRUNCATE $file 6000
15471     cmp $temp $file || error "$temp $file differ (truncate1)"
15472
15473     echo "12345" >>$temp
15474     echo "12345" >>$file
15475     cmp $temp $file || error "$temp $file differ (append1)"
15476
15477     echo "12345" >>$temp
15478     echo "12345" >>$file
15479     cmp $temp $file || error "$temp $file differ (append2)"
15480
15481     rm -f $temp $file
15482     true
15483 }
15484
15485 test_155_big_load() {
15486         remote_ost_nodsh && skip "remote OST with nodsh"
15487
15488         local temp=$TMP/$tfile
15489         local file=$DIR/$tfile
15490
15491         free_min_max
15492         local cache_size=$(do_facet ost$((MAXI+1)) \
15493                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15494         local large_file_size=$((cache_size * 2))
15495
15496         echo "OSS cache size: $cache_size KB"
15497         echo "Large file size: $large_file_size KB"
15498
15499         [ $MAXV -le $large_file_size ] &&
15500                 skip_env "max available OST size needs > $large_file_size KB"
15501
15502         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15503
15504         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15505                 error "dd of=$temp bs=$large_file_size count=1k failed"
15506         cp $temp $file
15507         ls -lh $temp $file
15508         cancel_lru_locks osc
15509         cmp $temp $file || error "$temp $file differ"
15510
15511         rm -f $temp $file
15512         true
15513 }
15514
15515 save_writethrough() {
15516         local facets=$(get_facets OST)
15517
15518         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15519 }
15520
15521 test_155a() {
15522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15523
15524         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15525
15526         save_writethrough $p
15527
15528         set_cache read on
15529         set_cache writethrough on
15530         test_155_small_load
15531         restore_lustre_params < $p
15532         rm -f $p
15533 }
15534 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15535
15536 test_155b() {
15537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15538
15539         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15540
15541         save_writethrough $p
15542
15543         set_cache read on
15544         set_cache writethrough off
15545         test_155_small_load
15546         restore_lustre_params < $p
15547         rm -f $p
15548 }
15549 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15550
15551 test_155c() {
15552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15553
15554         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15555
15556         save_writethrough $p
15557
15558         set_cache read off
15559         set_cache writethrough on
15560         test_155_small_load
15561         restore_lustre_params < $p
15562         rm -f $p
15563 }
15564 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15565
15566 test_155d() {
15567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15568
15569         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15570
15571         save_writethrough $p
15572
15573         set_cache read off
15574         set_cache writethrough off
15575         test_155_small_load
15576         restore_lustre_params < $p
15577         rm -f $p
15578 }
15579 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15580
15581 test_155e() {
15582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15583
15584         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15585
15586         save_writethrough $p
15587
15588         set_cache read on
15589         set_cache writethrough on
15590         test_155_big_load
15591         restore_lustre_params < $p
15592         rm -f $p
15593 }
15594 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15595
15596 test_155f() {
15597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15598
15599         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15600
15601         save_writethrough $p
15602
15603         set_cache read on
15604         set_cache writethrough off
15605         test_155_big_load
15606         restore_lustre_params < $p
15607         rm -f $p
15608 }
15609 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15610
15611 test_155g() {
15612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15613
15614         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15615
15616         save_writethrough $p
15617
15618         set_cache read off
15619         set_cache writethrough on
15620         test_155_big_load
15621         restore_lustre_params < $p
15622         rm -f $p
15623 }
15624 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15625
15626 test_155h() {
15627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15628
15629         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15630
15631         save_writethrough $p
15632
15633         set_cache read off
15634         set_cache writethrough off
15635         test_155_big_load
15636         restore_lustre_params < $p
15637         rm -f $p
15638 }
15639 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15640
15641 test_156() {
15642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15643         remote_ost_nodsh && skip "remote OST with nodsh"
15644         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15645                 skip "stats not implemented on old servers"
15646         [ "$ost1_FSTYPE" = "zfs" ] &&
15647                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15648
15649         local CPAGES=3
15650         local BEFORE
15651         local AFTER
15652         local file="$DIR/$tfile"
15653         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15654
15655         save_writethrough $p
15656         roc_hit_init
15657
15658         log "Turn on read and write cache"
15659         set_cache read on
15660         set_cache writethrough on
15661
15662         log "Write data and read it back."
15663         log "Read should be satisfied from the cache."
15664         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15665         BEFORE=$(roc_hit)
15666         cancel_lru_locks osc
15667         cat $file >/dev/null
15668         AFTER=$(roc_hit)
15669         if ! let "AFTER - BEFORE == CPAGES"; then
15670                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15671         else
15672                 log "cache hits: before: $BEFORE, after: $AFTER"
15673         fi
15674
15675         log "Read again; it should be satisfied from the cache."
15676         BEFORE=$AFTER
15677         cancel_lru_locks osc
15678         cat $file >/dev/null
15679         AFTER=$(roc_hit)
15680         if ! let "AFTER - BEFORE == CPAGES"; then
15681                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15682         else
15683                 log "cache hits:: before: $BEFORE, after: $AFTER"
15684         fi
15685
15686         log "Turn off the read cache and turn on the write cache"
15687         set_cache read off
15688         set_cache writethrough on
15689
15690         log "Read again; it should be satisfied from the cache."
15691         BEFORE=$(roc_hit)
15692         cancel_lru_locks osc
15693         cat $file >/dev/null
15694         AFTER=$(roc_hit)
15695         if ! let "AFTER - BEFORE == CPAGES"; then
15696                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15697         else
15698                 log "cache hits:: before: $BEFORE, after: $AFTER"
15699         fi
15700
15701         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15702                 # > 2.12.56 uses pagecache if cached
15703                 log "Read again; it should not be satisfied from the cache."
15704                 BEFORE=$AFTER
15705                 cancel_lru_locks osc
15706                 cat $file >/dev/null
15707                 AFTER=$(roc_hit)
15708                 if ! let "AFTER - BEFORE == 0"; then
15709                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15710                 else
15711                         log "cache hits:: before: $BEFORE, after: $AFTER"
15712                 fi
15713         fi
15714
15715         log "Write data and read it back."
15716         log "Read should be satisfied from the cache."
15717         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15718         BEFORE=$(roc_hit)
15719         cancel_lru_locks osc
15720         cat $file >/dev/null
15721         AFTER=$(roc_hit)
15722         if ! let "AFTER - BEFORE == CPAGES"; then
15723                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15724         else
15725                 log "cache hits:: before: $BEFORE, after: $AFTER"
15726         fi
15727
15728         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15729                 # > 2.12.56 uses pagecache if cached
15730                 log "Read again; it should not be satisfied from the cache."
15731                 BEFORE=$AFTER
15732                 cancel_lru_locks osc
15733                 cat $file >/dev/null
15734                 AFTER=$(roc_hit)
15735                 if ! let "AFTER - BEFORE == 0"; then
15736                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15737                 else
15738                         log "cache hits:: before: $BEFORE, after: $AFTER"
15739                 fi
15740         fi
15741
15742         log "Turn off read and write cache"
15743         set_cache read off
15744         set_cache writethrough off
15745
15746         log "Write data and read it back"
15747         log "It should not be satisfied from the cache."
15748         rm -f $file
15749         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15750         cancel_lru_locks osc
15751         BEFORE=$(roc_hit)
15752         cat $file >/dev/null
15753         AFTER=$(roc_hit)
15754         if ! let "AFTER - BEFORE == 0"; then
15755                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15756         else
15757                 log "cache hits:: before: $BEFORE, after: $AFTER"
15758         fi
15759
15760         log "Turn on the read cache and turn off the write cache"
15761         set_cache read on
15762         set_cache writethrough off
15763
15764         log "Write data and read it back"
15765         log "It should not be satisfied from the cache."
15766         rm -f $file
15767         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15768         BEFORE=$(roc_hit)
15769         cancel_lru_locks osc
15770         cat $file >/dev/null
15771         AFTER=$(roc_hit)
15772         if ! let "AFTER - BEFORE == 0"; then
15773                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15774         else
15775                 log "cache hits:: before: $BEFORE, after: $AFTER"
15776         fi
15777
15778         log "Read again; it should be satisfied from the cache."
15779         BEFORE=$(roc_hit)
15780         cancel_lru_locks osc
15781         cat $file >/dev/null
15782         AFTER=$(roc_hit)
15783         if ! let "AFTER - BEFORE == CPAGES"; then
15784                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15785         else
15786                 log "cache hits:: before: $BEFORE, after: $AFTER"
15787         fi
15788
15789         restore_lustre_params < $p
15790         rm -f $p $file
15791 }
15792 run_test 156 "Verification of tunables"
15793
15794 test_160a() {
15795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15796         remote_mds_nodsh && skip "remote MDS with nodsh"
15797         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15798                 skip "Need MDS version at least 2.2.0"
15799
15800         changelog_register || error "changelog_register failed"
15801         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15802         changelog_users $SINGLEMDS | grep -q $cl_user ||
15803                 error "User $cl_user not found in changelog_users"
15804
15805         mkdir_on_mdt0 $DIR/$tdir
15806
15807         # change something
15808         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15809         changelog_clear 0 || error "changelog_clear failed"
15810         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15811         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15812         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15813         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15814         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15815         rm $DIR/$tdir/pics/desktop.jpg
15816
15817         echo "verifying changelog mask"
15818         changelog_chmask "-MKDIR"
15819         changelog_chmask "-CLOSE"
15820
15821         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15822         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15823
15824         changelog_chmask "+MKDIR"
15825         changelog_chmask "+CLOSE"
15826
15827         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15828         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15829
15830         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15831         CLOSES=$(changelog_dump | grep -c "CLOSE")
15832         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15833         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15834
15835         # verify contents
15836         echo "verifying target fid"
15837         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15838         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15839         [ "$fidc" == "$fidf" ] ||
15840                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15841         echo "verifying parent fid"
15842         # The FID returned from the Changelog may be the directory shard on
15843         # a different MDT, and not the FID returned by path2fid on the parent.
15844         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15845         # since this is what will matter when recreating this file in the tree.
15846         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15847         local pathp=$($LFS fid2path $MOUNT "$fidp")
15848         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15849                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15850
15851         echo "getting records for $cl_user"
15852         changelog_users $SINGLEMDS
15853         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15854         local nclr=3
15855         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15856                 error "changelog_clear failed"
15857         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15858         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15859         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15860                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15861
15862         local min0_rec=$(changelog_users $SINGLEMDS |
15863                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15864         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15865                           awk '{ print $1; exit; }')
15866
15867         changelog_dump | tail -n 5
15868         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15869         [ $first_rec == $((min0_rec + 1)) ] ||
15870                 error "first index should be $min0_rec + 1 not $first_rec"
15871
15872         # LU-3446 changelog index reset on MDT restart
15873         local cur_rec1=$(changelog_users $SINGLEMDS |
15874                          awk '/^current.index:/ { print $NF }')
15875         changelog_clear 0 ||
15876                 error "clear all changelog records for $cl_user failed"
15877         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15878         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15879                 error "Fail to start $SINGLEMDS"
15880         local cur_rec2=$(changelog_users $SINGLEMDS |
15881                          awk '/^current.index:/ { print $NF }')
15882         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15883         [ $cur_rec1 == $cur_rec2 ] ||
15884                 error "current index should be $cur_rec1 not $cur_rec2"
15885
15886         echo "verifying users from this test are deregistered"
15887         changelog_deregister || error "changelog_deregister failed"
15888         changelog_users $SINGLEMDS | grep -q $cl_user &&
15889                 error "User '$cl_user' still in changelog_users"
15890
15891         # lctl get_param -n mdd.*.changelog_users
15892         # current_index: 144
15893         # ID    index (idle seconds)
15894         # cl3   144   (2) mask=<list>
15895         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15896                 # this is the normal case where all users were deregistered
15897                 # make sure no new records are added when no users are present
15898                 local last_rec1=$(changelog_users $SINGLEMDS |
15899                                   awk '/^current.index:/ { print $NF }')
15900                 touch $DIR/$tdir/chloe
15901                 local last_rec2=$(changelog_users $SINGLEMDS |
15902                                   awk '/^current.index:/ { print $NF }')
15903                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15904                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15905         else
15906                 # any changelog users must be leftovers from a previous test
15907                 changelog_users $SINGLEMDS
15908                 echo "other changelog users; can't verify off"
15909         fi
15910 }
15911 run_test 160a "changelog sanity"
15912
15913 test_160b() { # LU-3587
15914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15915         remote_mds_nodsh && skip "remote MDS with nodsh"
15916         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15917                 skip "Need MDS version at least 2.2.0"
15918
15919         changelog_register || error "changelog_register failed"
15920         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15921         changelog_users $SINGLEMDS | grep -q $cl_user ||
15922                 error "User '$cl_user' not found in changelog_users"
15923
15924         local longname1=$(str_repeat a 255)
15925         local longname2=$(str_repeat b 255)
15926
15927         cd $DIR
15928         echo "creating very long named file"
15929         touch $longname1 || error "create of '$longname1' failed"
15930         echo "renaming very long named file"
15931         mv $longname1 $longname2
15932
15933         changelog_dump | grep RENME | tail -n 5
15934         rm -f $longname2
15935 }
15936 run_test 160b "Verify that very long rename doesn't crash in changelog"
15937
15938 test_160c() {
15939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15940         remote_mds_nodsh && skip "remote MDS with nodsh"
15941
15942         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15943                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15944                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15945                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15946
15947         local rc=0
15948
15949         # Registration step
15950         changelog_register || error "changelog_register failed"
15951
15952         rm -rf $DIR/$tdir
15953         mkdir -p $DIR/$tdir
15954         $MCREATE $DIR/$tdir/foo_160c
15955         changelog_chmask "-TRUNC"
15956         $TRUNCATE $DIR/$tdir/foo_160c 200
15957         changelog_chmask "+TRUNC"
15958         $TRUNCATE $DIR/$tdir/foo_160c 199
15959         changelog_dump | tail -n 5
15960         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15961         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15962 }
15963 run_test 160c "verify that changelog log catch the truncate event"
15964
15965 test_160d() {
15966         remote_mds_nodsh && skip "remote MDS with nodsh"
15967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15969         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15970                 skip "Need MDS version at least 2.7.60"
15971
15972         # Registration step
15973         changelog_register || error "changelog_register failed"
15974
15975         mkdir -p $DIR/$tdir/migrate_dir
15976         changelog_clear 0 || error "changelog_clear failed"
15977
15978         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15979         changelog_dump | tail -n 5
15980         local migrates=$(changelog_dump | grep -c "MIGRT")
15981         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15982 }
15983 run_test 160d "verify that changelog log catch the migrate event"
15984
15985 test_160e() {
15986         remote_mds_nodsh && skip "remote MDS with nodsh"
15987
15988         # Create a user
15989         changelog_register || error "changelog_register failed"
15990
15991         local MDT0=$(facet_svc $SINGLEMDS)
15992         local rc
15993
15994         # No user (expect fail)
15995         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15996         rc=$?
15997         if [ $rc -eq 0 ]; then
15998                 error "Should fail without user"
15999         elif [ $rc -ne 4 ]; then
16000                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16001         fi
16002
16003         # Delete a future user (expect fail)
16004         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16005         rc=$?
16006         if [ $rc -eq 0 ]; then
16007                 error "Deleted non-existant user cl77"
16008         elif [ $rc -ne 2 ]; then
16009                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16010         fi
16011
16012         # Clear to a bad index (1 billion should be safe)
16013         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16014         rc=$?
16015
16016         if [ $rc -eq 0 ]; then
16017                 error "Successfully cleared to invalid CL index"
16018         elif [ $rc -ne 22 ]; then
16019                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16020         fi
16021 }
16022 run_test 160e "changelog negative testing (should return errors)"
16023
16024 test_160f() {
16025         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16026         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16027                 skip "Need MDS version at least 2.10.56"
16028
16029         local mdts=$(comma_list $(mdts_nodes))
16030
16031         # Create a user
16032         changelog_register || error "first changelog_register failed"
16033         changelog_register || error "second changelog_register failed"
16034         local cl_users
16035         declare -A cl_user1
16036         declare -A cl_user2
16037         local user_rec1
16038         local user_rec2
16039         local i
16040
16041         # generate some changelog records to accumulate on each MDT
16042         # use all_char because created files should be evenly distributed
16043         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16044                 error "test_mkdir $tdir failed"
16045         log "$(date +%s): creating first files"
16046         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16047                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16048                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16049         done
16050
16051         # check changelogs have been generated
16052         local start=$SECONDS
16053         local idle_time=$((MDSCOUNT * 5 + 5))
16054         local nbcl=$(changelog_dump | wc -l)
16055         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16056
16057         for param in "changelog_max_idle_time=$idle_time" \
16058                      "changelog_gc=1" \
16059                      "changelog_min_gc_interval=2" \
16060                      "changelog_min_free_cat_entries=3"; do
16061                 local MDT0=$(facet_svc $SINGLEMDS)
16062                 local var="${param%=*}"
16063                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16064
16065                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16066                 do_nodes $mdts $LCTL set_param mdd.*.$param
16067         done
16068
16069         # force cl_user2 to be idle (1st part), but also cancel the
16070         # cl_user1 records so that it is not evicted later in the test.
16071         local sleep1=$((idle_time / 2))
16072         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16073         sleep $sleep1
16074
16075         # simulate changelog catalog almost full
16076         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16077         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16078
16079         for i in $(seq $MDSCOUNT); do
16080                 cl_users=(${CL_USERS[mds$i]})
16081                 cl_user1[mds$i]="${cl_users[0]}"
16082                 cl_user2[mds$i]="${cl_users[1]}"
16083
16084                 [ -n "${cl_user1[mds$i]}" ] ||
16085                         error "mds$i: no user registered"
16086                 [ -n "${cl_user2[mds$i]}" ] ||
16087                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16088
16089                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16090                 [ -n "$user_rec1" ] ||
16091                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16092                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16093                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16094                 [ -n "$user_rec2" ] ||
16095                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16096                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16097                      "$user_rec1 + 2 == $user_rec2"
16098                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16099                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16100                               "$user_rec1 + 2, but is $user_rec2"
16101                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16102                 [ -n "$user_rec2" ] ||
16103                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16104                 [ $user_rec1 == $user_rec2 ] ||
16105                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16106                               "$user_rec1, but is $user_rec2"
16107         done
16108
16109         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16110         local sleep2=$((idle_time - (SECONDS - start) + 1))
16111         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16112         sleep $sleep2
16113
16114         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16115         # cl_user1 should be OK because it recently processed records.
16116         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16117         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16118                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16119                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16120         done
16121
16122         # ensure gc thread is done
16123         for i in $(mdts_nodes); do
16124                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16125                         error "$i: GC-thread not done"
16126         done
16127
16128         local first_rec
16129         for (( i = 1; i <= MDSCOUNT; i++ )); do
16130                 # check cl_user1 still registered
16131                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16132                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16133                 # check cl_user2 unregistered
16134                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16135                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16136
16137                 # check changelogs are present and starting at $user_rec1 + 1
16138                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16139                 [ -n "$user_rec1" ] ||
16140                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16141                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16142                             awk '{ print $1; exit; }')
16143
16144                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16145                 [ $((user_rec1 + 1)) == $first_rec ] ||
16146                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16147         done
16148 }
16149 run_test 160f "changelog garbage collect (timestamped users)"
16150
16151 test_160g() {
16152         remote_mds_nodsh && skip "remote MDS with nodsh"
16153         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16154                 skip "Need MDS version at least 2.14.55"
16155
16156         local mdts=$(comma_list $(mdts_nodes))
16157
16158         # Create a user
16159         changelog_register || error "first changelog_register failed"
16160         changelog_register || error "second changelog_register failed"
16161         local cl_users
16162         declare -A cl_user1
16163         declare -A cl_user2
16164         local user_rec1
16165         local user_rec2
16166         local i
16167
16168         # generate some changelog records to accumulate on each MDT
16169         # use all_char because created files should be evenly distributed
16170         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16171                 error "test_mkdir $tdir failed"
16172         for ((i = 0; i < MDSCOUNT; i++)); do
16173                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16174                         error "create $DIR/$tdir/d$i.1 failed"
16175         done
16176
16177         # check changelogs have been generated
16178         local nbcl=$(changelog_dump | wc -l)
16179         (( $nbcl > 0 )) || error "no changelogs found"
16180
16181         # reduce the max_idle_indexes value to make sure we exceed it
16182         for param in "changelog_max_idle_indexes=2" \
16183                      "changelog_gc=1" \
16184                      "changelog_min_gc_interval=2"; do
16185                 local MDT0=$(facet_svc $SINGLEMDS)
16186                 local var="${param%=*}"
16187                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16188
16189                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16190                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16191                         error "unable to set mdd.*.$param"
16192         done
16193
16194         local start=$SECONDS
16195         for i in $(seq $MDSCOUNT); do
16196                 cl_users=(${CL_USERS[mds$i]})
16197                 cl_user1[mds$i]="${cl_users[0]}"
16198                 cl_user2[mds$i]="${cl_users[1]}"
16199
16200                 [ -n "${cl_user1[mds$i]}" ] ||
16201                         error "mds$i: user1 is not registered"
16202                 [ -n "${cl_user2[mds$i]}" ] ||
16203                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16204
16205                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16206                 [ -n "$user_rec1" ] ||
16207                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16208                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16209                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16210                 [ -n "$user_rec2" ] ||
16211                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16212                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16213                      "$user_rec1 + 2 == $user_rec2"
16214                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16215                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16216                               "expected $user_rec1 + 2, but is $user_rec2"
16217                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16218                 [ -n "$user_rec2" ] ||
16219                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16220                 [ $user_rec1 == $user_rec2 ] ||
16221                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16222                               "expected $user_rec1, but is $user_rec2"
16223         done
16224
16225         # ensure we are past the previous changelog_min_gc_interval set above
16226         local sleep2=$((start + 2 - SECONDS))
16227         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16228         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16229         # cl_user1 should be OK because it recently processed records.
16230         for ((i = 0; i < MDSCOUNT; i++)); do
16231                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16232                         error "create $DIR/$tdir/d$i.3 failed"
16233         done
16234
16235         # ensure gc thread is done
16236         for i in $(mdts_nodes); do
16237                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16238                         error "$i: GC-thread not done"
16239         done
16240
16241         local first_rec
16242         for (( i = 1; i <= MDSCOUNT; i++ )); do
16243                 # check cl_user1 still registered
16244                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16245                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16246                 # check cl_user2 unregistered
16247                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16248                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16249
16250                 # check changelogs are present and starting at $user_rec1 + 1
16251                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16252                 [ -n "$user_rec1" ] ||
16253                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16254                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16255                             awk '{ print $1; exit; }')
16256
16257                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16258                 [ $((user_rec1 + 1)) == $first_rec ] ||
16259                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16260         done
16261 }
16262 run_test 160g "changelog garbage collect on idle records"
16263
16264 test_160h() {
16265         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16266         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16267                 skip "Need MDS version at least 2.10.56"
16268
16269         local mdts=$(comma_list $(mdts_nodes))
16270
16271         # Create a user
16272         changelog_register || error "first changelog_register failed"
16273         changelog_register || error "second changelog_register failed"
16274         local cl_users
16275         declare -A cl_user1
16276         declare -A cl_user2
16277         local user_rec1
16278         local user_rec2
16279         local i
16280
16281         # generate some changelog records to accumulate on each MDT
16282         # use all_char because created files should be evenly distributed
16283         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16284                 error "test_mkdir $tdir failed"
16285         for ((i = 0; i < MDSCOUNT; i++)); do
16286                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16287                         error "create $DIR/$tdir/d$i.1 failed"
16288         done
16289
16290         # check changelogs have been generated
16291         local nbcl=$(changelog_dump | wc -l)
16292         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16293
16294         for param in "changelog_max_idle_time=10" \
16295                      "changelog_gc=1" \
16296                      "changelog_min_gc_interval=2"; do
16297                 local MDT0=$(facet_svc $SINGLEMDS)
16298                 local var="${param%=*}"
16299                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16300
16301                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16302                 do_nodes $mdts $LCTL set_param mdd.*.$param
16303         done
16304
16305         # force cl_user2 to be idle (1st part)
16306         sleep 9
16307
16308         for i in $(seq $MDSCOUNT); do
16309                 cl_users=(${CL_USERS[mds$i]})
16310                 cl_user1[mds$i]="${cl_users[0]}"
16311                 cl_user2[mds$i]="${cl_users[1]}"
16312
16313                 [ -n "${cl_user1[mds$i]}" ] ||
16314                         error "mds$i: no user registered"
16315                 [ -n "${cl_user2[mds$i]}" ] ||
16316                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16317
16318                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16319                 [ -n "$user_rec1" ] ||
16320                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16321                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16322                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16323                 [ -n "$user_rec2" ] ||
16324                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16325                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16326                      "$user_rec1 + 2 == $user_rec2"
16327                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16328                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16329                               "$user_rec1 + 2, but is $user_rec2"
16330                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16331                 [ -n "$user_rec2" ] ||
16332                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16333                 [ $user_rec1 == $user_rec2 ] ||
16334                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16335                               "$user_rec1, but is $user_rec2"
16336         done
16337
16338         # force cl_user2 to be idle (2nd part) and to reach
16339         # changelog_max_idle_time
16340         sleep 2
16341
16342         # force each GC-thread start and block then
16343         # one per MDT/MDD, set fail_val accordingly
16344         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16345         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16346
16347         # generate more changelogs to trigger fail_loc
16348         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16349                 error "create $DIR/$tdir/${tfile}bis failed"
16350
16351         # stop MDT to stop GC-thread, should be done in back-ground as it will
16352         # block waiting for the thread to be released and exit
16353         declare -A stop_pids
16354         for i in $(seq $MDSCOUNT); do
16355                 stop mds$i &
16356                 stop_pids[mds$i]=$!
16357         done
16358
16359         for i in $(mdts_nodes); do
16360                 local facet
16361                 local nb=0
16362                 local facets=$(facets_up_on_host $i)
16363
16364                 for facet in ${facets//,/ }; do
16365                         if [[ $facet == mds* ]]; then
16366                                 nb=$((nb + 1))
16367                         fi
16368                 done
16369                 # ensure each MDS's gc threads are still present and all in "R"
16370                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16371                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16372                         error "$i: expected $nb GC-thread"
16373                 wait_update $i \
16374                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16375                         "R" 20 ||
16376                         error "$i: GC-thread not found in R-state"
16377                 # check umounts of each MDT on MDS have reached kthread_stop()
16378                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16379                         error "$i: expected $nb umount"
16380                 wait_update $i \
16381                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16382                         error "$i: umount not found in D-state"
16383         done
16384
16385         # release all GC-threads
16386         do_nodes $mdts $LCTL set_param fail_loc=0
16387
16388         # wait for MDT stop to complete
16389         for i in $(seq $MDSCOUNT); do
16390                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16391         done
16392
16393         # XXX
16394         # may try to check if any orphan changelog records are present
16395         # via ldiskfs/zfs and llog_reader...
16396
16397         # re-start/mount MDTs
16398         for i in $(seq $MDSCOUNT); do
16399                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16400                         error "Fail to start mds$i"
16401         done
16402
16403         local first_rec
16404         for i in $(seq $MDSCOUNT); do
16405                 # check cl_user1 still registered
16406                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16407                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16408                 # check cl_user2 unregistered
16409                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16410                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16411
16412                 # check changelogs are present and starting at $user_rec1 + 1
16413                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16414                 [ -n "$user_rec1" ] ||
16415                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16416                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16417                             awk '{ print $1; exit; }')
16418
16419                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16420                 [ $((user_rec1 + 1)) == $first_rec ] ||
16421                         error "mds$i: first index should be $user_rec1 + 1, " \
16422                               "but is $first_rec"
16423         done
16424 }
16425 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16426               "during mount"
16427
16428 test_160i() {
16429
16430         local mdts=$(comma_list $(mdts_nodes))
16431
16432         changelog_register || error "first changelog_register failed"
16433
16434         # generate some changelog records to accumulate on each MDT
16435         # use all_char because created files should be evenly distributed
16436         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16437                 error "test_mkdir $tdir failed"
16438         for ((i = 0; i < MDSCOUNT; i++)); do
16439                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16440                         error "create $DIR/$tdir/d$i.1 failed"
16441         done
16442
16443         # check changelogs have been generated
16444         local nbcl=$(changelog_dump | wc -l)
16445         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16446
16447         # simulate race between register and unregister
16448         # XXX as fail_loc is set per-MDS, with DNE configs the race
16449         # simulation will only occur for one MDT per MDS and for the
16450         # others the normal race scenario will take place
16451         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16452         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16453         do_nodes $mdts $LCTL set_param fail_val=1
16454
16455         # unregister 1st user
16456         changelog_deregister &
16457         local pid1=$!
16458         # wait some time for deregister work to reach race rdv
16459         sleep 2
16460         # register 2nd user
16461         changelog_register || error "2nd user register failed"
16462
16463         wait $pid1 || error "1st user deregister failed"
16464
16465         local i
16466         local last_rec
16467         declare -A LAST_REC
16468         for i in $(seq $MDSCOUNT); do
16469                 if changelog_users mds$i | grep "^cl"; then
16470                         # make sure new records are added with one user present
16471                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16472                                           awk '/^current.index:/ { print $NF }')
16473                 else
16474                         error "mds$i has no user registered"
16475                 fi
16476         done
16477
16478         # generate more changelog records to accumulate on each MDT
16479         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16480                 error "create $DIR/$tdir/${tfile}bis failed"
16481
16482         for i in $(seq $MDSCOUNT); do
16483                 last_rec=$(changelog_users $SINGLEMDS |
16484                            awk '/^current.index:/ { print $NF }')
16485                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16486                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16487                         error "changelogs are off on mds$i"
16488         done
16489 }
16490 run_test 160i "changelog user register/unregister race"
16491
16492 test_160j() {
16493         remote_mds_nodsh && skip "remote MDS with nodsh"
16494         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16495                 skip "Need MDS version at least 2.12.56"
16496
16497         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16498         stack_trap "umount $MOUNT2" EXIT
16499
16500         changelog_register || error "first changelog_register failed"
16501         stack_trap "changelog_deregister" EXIT
16502
16503         # generate some changelog
16504         # use all_char because created files should be evenly distributed
16505         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16506                 error "mkdir $tdir failed"
16507         for ((i = 0; i < MDSCOUNT; i++)); do
16508                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16509                         error "create $DIR/$tdir/d$i.1 failed"
16510         done
16511
16512         # open the changelog device
16513         exec 3>/dev/changelog-$FSNAME-MDT0000
16514         stack_trap "exec 3>&-" EXIT
16515         exec 4</dev/changelog-$FSNAME-MDT0000
16516         stack_trap "exec 4<&-" EXIT
16517
16518         # umount the first lustre mount
16519         umount $MOUNT
16520         stack_trap "mount_client $MOUNT" EXIT
16521
16522         # read changelog, which may or may not fail, but should not crash
16523         cat <&4 >/dev/null
16524
16525         # clear changelog
16526         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16527         changelog_users $SINGLEMDS | grep -q $cl_user ||
16528                 error "User $cl_user not found in changelog_users"
16529
16530         printf 'clear:'$cl_user':0' >&3
16531 }
16532 run_test 160j "client can be umounted while its chanangelog is being used"
16533
16534 test_160k() {
16535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16536         remote_mds_nodsh && skip "remote MDS with nodsh"
16537
16538         mkdir -p $DIR/$tdir/1/1
16539
16540         changelog_register || error "changelog_register failed"
16541         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16542
16543         changelog_users $SINGLEMDS | grep -q $cl_user ||
16544                 error "User '$cl_user' not found in changelog_users"
16545 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16546         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16547         rmdir $DIR/$tdir/1/1 & sleep 1
16548         mkdir $DIR/$tdir/2
16549         touch $DIR/$tdir/2/2
16550         rm -rf $DIR/$tdir/2
16551
16552         wait
16553         sleep 4
16554
16555         changelog_dump | grep rmdir || error "rmdir not recorded"
16556 }
16557 run_test 160k "Verify that changelog records are not lost"
16558
16559 # Verifies that a file passed as a parameter has recently had an operation
16560 # performed on it that has generated an MTIME changelog which contains the
16561 # correct parent FID. As files might reside on a different MDT from the
16562 # parent directory in DNE configurations, the FIDs are translated to paths
16563 # before being compared, which should be identical
16564 compare_mtime_changelog() {
16565         local file="${1}"
16566         local mdtidx
16567         local mtime
16568         local cl_fid
16569         local pdir
16570         local dir
16571
16572         mdtidx=$($LFS getstripe --mdt-index $file)
16573         mdtidx=$(printf "%04x" $mdtidx)
16574
16575         # Obtain the parent FID from the MTIME changelog
16576         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16577         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16578
16579         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16580         [ -z "$cl_fid" ] && error "parent FID not present"
16581
16582         # Verify that the path for the parent FID is the same as the path for
16583         # the test directory
16584         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16585
16586         dir=$(dirname $1)
16587
16588         [[ "${pdir%/}" == "$dir" ]] ||
16589                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16590 }
16591
16592 test_160l() {
16593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16594
16595         remote_mds_nodsh && skip "remote MDS with nodsh"
16596         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16597                 skip "Need MDS version at least 2.13.55"
16598
16599         local cl_user
16600
16601         changelog_register || error "changelog_register failed"
16602         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16603
16604         changelog_users $SINGLEMDS | grep -q $cl_user ||
16605                 error "User '$cl_user' not found in changelog_users"
16606
16607         # Clear some types so that MTIME changelogs are generated
16608         changelog_chmask "-CREAT"
16609         changelog_chmask "-CLOSE"
16610
16611         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16612
16613         # Test CL_MTIME during setattr
16614         touch $DIR/$tdir/$tfile
16615         compare_mtime_changelog $DIR/$tdir/$tfile
16616
16617         # Test CL_MTIME during close
16618         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16619         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16620 }
16621 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16622
16623 test_160m() {
16624         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16625         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16626                 skip "Need MDS version at least 2.14.51"
16627         local cl_users
16628         local cl_user1
16629         local cl_user2
16630         local pid1
16631
16632         # Create a user
16633         changelog_register || error "first changelog_register failed"
16634         changelog_register || error "second changelog_register failed"
16635
16636         cl_users=(${CL_USERS[mds1]})
16637         cl_user1="${cl_users[0]}"
16638         cl_user2="${cl_users[1]}"
16639         # generate some changelog records to accumulate on MDT0
16640         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16641         createmany -m $DIR/$tdir/$tfile 50 ||
16642                 error "create $DIR/$tdir/$tfile failed"
16643         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16644         rm -f $DIR/$tdir
16645
16646         # check changelogs have been generated
16647         local nbcl=$(changelog_dump | wc -l)
16648         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16649
16650 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16651         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16652
16653         __changelog_clear mds1 $cl_user1 +10
16654         __changelog_clear mds1 $cl_user2 0 &
16655         pid1=$!
16656         sleep 2
16657         __changelog_clear mds1 $cl_user1 0 ||
16658                 error "fail to cancel record for $cl_user1"
16659         wait $pid1
16660         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16661 }
16662 run_test 160m "Changelog clear race"
16663
16664 test_160n() {
16665         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16666         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16667                 skip "Need MDS version at least 2.14.51"
16668         local cl_users
16669         local cl_user1
16670         local cl_user2
16671         local pid1
16672         local first_rec
16673         local last_rec=0
16674
16675         # Create a user
16676         changelog_register || error "first changelog_register failed"
16677
16678         cl_users=(${CL_USERS[mds1]})
16679         cl_user1="${cl_users[0]}"
16680
16681         # generate some changelog records to accumulate on MDT0
16682         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16683         first_rec=$(changelog_users $SINGLEMDS |
16684                         awk '/^current.index:/ { print $NF }')
16685         while (( last_rec < (( first_rec + 65000)) )); do
16686                 createmany -m $DIR/$tdir/$tfile 10000 ||
16687                         error "create $DIR/$tdir/$tfile failed"
16688
16689                 for i in $(seq 0 10000); do
16690                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16691                                 > /dev/null
16692                 done
16693
16694                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16695                         error "unlinkmany failed unlink"
16696                 last_rec=$(changelog_users $SINGLEMDS |
16697                         awk '/^current.index:/ { print $NF }')
16698                 echo last record $last_rec
16699                 (( last_rec == 0 )) && error "no changelog found"
16700         done
16701
16702 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16703         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16704
16705         __changelog_clear mds1 $cl_user1 0 &
16706         pid1=$!
16707         sleep 2
16708         __changelog_clear mds1 $cl_user1 0 ||
16709                 error "fail to cancel record for $cl_user1"
16710         wait $pid1
16711         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16712 }
16713 run_test 160n "Changelog destroy race"
16714
16715 test_160o() {
16716         local mdt="$(facet_svc $SINGLEMDS)"
16717
16718         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16719         remote_mds_nodsh && skip "remote MDS with nodsh"
16720         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16721                 skip "Need MDS version at least 2.14.52"
16722
16723         changelog_register --user test_160o -m unlnk+close+open ||
16724                 error "changelog_register failed"
16725
16726         do_facet $SINGLEMDS $LCTL --device $mdt \
16727                                 changelog_register -u "Tt3_-#" &&
16728                 error "bad symbols in name should fail"
16729
16730         do_facet $SINGLEMDS $LCTL --device $mdt \
16731                                 changelog_register -u test_160o &&
16732                 error "the same name registration should fail"
16733
16734         do_facet $SINGLEMDS $LCTL --device $mdt \
16735                         changelog_register -u test_160toolongname &&
16736                 error "too long name registration should fail"
16737
16738         changelog_chmask "MARK+HSM"
16739         lctl get_param mdd.*.changelog*mask
16740         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16741         changelog_users $SINGLEMDS | grep -q $cl_user ||
16742                 error "User $cl_user not found in changelog_users"
16743         #verify username
16744         echo $cl_user | grep -q test_160o ||
16745                 error "User $cl_user has no specific name 'test160o'"
16746
16747         # change something
16748         changelog_clear 0 || error "changelog_clear failed"
16749         # generate some changelog records to accumulate on MDT0
16750         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16751         touch $DIR/$tdir/$tfile                 # open 1
16752
16753         OPENS=$(changelog_dump | grep -c "OPEN")
16754         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16755
16756         # must be no MKDIR it wasn't set as user mask
16757         MKDIR=$(changelog_dump | grep -c "MKDIR")
16758         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16759
16760         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16761                                 mdd.$mdt.changelog_current_mask -n)
16762         # register maskless user
16763         changelog_register || error "changelog_register failed"
16764         # effective mask should be not changed because it is not minimal
16765         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16766                                 mdd.$mdt.changelog_current_mask -n)
16767         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16768         # set server mask to minimal value
16769         changelog_chmask "MARK"
16770         # check effective mask again, should be treated as DEFMASK now
16771         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16772                                 mdd.$mdt.changelog_current_mask -n)
16773         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16774
16775         do_facet $SINGLEMDS $LCTL --device $mdt \
16776                                 changelog_deregister -u test_160o ||
16777                 error "cannot deregister by name"
16778 }
16779 run_test 160o "changelog user name and mask"
16780
16781 test_160p() {
16782         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16783         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16784                 skip "Need MDS version at least 2.14.51"
16785         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16786         local cl_users
16787         local cl_user1
16788         local entry_count
16789
16790         # Create a user
16791         changelog_register || error "first changelog_register failed"
16792
16793         cl_users=(${CL_USERS[mds1]})
16794         cl_user1="${cl_users[0]}"
16795
16796         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16797         createmany -m $DIR/$tdir/$tfile 50 ||
16798                 error "create $DIR/$tdir/$tfile failed"
16799         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16800         rm -rf $DIR/$tdir
16801
16802         # check changelogs have been generated
16803         entry_count=$(changelog_dump | wc -l)
16804         ((entry_count != 0)) || error "no changelog entries found"
16805
16806         # remove changelog_users and check that orphan entries are removed
16807         stop mds1
16808         local dev=$(mdsdevname 1)
16809         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16810         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16811         entry_count=$(changelog_dump | wc -l)
16812         ((entry_count == 0)) ||
16813                 error "found $entry_count changelog entries, expected none"
16814 }
16815 run_test 160p "Changelog orphan cleanup with no users"
16816
16817 test_160q() {
16818         local mdt="$(facet_svc $SINGLEMDS)"
16819         local clu
16820
16821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16822         remote_mds_nodsh && skip "remote MDS with nodsh"
16823         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16824                 skip "Need MDS version at least 2.14.54"
16825
16826         # set server mask to minimal value like server init does
16827         changelog_chmask "MARK"
16828         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16829                 error "changelog_register failed"
16830         # check effective mask again, should be treated as DEFMASK now
16831         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16832                                 mdd.$mdt.changelog_current_mask -n)
16833         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16834                 error "changelog_deregister failed"
16835         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16836 }
16837 run_test 160q "changelog effective mask is DEFMASK if not set"
16838
16839 test_160s() {
16840         remote_mds_nodsh && skip "remote MDS with nodsh"
16841         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16842                 skip "Need MDS version at least 2.14.55"
16843
16844         local mdts=$(comma_list $(mdts_nodes))
16845
16846         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16847         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16848                                        fail_val=$((24 * 3600 * 10))
16849
16850         # Create a user which is 10 days old
16851         changelog_register || error "first changelog_register failed"
16852         local cl_users
16853         declare -A cl_user1
16854         local i
16855
16856         # generate some changelog records to accumulate on each MDT
16857         # use all_char because created files should be evenly distributed
16858         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16859                 error "test_mkdir $tdir failed"
16860         for ((i = 0; i < MDSCOUNT; i++)); do
16861                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16862                         error "create $DIR/$tdir/d$i.1 failed"
16863         done
16864
16865         # check changelogs have been generated
16866         local nbcl=$(changelog_dump | wc -l)
16867         (( nbcl > 0 )) || error "no changelogs found"
16868
16869         # reduce the max_idle_indexes value to make sure we exceed it
16870         for param in "changelog_max_idle_indexes=2097446912" \
16871                      "changelog_max_idle_time=2592000" \
16872                      "changelog_gc=1" \
16873                      "changelog_min_gc_interval=2"; do
16874                 local MDT0=$(facet_svc $SINGLEMDS)
16875                 local var="${param%=*}"
16876                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16877
16878                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16879                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16880                         error "unable to set mdd.*.$param"
16881         done
16882
16883         local start=$SECONDS
16884         for i in $(seq $MDSCOUNT); do
16885                 cl_users=(${CL_USERS[mds$i]})
16886                 cl_user1[mds$i]="${cl_users[0]}"
16887
16888                 [[ -n "${cl_user1[mds$i]}" ]] ||
16889                         error "mds$i: no user registered"
16890         done
16891
16892         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16893         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16894
16895         # ensure we are past the previous changelog_min_gc_interval set above
16896         local sleep2=$((start + 2 - SECONDS))
16897         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16898
16899         # Generate one more changelog to trigger GC
16900         for ((i = 0; i < MDSCOUNT; i++)); do
16901                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16902                         error "create $DIR/$tdir/d$i.3 failed"
16903         done
16904
16905         # ensure gc thread is done
16906         for node in $(mdts_nodes); do
16907                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16908                         error "$node: GC-thread not done"
16909         done
16910
16911         do_nodes $mdts $LCTL set_param fail_loc=0
16912
16913         for (( i = 1; i <= MDSCOUNT; i++ )); do
16914                 # check cl_user1 is purged
16915                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16916                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16917         done
16918         return 0
16919 }
16920 run_test 160s "changelog garbage collect on idle records * time"
16921
16922 test_161a() {
16923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16924
16925         test_mkdir -c1 $DIR/$tdir
16926         cp /etc/hosts $DIR/$tdir/$tfile
16927         test_mkdir -c1 $DIR/$tdir/foo1
16928         test_mkdir -c1 $DIR/$tdir/foo2
16929         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16930         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16931         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16932         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16933         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16934         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16935                 $LFS fid2path $DIR $FID
16936                 error "bad link ea"
16937         fi
16938         # middle
16939         rm $DIR/$tdir/foo2/zachary
16940         # last
16941         rm $DIR/$tdir/foo2/thor
16942         # first
16943         rm $DIR/$tdir/$tfile
16944         # rename
16945         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16946         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16947                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16948         rm $DIR/$tdir/foo2/maggie
16949
16950         # overflow the EA
16951         local longname=$tfile.avg_len_is_thirty_two_
16952         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16953                 error_noexit 'failed to unlink many hardlinks'" EXIT
16954         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16955                 error "failed to hardlink many files"
16956         links=$($LFS fid2path $DIR $FID | wc -l)
16957         echo -n "${links}/1000 links in link EA"
16958         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16959 }
16960 run_test 161a "link ea sanity"
16961
16962 test_161b() {
16963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16964         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16965
16966         local MDTIDX=1
16967         local remote_dir=$DIR/$tdir/remote_dir
16968
16969         mkdir -p $DIR/$tdir
16970         $LFS mkdir -i $MDTIDX $remote_dir ||
16971                 error "create remote directory failed"
16972
16973         cp /etc/hosts $remote_dir/$tfile
16974         mkdir -p $remote_dir/foo1
16975         mkdir -p $remote_dir/foo2
16976         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16977         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16978         ln $remote_dir/$tfile $remote_dir/foo1/luna
16979         ln $remote_dir/$tfile $remote_dir/foo2/thor
16980
16981         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16982                      tr -d ']')
16983         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16984                 $LFS fid2path $DIR $FID
16985                 error "bad link ea"
16986         fi
16987         # middle
16988         rm $remote_dir/foo2/zachary
16989         # last
16990         rm $remote_dir/foo2/thor
16991         # first
16992         rm $remote_dir/$tfile
16993         # rename
16994         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16995         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16996         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16997                 $LFS fid2path $DIR $FID
16998                 error "bad link rename"
16999         fi
17000         rm $remote_dir/foo2/maggie
17001
17002         # overflow the EA
17003         local longname=filename_avg_len_is_thirty_two_
17004         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17005                 error "failed to hardlink many files"
17006         links=$($LFS fid2path $DIR $FID | wc -l)
17007         echo -n "${links}/1000 links in link EA"
17008         [[ ${links} -gt 60 ]] ||
17009                 error "expected at least 60 links in link EA"
17010         unlinkmany $remote_dir/foo2/$longname 1000 ||
17011         error "failed to unlink many hardlinks"
17012 }
17013 run_test 161b "link ea sanity under remote directory"
17014
17015 test_161c() {
17016         remote_mds_nodsh && skip "remote MDS with nodsh"
17017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17018         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17019                 skip "Need MDS version at least 2.1.5"
17020
17021         # define CLF_RENAME_LAST 0x0001
17022         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17023         changelog_register || error "changelog_register failed"
17024
17025         rm -rf $DIR/$tdir
17026         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17027         touch $DIR/$tdir/foo_161c
17028         touch $DIR/$tdir/bar_161c
17029         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17030         changelog_dump | grep RENME | tail -n 5
17031         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17032         changelog_clear 0 || error "changelog_clear failed"
17033         if [ x$flags != "x0x1" ]; then
17034                 error "flag $flags is not 0x1"
17035         fi
17036
17037         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17038         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17039         touch $DIR/$tdir/foo_161c
17040         touch $DIR/$tdir/bar_161c
17041         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17042         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17043         changelog_dump | grep RENME | tail -n 5
17044         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17045         changelog_clear 0 || error "changelog_clear failed"
17046         if [ x$flags != "x0x0" ]; then
17047                 error "flag $flags is not 0x0"
17048         fi
17049         echo "rename overwrite a target having nlink > 1," \
17050                 "changelog record has flags of $flags"
17051
17052         # rename doesn't overwrite a target (changelog flag 0x0)
17053         touch $DIR/$tdir/foo_161c
17054         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17055         changelog_dump | grep RENME | tail -n 5
17056         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17057         changelog_clear 0 || error "changelog_clear failed"
17058         if [ x$flags != "x0x0" ]; then
17059                 error "flag $flags is not 0x0"
17060         fi
17061         echo "rename doesn't overwrite a target," \
17062                 "changelog record has flags of $flags"
17063
17064         # define CLF_UNLINK_LAST 0x0001
17065         # unlink a file having nlink = 1 (changelog flag 0x1)
17066         rm -f $DIR/$tdir/foo2_161c
17067         changelog_dump | grep UNLNK | tail -n 5
17068         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17069         changelog_clear 0 || error "changelog_clear failed"
17070         if [ x$flags != "x0x1" ]; then
17071                 error "flag $flags is not 0x1"
17072         fi
17073         echo "unlink a file having nlink = 1," \
17074                 "changelog record has flags of $flags"
17075
17076         # unlink a file having nlink > 1 (changelog flag 0x0)
17077         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17078         rm -f $DIR/$tdir/foobar_161c
17079         changelog_dump | grep UNLNK | tail -n 5
17080         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17081         changelog_clear 0 || error "changelog_clear failed"
17082         if [ x$flags != "x0x0" ]; then
17083                 error "flag $flags is not 0x0"
17084         fi
17085         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17086 }
17087 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17088
17089 test_161d() {
17090         remote_mds_nodsh && skip "remote MDS with nodsh"
17091         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17092
17093         local pid
17094         local fid
17095
17096         changelog_register || error "changelog_register failed"
17097
17098         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17099         # interfer with $MOUNT/.lustre/fid/ access
17100         mkdir $DIR/$tdir
17101         [[ $? -eq 0 ]] || error "mkdir failed"
17102
17103         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17104         $LCTL set_param fail_loc=0x8000140c
17105         # 5s pause
17106         $LCTL set_param fail_val=5
17107
17108         # create file
17109         echo foofoo > $DIR/$tdir/$tfile &
17110         pid=$!
17111
17112         # wait for create to be delayed
17113         sleep 2
17114
17115         ps -p $pid
17116         [[ $? -eq 0 ]] || error "create should be blocked"
17117
17118         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17119         stack_trap "rm -f $tempfile"
17120         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17121         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17122         # some delay may occur during ChangeLog publishing and file read just
17123         # above, that could allow file write to happen finally
17124         [[ -s $tempfile ]] && echo "file should be empty"
17125
17126         $LCTL set_param fail_loc=0
17127
17128         wait $pid
17129         [[ $? -eq 0 ]] || error "create failed"
17130 }
17131 run_test 161d "create with concurrent .lustre/fid access"
17132
17133 check_path() {
17134         local expected="$1"
17135         shift
17136         local fid="$2"
17137
17138         local path
17139         path=$($LFS fid2path "$@")
17140         local rc=$?
17141
17142         if [ $rc -ne 0 ]; then
17143                 error "path looked up of '$expected' failed: rc=$rc"
17144         elif [ "$path" != "$expected" ]; then
17145                 error "path looked up '$path' instead of '$expected'"
17146         else
17147                 echo "FID '$fid' resolves to path '$path' as expected"
17148         fi
17149 }
17150
17151 test_162a() { # was test_162
17152         test_mkdir -p -c1 $DIR/$tdir/d2
17153         touch $DIR/$tdir/d2/$tfile
17154         touch $DIR/$tdir/d2/x1
17155         touch $DIR/$tdir/d2/x2
17156         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17157         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17158         # regular file
17159         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17160         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17161
17162         # softlink
17163         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17164         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17165         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17166
17167         # softlink to wrong file
17168         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17169         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17170         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17171
17172         # hardlink
17173         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17174         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17175         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17176         # fid2path dir/fsname should both work
17177         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17178         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17179
17180         # hardlink count: check that there are 2 links
17181         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17182         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17183
17184         # hardlink indexing: remove the first link
17185         rm $DIR/$tdir/d2/p/q/r/hlink
17186         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17187 }
17188 run_test 162a "path lookup sanity"
17189
17190 test_162b() {
17191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17192         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17193
17194         mkdir $DIR/$tdir
17195         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17196                                 error "create striped dir failed"
17197
17198         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17199                                         tail -n 1 | awk '{print $2}')
17200         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17201
17202         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17203         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17204
17205         # regular file
17206         for ((i=0;i<5;i++)); do
17207                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17208                         error "get fid for f$i failed"
17209                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17210
17211                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17212                         error "get fid for d$i failed"
17213                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17214         done
17215
17216         return 0
17217 }
17218 run_test 162b "striped directory path lookup sanity"
17219
17220 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17221 test_162c() {
17222         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17223                 skip "Need MDS version at least 2.7.51"
17224
17225         local lpath=$tdir.local
17226         local rpath=$tdir.remote
17227
17228         test_mkdir $DIR/$lpath
17229         test_mkdir $DIR/$rpath
17230
17231         for ((i = 0; i <= 101; i++)); do
17232                 lpath="$lpath/$i"
17233                 mkdir $DIR/$lpath
17234                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17235                         error "get fid for local directory $DIR/$lpath failed"
17236                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17237
17238                 rpath="$rpath/$i"
17239                 test_mkdir $DIR/$rpath
17240                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17241                         error "get fid for remote directory $DIR/$rpath failed"
17242                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17243         done
17244
17245         return 0
17246 }
17247 run_test 162c "fid2path works with paths 100 or more directories deep"
17248
17249 oalr_event_count() {
17250         local event="${1}"
17251         local trace="${2}"
17252
17253         awk -v name="${FSNAME}-OST0000" \
17254             -v event="${event}" \
17255             '$1 == "TRACE" && $2 == event && $3 == name' \
17256             "${trace}" |
17257         wc -l
17258 }
17259
17260 oalr_expect_event_count() {
17261         local event="${1}"
17262         local trace="${2}"
17263         local expect="${3}"
17264         local count
17265
17266         count=$(oalr_event_count "${event}" "${trace}")
17267         if ((count == expect)); then
17268                 return 0
17269         fi
17270
17271         error_noexit "${event} event count was '${count}', expected ${expect}"
17272         cat "${trace}" >&2
17273         exit 1
17274 }
17275
17276 cleanup_165() {
17277         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17278         stop ost1
17279         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17280 }
17281
17282 setup_165() {
17283         sync # Flush previous IOs so we can count log entries.
17284         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17285         stack_trap cleanup_165 EXIT
17286 }
17287
17288 test_165a() {
17289         local trace="/tmp/${tfile}.trace"
17290         local rc
17291         local count
17292
17293         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17294                 skip "OFD access log unsupported"
17295
17296         setup_165
17297         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17298         sleep 5
17299
17300         do_facet ost1 ofd_access_log_reader --list
17301         stop ost1
17302
17303         do_facet ost1 killall -TERM ofd_access_log_reader
17304         wait
17305         rc=$?
17306
17307         if ((rc != 0)); then
17308                 error "ofd_access_log_reader exited with rc = '${rc}'"
17309         fi
17310
17311         # Parse trace file for discovery events:
17312         oalr_expect_event_count alr_log_add "${trace}" 1
17313         oalr_expect_event_count alr_log_eof "${trace}" 1
17314         oalr_expect_event_count alr_log_free "${trace}" 1
17315 }
17316 run_test 165a "ofd access log discovery"
17317
17318 test_165b() {
17319         local trace="/tmp/${tfile}.trace"
17320         local file="${DIR}/${tfile}"
17321         local pfid1
17322         local pfid2
17323         local -a entry
17324         local rc
17325         local count
17326         local size
17327         local flags
17328
17329         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17330                 skip "OFD access log unsupported"
17331
17332         setup_165
17333         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17334         sleep 5
17335
17336         do_facet ost1 ofd_access_log_reader --list
17337
17338         lfs setstripe -c 1 -i 0 "${file}"
17339         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17340                 error "cannot create '${file}'"
17341
17342         sleep 5
17343         do_facet ost1 killall -TERM ofd_access_log_reader
17344         wait
17345         rc=$?
17346
17347         if ((rc != 0)); then
17348                 error "ofd_access_log_reader exited with rc = '${rc}'"
17349         fi
17350
17351         oalr_expect_event_count alr_log_entry "${trace}" 1
17352
17353         pfid1=$($LFS path2fid "${file}")
17354
17355         # 1     2             3   4    5     6   7    8    9     10
17356         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17357         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17358
17359         echo "entry = '${entry[*]}'" >&2
17360
17361         pfid2=${entry[4]}
17362         if [[ "${pfid1}" != "${pfid2}" ]]; then
17363                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17364         fi
17365
17366         size=${entry[8]}
17367         if ((size != 1048576)); then
17368                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17369         fi
17370
17371         flags=${entry[10]}
17372         if [[ "${flags}" != "w" ]]; then
17373                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17374         fi
17375
17376         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17377         sleep 5
17378
17379         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17380                 error "cannot read '${file}'"
17381         sleep 5
17382
17383         do_facet ost1 killall -TERM ofd_access_log_reader
17384         wait
17385         rc=$?
17386
17387         if ((rc != 0)); then
17388                 error "ofd_access_log_reader exited with rc = '${rc}'"
17389         fi
17390
17391         oalr_expect_event_count alr_log_entry "${trace}" 1
17392
17393         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17394         echo "entry = '${entry[*]}'" >&2
17395
17396         pfid2=${entry[4]}
17397         if [[ "${pfid1}" != "${pfid2}" ]]; then
17398                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17399         fi
17400
17401         size=${entry[8]}
17402         if ((size != 524288)); then
17403                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17404         fi
17405
17406         flags=${entry[10]}
17407         if [[ "${flags}" != "r" ]]; then
17408                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17409         fi
17410 }
17411 run_test 165b "ofd access log entries are produced and consumed"
17412
17413 test_165c() {
17414         local trace="/tmp/${tfile}.trace"
17415         local file="${DIR}/${tdir}/${tfile}"
17416
17417         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17418                 skip "OFD access log unsupported"
17419
17420         test_mkdir "${DIR}/${tdir}"
17421
17422         setup_165
17423         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17424         sleep 5
17425
17426         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17427
17428         # 4096 / 64 = 64. Create twice as many entries.
17429         for ((i = 0; i < 128; i++)); do
17430                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17431                         error "cannot create file"
17432         done
17433
17434         sync
17435
17436         do_facet ost1 killall -TERM ofd_access_log_reader
17437         wait
17438         rc=$?
17439         if ((rc != 0)); then
17440                 error "ofd_access_log_reader exited with rc = '${rc}'"
17441         fi
17442
17443         unlinkmany  "${file}-%d" 128
17444 }
17445 run_test 165c "full ofd access logs do not block IOs"
17446
17447 oal_get_read_count() {
17448         local stats="$1"
17449
17450         # STATS lustre-OST0001 alr_read_count 1
17451
17452         do_facet ost1 cat "${stats}" |
17453         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17454              END { print count; }'
17455 }
17456
17457 oal_expect_read_count() {
17458         local stats="$1"
17459         local count
17460         local expect="$2"
17461
17462         # Ask ofd_access_log_reader to write stats.
17463         do_facet ost1 killall -USR1 ofd_access_log_reader
17464
17465         # Allow some time for things to happen.
17466         sleep 1
17467
17468         count=$(oal_get_read_count "${stats}")
17469         if ((count == expect)); then
17470                 return 0
17471         fi
17472
17473         error_noexit "bad read count, got ${count}, expected ${expect}"
17474         do_facet ost1 cat "${stats}" >&2
17475         exit 1
17476 }
17477
17478 test_165d() {
17479         local stats="/tmp/${tfile}.stats"
17480         local file="${DIR}/${tdir}/${tfile}"
17481         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17482
17483         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17484                 skip "OFD access log unsupported"
17485
17486         test_mkdir "${DIR}/${tdir}"
17487
17488         setup_165
17489         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17490         sleep 5
17491
17492         lfs setstripe -c 1 -i 0 "${file}"
17493
17494         do_facet ost1 lctl set_param "${param}=rw"
17495         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17496                 error "cannot create '${file}'"
17497         oal_expect_read_count "${stats}" 1
17498
17499         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17500                 error "cannot read '${file}'"
17501         oal_expect_read_count "${stats}" 2
17502
17503         do_facet ost1 lctl set_param "${param}=r"
17504         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17505                 error "cannot create '${file}'"
17506         oal_expect_read_count "${stats}" 2
17507
17508         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17509                 error "cannot read '${file}'"
17510         oal_expect_read_count "${stats}" 3
17511
17512         do_facet ost1 lctl set_param "${param}=w"
17513         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17514                 error "cannot create '${file}'"
17515         oal_expect_read_count "${stats}" 4
17516
17517         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17518                 error "cannot read '${file}'"
17519         oal_expect_read_count "${stats}" 4
17520
17521         do_facet ost1 lctl set_param "${param}=0"
17522         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17523                 error "cannot create '${file}'"
17524         oal_expect_read_count "${stats}" 4
17525
17526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17527                 error "cannot read '${file}'"
17528         oal_expect_read_count "${stats}" 4
17529
17530         do_facet ost1 killall -TERM ofd_access_log_reader
17531         wait
17532         rc=$?
17533         if ((rc != 0)); then
17534                 error "ofd_access_log_reader exited with rc = '${rc}'"
17535         fi
17536 }
17537 run_test 165d "ofd_access_log mask works"
17538
17539 test_165e() {
17540         local stats="/tmp/${tfile}.stats"
17541         local file0="${DIR}/${tdir}-0/${tfile}"
17542         local file1="${DIR}/${tdir}-1/${tfile}"
17543
17544         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17545                 skip "OFD access log unsupported"
17546
17547         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17548
17549         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17550         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17551
17552         lfs setstripe -c 1 -i 0 "${file0}"
17553         lfs setstripe -c 1 -i 0 "${file1}"
17554
17555         setup_165
17556         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17557         sleep 5
17558
17559         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17560                 error "cannot create '${file0}'"
17561         sync
17562         oal_expect_read_count "${stats}" 0
17563
17564         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17565                 error "cannot create '${file1}'"
17566         sync
17567         oal_expect_read_count "${stats}" 1
17568
17569         do_facet ost1 killall -TERM ofd_access_log_reader
17570         wait
17571         rc=$?
17572         if ((rc != 0)); then
17573                 error "ofd_access_log_reader exited with rc = '${rc}'"
17574         fi
17575 }
17576 run_test 165e "ofd_access_log MDT index filter works"
17577
17578 test_165f() {
17579         local trace="/tmp/${tfile}.trace"
17580         local rc
17581         local count
17582
17583         setup_165
17584         do_facet ost1 timeout 60 ofd_access_log_reader \
17585                 --exit-on-close --debug=- --trace=- > "${trace}" &
17586         sleep 5
17587         stop ost1
17588
17589         wait
17590         rc=$?
17591
17592         if ((rc != 0)); then
17593                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17594                 cat "${trace}"
17595                 exit 1
17596         fi
17597 }
17598 run_test 165f "ofd_access_log_reader --exit-on-close works"
17599
17600 test_169() {
17601         # do directio so as not to populate the page cache
17602         log "creating a 10 Mb file"
17603         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17604                 error "multiop failed while creating a file"
17605         log "starting reads"
17606         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17607         log "truncating the file"
17608         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17609                 error "multiop failed while truncating the file"
17610         log "killing dd"
17611         kill %+ || true # reads might have finished
17612         echo "wait until dd is finished"
17613         wait
17614         log "removing the temporary file"
17615         rm -rf $DIR/$tfile || error "tmp file removal failed"
17616 }
17617 run_test 169 "parallel read and truncate should not deadlock"
17618
17619 test_170() {
17620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17621
17622         $LCTL clear     # bug 18514
17623         $LCTL debug_daemon start $TMP/${tfile}_log_good
17624         touch $DIR/$tfile
17625         $LCTL debug_daemon stop
17626         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17627                 error "sed failed to read log_good"
17628
17629         $LCTL debug_daemon start $TMP/${tfile}_log_good
17630         rm -rf $DIR/$tfile
17631         $LCTL debug_daemon stop
17632
17633         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17634                error "lctl df log_bad failed"
17635
17636         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17637         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17638
17639         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17640         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17641
17642         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17643                 error "bad_line good_line1 good_line2 are empty"
17644
17645         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17646         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17647         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17648
17649         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17650         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17651         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17652
17653         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17654                 error "bad_line_new good_line_new are empty"
17655
17656         local expected_good=$((good_line1 + good_line2*2))
17657
17658         rm -f $TMP/${tfile}*
17659         # LU-231, short malformed line may not be counted into bad lines
17660         if [ $bad_line -ne $bad_line_new ] &&
17661                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17662                 error "expected $bad_line bad lines, but got $bad_line_new"
17663                 return 1
17664         fi
17665
17666         if [ $expected_good -ne $good_line_new ]; then
17667                 error "expected $expected_good good lines, but got $good_line_new"
17668                 return 2
17669         fi
17670         true
17671 }
17672 run_test 170 "test lctl df to handle corrupted log ====================="
17673
17674 test_171() { # bug20592
17675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17676
17677         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17678         $LCTL set_param fail_loc=0x50e
17679         $LCTL set_param fail_val=3000
17680         multiop_bg_pause $DIR/$tfile O_s || true
17681         local MULTIPID=$!
17682         kill -USR1 $MULTIPID
17683         # cause log dump
17684         sleep 3
17685         wait $MULTIPID
17686         if dmesg | grep "recursive fault"; then
17687                 error "caught a recursive fault"
17688         fi
17689         $LCTL set_param fail_loc=0
17690         true
17691 }
17692 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17693
17694 # it would be good to share it with obdfilter-survey/iokit-libecho code
17695 setup_obdecho_osc () {
17696         local rc=0
17697         local ost_nid=$1
17698         local obdfilter_name=$2
17699         echo "Creating new osc for $obdfilter_name on $ost_nid"
17700         # make sure we can find loopback nid
17701         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17702
17703         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17704                            ${obdfilter_name}_osc_UUID || rc=2; }
17705         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17706                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17707         return $rc
17708 }
17709
17710 cleanup_obdecho_osc () {
17711         local obdfilter_name=$1
17712         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17713         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17714         return 0
17715 }
17716
17717 obdecho_test() {
17718         local OBD=$1
17719         local node=$2
17720         local pages=${3:-64}
17721         local rc=0
17722         local id
17723
17724         local count=10
17725         local obd_size=$(get_obd_size $node $OBD)
17726         local page_size=$(get_page_size $node)
17727         if [[ -n "$obd_size" ]]; then
17728                 local new_count=$((obd_size / (pages * page_size / 1024)))
17729                 [[ $new_count -ge $count ]] || count=$new_count
17730         fi
17731
17732         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17733         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17734                            rc=2; }
17735         if [ $rc -eq 0 ]; then
17736             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17737             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17738         fi
17739         echo "New object id is $id"
17740         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17741                            rc=4; }
17742         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17743                            "test_brw $count w v $pages $id" || rc=4; }
17744         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17745                            rc=4; }
17746         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17747                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17748         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17749                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17750         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17751         return $rc
17752 }
17753
17754 test_180a() {
17755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17756
17757         if ! [ -d /sys/fs/lustre/echo_client ] &&
17758            ! module_loaded obdecho; then
17759                 load_module obdecho/obdecho &&
17760                         stack_trap "rmmod obdecho" EXIT ||
17761                         error "unable to load obdecho on client"
17762         fi
17763
17764         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17765         local host=$($LCTL get_param -n osc.$osc.import |
17766                      awk '/current_connection:/ { print $2 }' )
17767         local target=$($LCTL get_param -n osc.$osc.import |
17768                        awk '/target:/ { print $2 }' )
17769         target=${target%_UUID}
17770
17771         if [ -n "$target" ]; then
17772                 setup_obdecho_osc $host $target &&
17773                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17774                         { error "obdecho setup failed with $?"; return; }
17775
17776                 obdecho_test ${target}_osc client ||
17777                         error "obdecho_test failed on ${target}_osc"
17778         else
17779                 $LCTL get_param osc.$osc.import
17780                 error "there is no osc.$osc.import target"
17781         fi
17782 }
17783 run_test 180a "test obdecho on osc"
17784
17785 test_180b() {
17786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17787         remote_ost_nodsh && skip "remote OST with nodsh"
17788
17789         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17790                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17791                 error "failed to load module obdecho"
17792
17793         local target=$(do_facet ost1 $LCTL dl |
17794                        awk '/obdfilter/ { print $4; exit; }')
17795
17796         if [ -n "$target" ]; then
17797                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17798         else
17799                 do_facet ost1 $LCTL dl
17800                 error "there is no obdfilter target on ost1"
17801         fi
17802 }
17803 run_test 180b "test obdecho directly on obdfilter"
17804
17805 test_180c() { # LU-2598
17806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17807         remote_ost_nodsh && skip "remote OST with nodsh"
17808         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17809                 skip "Need MDS version at least 2.4.0"
17810
17811         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17812                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17813                 error "failed to load module obdecho"
17814
17815         local target=$(do_facet ost1 $LCTL dl |
17816                        awk '/obdfilter/ { print $4; exit; }')
17817
17818         if [ -n "$target" ]; then
17819                 local pages=16384 # 64MB bulk I/O RPC size
17820
17821                 obdecho_test "$target" ost1 "$pages" ||
17822                         error "obdecho_test with pages=$pages failed with $?"
17823         else
17824                 do_facet ost1 $LCTL dl
17825                 error "there is no obdfilter target on ost1"
17826         fi
17827 }
17828 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17829
17830 test_181() { # bug 22177
17831         test_mkdir $DIR/$tdir
17832         # create enough files to index the directory
17833         createmany -o $DIR/$tdir/foobar 4000
17834         # print attributes for debug purpose
17835         lsattr -d .
17836         # open dir
17837         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17838         MULTIPID=$!
17839         # remove the files & current working dir
17840         unlinkmany $DIR/$tdir/foobar 4000
17841         rmdir $DIR/$tdir
17842         kill -USR1 $MULTIPID
17843         wait $MULTIPID
17844         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17845         return 0
17846 }
17847 run_test 181 "Test open-unlinked dir ========================"
17848
17849 test_182a() {
17850         local fcount=1000
17851         local tcount=10
17852
17853         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17854
17855         $LCTL set_param mdc.*.rpc_stats=clear
17856
17857         for (( i = 0; i < $tcount; i++ )) ; do
17858                 mkdir $DIR/$tdir/$i
17859         done
17860
17861         for (( i = 0; i < $tcount; i++ )) ; do
17862                 createmany -o $DIR/$tdir/$i/f- $fcount &
17863         done
17864         wait
17865
17866         for (( i = 0; i < $tcount; i++ )) ; do
17867                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17868         done
17869         wait
17870
17871         $LCTL get_param mdc.*.rpc_stats
17872
17873         rm -rf $DIR/$tdir
17874 }
17875 run_test 182a "Test parallel modify metadata operations from mdc"
17876
17877 test_182b() {
17878         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17879         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17880         local dcount=1000
17881         local tcount=10
17882         local stime
17883         local etime
17884         local delta
17885
17886         do_facet mds1 $LCTL list_param \
17887                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17888                 skip "MDS lacks parallel RPC handling"
17889
17890         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17891
17892         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17893                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17894
17895         stime=$(date +%s)
17896         createmany -i 0 -d $DIR/$tdir/t- $tcount
17897
17898         for (( i = 0; i < $tcount; i++ )) ; do
17899                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17900         done
17901         wait
17902         etime=$(date +%s)
17903         delta=$((etime - stime))
17904         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17905
17906         stime=$(date +%s)
17907         for (( i = 0; i < $tcount; i++ )) ; do
17908                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17909         done
17910         wait
17911         etime=$(date +%s)
17912         delta=$((etime - stime))
17913         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17914
17915         rm -rf $DIR/$tdir
17916
17917         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17918
17919         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17920
17921         stime=$(date +%s)
17922         createmany -i 0 -d $DIR/$tdir/t- $tcount
17923
17924         for (( i = 0; i < $tcount; i++ )) ; do
17925                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17926         done
17927         wait
17928         etime=$(date +%s)
17929         delta=$((etime - stime))
17930         echo "Time for file creation $delta sec for 1 RPC sent at a time"
17931
17932         stime=$(date +%s)
17933         for (( i = 0; i < $tcount; i++ )) ; do
17934                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
17935         done
17936         wait
17937         etime=$(date +%s)
17938         delta=$((etime - stime))
17939         echo "Time for file removal $delta sec for 1 RPC sent at a time"
17940
17941         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
17942 }
17943 run_test 182b "Test parallel modify metadata operations from osp"
17944
17945 test_183() { # LU-2275
17946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17947         remote_mds_nodsh && skip "remote MDS with nodsh"
17948         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17949                 skip "Need MDS version at least 2.3.56"
17950
17951         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17952         echo aaa > $DIR/$tdir/$tfile
17953
17954 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17955         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17956
17957         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17958         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17959
17960         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17961
17962         # Flush negative dentry cache
17963         touch $DIR/$tdir/$tfile
17964
17965         # We are not checking for any leaked references here, they'll
17966         # become evident next time we do cleanup with module unload.
17967         rm -rf $DIR/$tdir
17968 }
17969 run_test 183 "No crash or request leak in case of strange dispositions ========"
17970
17971 # test suite 184 is for LU-2016, LU-2017
17972 test_184a() {
17973         check_swap_layouts_support
17974
17975         dir0=$DIR/$tdir/$testnum
17976         test_mkdir -p -c1 $dir0
17977         ref1=/etc/passwd
17978         ref2=/etc/group
17979         file1=$dir0/f1
17980         file2=$dir0/f2
17981         $LFS setstripe -c1 $file1
17982         cp $ref1 $file1
17983         $LFS setstripe -c2 $file2
17984         cp $ref2 $file2
17985         gen1=$($LFS getstripe -g $file1)
17986         gen2=$($LFS getstripe -g $file2)
17987
17988         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17989         gen=$($LFS getstripe -g $file1)
17990         [[ $gen1 != $gen ]] ||
17991                 error "Layout generation on $file1 does not change"
17992         gen=$($LFS getstripe -g $file2)
17993         [[ $gen2 != $gen ]] ||
17994                 error "Layout generation on $file2 does not change"
17995
17996         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17997         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17998
17999         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18000 }
18001 run_test 184a "Basic layout swap"
18002
18003 test_184b() {
18004         check_swap_layouts_support
18005
18006         dir0=$DIR/$tdir/$testnum
18007         mkdir -p $dir0 || error "creating dir $dir0"
18008         file1=$dir0/f1
18009         file2=$dir0/f2
18010         file3=$dir0/f3
18011         dir1=$dir0/d1
18012         dir2=$dir0/d2
18013         mkdir $dir1 $dir2
18014         $LFS setstripe -c1 $file1
18015         $LFS setstripe -c2 $file2
18016         $LFS setstripe -c1 $file3
18017         chown $RUNAS_ID $file3
18018         gen1=$($LFS getstripe -g $file1)
18019         gen2=$($LFS getstripe -g $file2)
18020
18021         $LFS swap_layouts $dir1 $dir2 &&
18022                 error "swap of directories layouts should fail"
18023         $LFS swap_layouts $dir1 $file1 &&
18024                 error "swap of directory and file layouts should fail"
18025         $RUNAS $LFS swap_layouts $file1 $file2 &&
18026                 error "swap of file we cannot write should fail"
18027         $LFS swap_layouts $file1 $file3 &&
18028                 error "swap of file with different owner should fail"
18029         /bin/true # to clear error code
18030 }
18031 run_test 184b "Forbidden layout swap (will generate errors)"
18032
18033 test_184c() {
18034         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18035         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18036         check_swap_layouts_support
18037         check_swap_layout_no_dom $DIR
18038
18039         local dir0=$DIR/$tdir/$testnum
18040         mkdir -p $dir0 || error "creating dir $dir0"
18041
18042         local ref1=$dir0/ref1
18043         local ref2=$dir0/ref2
18044         local file1=$dir0/file1
18045         local file2=$dir0/file2
18046         # create a file large enough for the concurrent test
18047         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18048         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18049         echo "ref file size: ref1($(stat -c %s $ref1))," \
18050              "ref2($(stat -c %s $ref2))"
18051
18052         cp $ref2 $file2
18053         dd if=$ref1 of=$file1 bs=16k &
18054         local DD_PID=$!
18055
18056         # Make sure dd starts to copy file, but wait at most 5 seconds
18057         local loops=0
18058         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18059
18060         $LFS swap_layouts $file1 $file2
18061         local rc=$?
18062         wait $DD_PID
18063         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18064         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18065
18066         # how many bytes copied before swapping layout
18067         local copied=$(stat -c %s $file2)
18068         local remaining=$(stat -c %s $ref1)
18069         remaining=$((remaining - copied))
18070         echo "Copied $copied bytes before swapping layout..."
18071
18072         cmp -n $copied $file1 $ref2 | grep differ &&
18073                 error "Content mismatch [0, $copied) of ref2 and file1"
18074         cmp -n $copied $file2 $ref1 ||
18075                 error "Content mismatch [0, $copied) of ref1 and file2"
18076         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18077                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18078
18079         # clean up
18080         rm -f $ref1 $ref2 $file1 $file2
18081 }
18082 run_test 184c "Concurrent write and layout swap"
18083
18084 test_184d() {
18085         check_swap_layouts_support
18086         check_swap_layout_no_dom $DIR
18087         [ -z "$(which getfattr 2>/dev/null)" ] &&
18088                 skip_env "no getfattr command"
18089
18090         local file1=$DIR/$tdir/$tfile-1
18091         local file2=$DIR/$tdir/$tfile-2
18092         local file3=$DIR/$tdir/$tfile-3
18093         local lovea1
18094         local lovea2
18095
18096         mkdir -p $DIR/$tdir
18097         touch $file1 || error "create $file1 failed"
18098         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18099                 error "create $file2 failed"
18100         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18101                 error "create $file3 failed"
18102         lovea1=$(get_layout_param $file1)
18103
18104         $LFS swap_layouts $file2 $file3 ||
18105                 error "swap $file2 $file3 layouts failed"
18106         $LFS swap_layouts $file1 $file2 ||
18107                 error "swap $file1 $file2 layouts failed"
18108
18109         lovea2=$(get_layout_param $file2)
18110         echo "$lovea1"
18111         echo "$lovea2"
18112         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18113
18114         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18115         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18116 }
18117 run_test 184d "allow stripeless layouts swap"
18118
18119 test_184e() {
18120         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18121                 skip "Need MDS version at least 2.6.94"
18122         check_swap_layouts_support
18123         check_swap_layout_no_dom $DIR
18124         [ -z "$(which getfattr 2>/dev/null)" ] &&
18125                 skip_env "no getfattr command"
18126
18127         local file1=$DIR/$tdir/$tfile-1
18128         local file2=$DIR/$tdir/$tfile-2
18129         local file3=$DIR/$tdir/$tfile-3
18130         local lovea
18131
18132         mkdir -p $DIR/$tdir
18133         touch $file1 || error "create $file1 failed"
18134         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18135                 error "create $file2 failed"
18136         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18137                 error "create $file3 failed"
18138
18139         $LFS swap_layouts $file1 $file2 ||
18140                 error "swap $file1 $file2 layouts failed"
18141
18142         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18143         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18144
18145         echo 123 > $file1 || error "Should be able to write into $file1"
18146
18147         $LFS swap_layouts $file1 $file3 ||
18148                 error "swap $file1 $file3 layouts failed"
18149
18150         echo 123 > $file1 || error "Should be able to write into $file1"
18151
18152         rm -rf $file1 $file2 $file3
18153 }
18154 run_test 184e "Recreate layout after stripeless layout swaps"
18155
18156 test_184f() {
18157         # Create a file with name longer than sizeof(struct stat) ==
18158         # 144 to see if we can get chars from the file name to appear
18159         # in the returned striping. Note that 'f' == 0x66.
18160         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18161
18162         mkdir -p $DIR/$tdir
18163         mcreate $DIR/$tdir/$file
18164         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18165                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18166         fi
18167 }
18168 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18169
18170 test_185() { # LU-2441
18171         # LU-3553 - no volatile file support in old servers
18172         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18173                 skip "Need MDS version at least 2.3.60"
18174
18175         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18176         touch $DIR/$tdir/spoo
18177         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18178         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18179                 error "cannot create/write a volatile file"
18180         [ "$FILESET" == "" ] &&
18181         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18182                 error "FID is still valid after close"
18183
18184         multiop_bg_pause $DIR/$tdir vVw4096_c
18185         local multi_pid=$!
18186
18187         local OLD_IFS=$IFS
18188         IFS=":"
18189         local fidv=($fid)
18190         IFS=$OLD_IFS
18191         # assume that the next FID for this client is sequential, since stdout
18192         # is unfortunately eaten by multiop_bg_pause
18193         local n=$((${fidv[1]} + 1))
18194         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18195         if [ "$FILESET" == "" ]; then
18196                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18197                         error "FID is missing before close"
18198         fi
18199         kill -USR1 $multi_pid
18200         # 1 second delay, so if mtime change we will see it
18201         sleep 1
18202         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18203         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18204 }
18205 run_test 185 "Volatile file support"
18206
18207 function create_check_volatile() {
18208         local idx=$1
18209         local tgt
18210
18211         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18212         local PID=$!
18213         sleep 1
18214         local FID=$(cat /tmp/${tfile}.fid)
18215         [ "$FID" == "" ] && error "can't get FID for volatile"
18216         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18217         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18218         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18219         kill -USR1 $PID
18220         wait
18221         sleep 1
18222         cancel_lru_locks mdc # flush opencache
18223         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18224         return 0
18225 }
18226
18227 test_185a(){
18228         # LU-12516 - volatile creation via .lustre
18229         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18230                 skip "Need MDS version at least 2.3.55"
18231
18232         create_check_volatile 0
18233         [ $MDSCOUNT -lt 2 ] && return 0
18234
18235         # DNE case
18236         create_check_volatile 1
18237
18238         return 0
18239 }
18240 run_test 185a "Volatile file creation in .lustre/fid/"
18241
18242 test_187a() {
18243         remote_mds_nodsh && skip "remote MDS with nodsh"
18244         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18245                 skip "Need MDS version at least 2.3.0"
18246
18247         local dir0=$DIR/$tdir/$testnum
18248         mkdir -p $dir0 || error "creating dir $dir0"
18249
18250         local file=$dir0/file1
18251         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18252         local dv1=$($LFS data_version $file)
18253         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18254         local dv2=$($LFS data_version $file)
18255         [[ $dv1 != $dv2 ]] ||
18256                 error "data version did not change on write $dv1 == $dv2"
18257
18258         # clean up
18259         rm -f $file1
18260 }
18261 run_test 187a "Test data version change"
18262
18263 test_187b() {
18264         remote_mds_nodsh && skip "remote MDS with nodsh"
18265         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18266                 skip "Need MDS version at least 2.3.0"
18267
18268         local dir0=$DIR/$tdir/$testnum
18269         mkdir -p $dir0 || error "creating dir $dir0"
18270
18271         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18272         [[ ${DV[0]} != ${DV[1]} ]] ||
18273                 error "data version did not change on write"\
18274                       " ${DV[0]} == ${DV[1]}"
18275
18276         # clean up
18277         rm -f $file1
18278 }
18279 run_test 187b "Test data version change on volatile file"
18280
18281 test_200() {
18282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18283         remote_mgs_nodsh && skip "remote MGS with nodsh"
18284         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18285
18286         local POOL=${POOL:-cea1}
18287         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18288         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18289         # Pool OST targets
18290         local first_ost=0
18291         local last_ost=$(($OSTCOUNT - 1))
18292         local ost_step=2
18293         local ost_list=$(seq $first_ost $ost_step $last_ost)
18294         local ost_range="$first_ost $last_ost $ost_step"
18295         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18296         local file_dir=$POOL_ROOT/file_tst
18297         local subdir=$test_path/subdir
18298         local rc=0
18299
18300         while : ; do
18301                 # former test_200a test_200b
18302                 pool_add $POOL                          || { rc=$? ; break; }
18303                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18304                 # former test_200c test_200d
18305                 mkdir -p $test_path
18306                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18307                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18308                 mkdir -p $subdir
18309                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18310                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18311                                                         || { rc=$? ; break; }
18312                 # former test_200e test_200f
18313                 local files=$((OSTCOUNT*3))
18314                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18315                                                         || { rc=$? ; break; }
18316                 pool_create_files $POOL $file_dir $files "$ost_list" \
18317                                                         || { rc=$? ; break; }
18318                 # former test_200g test_200h
18319                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18320                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18321
18322                 # former test_201a test_201b test_201c
18323                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18324
18325                 local f=$test_path/$tfile
18326                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18327                 pool_remove $POOL $f                    || { rc=$? ; break; }
18328                 break
18329         done
18330
18331         destroy_test_pools
18332
18333         return $rc
18334 }
18335 run_test 200 "OST pools"
18336
18337 # usage: default_attr <count | size | offset>
18338 default_attr() {
18339         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18340 }
18341
18342 # usage: check_default_stripe_attr
18343 check_default_stripe_attr() {
18344         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18345         case $1 in
18346         --stripe-count|-c)
18347                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18348         --stripe-size|-S)
18349                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18350         --stripe-index|-i)
18351                 EXPECTED=-1;;
18352         *)
18353                 error "unknown getstripe attr '$1'"
18354         esac
18355
18356         [ $ACTUAL == $EXPECTED ] ||
18357                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18358 }
18359
18360 test_204a() {
18361         test_mkdir $DIR/$tdir
18362         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18363
18364         check_default_stripe_attr --stripe-count
18365         check_default_stripe_attr --stripe-size
18366         check_default_stripe_attr --stripe-index
18367 }
18368 run_test 204a "Print default stripe attributes"
18369
18370 test_204b() {
18371         test_mkdir $DIR/$tdir
18372         $LFS setstripe --stripe-count 1 $DIR/$tdir
18373
18374         check_default_stripe_attr --stripe-size
18375         check_default_stripe_attr --stripe-index
18376 }
18377 run_test 204b "Print default stripe size and offset"
18378
18379 test_204c() {
18380         test_mkdir $DIR/$tdir
18381         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18382
18383         check_default_stripe_attr --stripe-count
18384         check_default_stripe_attr --stripe-index
18385 }
18386 run_test 204c "Print default stripe count and offset"
18387
18388 test_204d() {
18389         test_mkdir $DIR/$tdir
18390         $LFS setstripe --stripe-index 0 $DIR/$tdir
18391
18392         check_default_stripe_attr --stripe-count
18393         check_default_stripe_attr --stripe-size
18394 }
18395 run_test 204d "Print default stripe count and size"
18396
18397 test_204e() {
18398         test_mkdir $DIR/$tdir
18399         $LFS setstripe -d $DIR/$tdir
18400
18401         check_default_stripe_attr --stripe-count --raw
18402         check_default_stripe_attr --stripe-size --raw
18403         check_default_stripe_attr --stripe-index --raw
18404 }
18405 run_test 204e "Print raw stripe attributes"
18406
18407 test_204f() {
18408         test_mkdir $DIR/$tdir
18409         $LFS setstripe --stripe-count 1 $DIR/$tdir
18410
18411         check_default_stripe_attr --stripe-size --raw
18412         check_default_stripe_attr --stripe-index --raw
18413 }
18414 run_test 204f "Print raw stripe size and offset"
18415
18416 test_204g() {
18417         test_mkdir $DIR/$tdir
18418         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18419
18420         check_default_stripe_attr --stripe-count --raw
18421         check_default_stripe_attr --stripe-index --raw
18422 }
18423 run_test 204g "Print raw stripe count and offset"
18424
18425 test_204h() {
18426         test_mkdir $DIR/$tdir
18427         $LFS setstripe --stripe-index 0 $DIR/$tdir
18428
18429         check_default_stripe_attr --stripe-count --raw
18430         check_default_stripe_attr --stripe-size --raw
18431 }
18432 run_test 204h "Print raw stripe count and size"
18433
18434 # Figure out which job scheduler is being used, if any,
18435 # or use a fake one
18436 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18437         JOBENV=SLURM_JOB_ID
18438 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18439         JOBENV=LSB_JOBID
18440 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18441         JOBENV=PBS_JOBID
18442 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18443         JOBENV=LOADL_STEP_ID
18444 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18445         JOBENV=JOB_ID
18446 else
18447         $LCTL list_param jobid_name > /dev/null 2>&1
18448         if [ $? -eq 0 ]; then
18449                 JOBENV=nodelocal
18450         else
18451                 JOBENV=FAKE_JOBID
18452         fi
18453 fi
18454 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18455
18456 verify_jobstats() {
18457         local cmd=($1)
18458         shift
18459         local facets="$@"
18460
18461 # we don't really need to clear the stats for this test to work, since each
18462 # command has a unique jobid, but it makes debugging easier if needed.
18463 #       for facet in $facets; do
18464 #               local dev=$(convert_facet2label $facet)
18465 #               # clear old jobstats
18466 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18467 #       done
18468
18469         # use a new JobID for each test, or we might see an old one
18470         [ "$JOBENV" = "FAKE_JOBID" ] &&
18471                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18472
18473         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18474
18475         [ "$JOBENV" = "nodelocal" ] && {
18476                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18477                 $LCTL set_param jobid_name=$FAKE_JOBID
18478                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18479         }
18480
18481         log "Test: ${cmd[*]}"
18482         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18483
18484         if [ $JOBENV = "FAKE_JOBID" ]; then
18485                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18486         else
18487                 ${cmd[*]}
18488         fi
18489
18490         # all files are created on OST0000
18491         for facet in $facets; do
18492                 local stats="*.$(convert_facet2label $facet).job_stats"
18493
18494                 # strip out libtool wrappers for in-tree executables
18495                 if (( $(do_facet $facet lctl get_param $stats |
18496                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18497                         do_facet $facet lctl get_param $stats
18498                         error "No jobstats for $JOBVAL found on $facet::$stats"
18499                 fi
18500         done
18501 }
18502
18503 jobstats_set() {
18504         local new_jobenv=$1
18505
18506         set_persistent_param_and_check client "jobid_var" \
18507                 "$FSNAME.sys.jobid_var" $new_jobenv
18508 }
18509
18510 test_205a() { # Job stats
18511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18512         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18513                 skip "Need MDS version with at least 2.7.1"
18514         remote_mgs_nodsh && skip "remote MGS with nodsh"
18515         remote_mds_nodsh && skip "remote MDS with nodsh"
18516         remote_ost_nodsh && skip "remote OST with nodsh"
18517         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18518                 skip "Server doesn't support jobstats"
18519         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18520
18521         local old_jobenv=$($LCTL get_param -n jobid_var)
18522         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18523
18524         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18525                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18526         else
18527                 stack_trap "do_facet mgs $PERM_CMD \
18528                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18529         fi
18530         changelog_register
18531
18532         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18533                                 mdt.*.job_cleanup_interval | head -n 1)
18534         local new_interval=5
18535         do_facet $SINGLEMDS \
18536                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18537         stack_trap "do_facet $SINGLEMDS \
18538                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18539         local start=$SECONDS
18540
18541         local cmd
18542         # mkdir
18543         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18544         verify_jobstats "$cmd" "$SINGLEMDS"
18545         # rmdir
18546         cmd="rmdir $DIR/$tdir"
18547         verify_jobstats "$cmd" "$SINGLEMDS"
18548         # mkdir on secondary MDT
18549         if [ $MDSCOUNT -gt 1 ]; then
18550                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18551                 verify_jobstats "$cmd" "mds2"
18552         fi
18553         # mknod
18554         cmd="mknod $DIR/$tfile c 1 3"
18555         verify_jobstats "$cmd" "$SINGLEMDS"
18556         # unlink
18557         cmd="rm -f $DIR/$tfile"
18558         verify_jobstats "$cmd" "$SINGLEMDS"
18559         # create all files on OST0000 so verify_jobstats can find OST stats
18560         # open & close
18561         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18562         verify_jobstats "$cmd" "$SINGLEMDS"
18563         # setattr
18564         cmd="touch $DIR/$tfile"
18565         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18566         # write
18567         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18568         verify_jobstats "$cmd" "ost1"
18569         # read
18570         cancel_lru_locks osc
18571         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18572         verify_jobstats "$cmd" "ost1"
18573         # truncate
18574         cmd="$TRUNCATE $DIR/$tfile 0"
18575         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18576         # rename
18577         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18578         verify_jobstats "$cmd" "$SINGLEMDS"
18579         # jobstats expiry - sleep until old stats should be expired
18580         local left=$((new_interval + 5 - (SECONDS - start)))
18581         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18582                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18583                         "0" $left
18584         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18585         verify_jobstats "$cmd" "$SINGLEMDS"
18586         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18587             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18588
18589         # Ensure that jobid are present in changelog (if supported by MDS)
18590         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18591                 changelog_dump | tail -10
18592                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18593                 [ $jobids -eq 9 ] ||
18594                         error "Wrong changelog jobid count $jobids != 9"
18595
18596                 # LU-5862
18597                 JOBENV="disable"
18598                 jobstats_set $JOBENV
18599                 touch $DIR/$tfile
18600                 changelog_dump | grep $tfile
18601                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18602                 [ $jobids -eq 0 ] ||
18603                         error "Unexpected jobids when jobid_var=$JOBENV"
18604         fi
18605
18606         # test '%j' access to environment variable - if supported
18607         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18608                 JOBENV="JOBCOMPLEX"
18609                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18610
18611                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18612         fi
18613
18614         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18615                 JOBENV="JOBCOMPLEX"
18616                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18617
18618                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18619         fi
18620
18621         # test '%j' access to per-session jobid - if supported
18622         if lctl list_param jobid_this_session > /dev/null 2>&1
18623         then
18624                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18625                 lctl set_param jobid_this_session=$USER
18626
18627                 JOBENV="JOBCOMPLEX"
18628                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18629
18630                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18631         fi
18632 }
18633 run_test 205a "Verify job stats"
18634
18635 # LU-13117, LU-13597
18636 test_205b() {
18637         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18638                 skip "Need MDS version at least 2.13.54.91"
18639
18640         job_stats="mdt.*.job_stats"
18641         $LCTL set_param $job_stats=clear
18642         # Setting jobid_var to USER might not be supported
18643         $LCTL set_param jobid_var=USER || true
18644         $LCTL set_param jobid_name="%e.%u"
18645         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18646         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18647                 grep "job_id:.*foolish" &&
18648                         error "Unexpected jobid found"
18649         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18650                 grep "open:.*min.*max.*sum" ||
18651                         error "wrong job_stats format found"
18652 }
18653 run_test 205b "Verify job stats jobid and output format"
18654
18655 # LU-13733
18656 test_205c() {
18657         $LCTL set_param llite.*.stats=0
18658         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18659         $LCTL get_param llite.*.stats
18660         $LCTL get_param llite.*.stats | grep \
18661                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18662                         error "wrong client stats format found"
18663 }
18664 run_test 205c "Verify client stats format"
18665
18666 # LU-1480, LU-1773 and LU-1657
18667 test_206() {
18668         mkdir -p $DIR/$tdir
18669         $LFS setstripe -c -1 $DIR/$tdir
18670 #define OBD_FAIL_LOV_INIT 0x1403
18671         $LCTL set_param fail_loc=0xa0001403
18672         $LCTL set_param fail_val=1
18673         touch $DIR/$tdir/$tfile || true
18674 }
18675 run_test 206 "fail lov_init_raid0() doesn't lbug"
18676
18677 test_207a() {
18678         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18679         local fsz=`stat -c %s $DIR/$tfile`
18680         cancel_lru_locks mdc
18681
18682         # do not return layout in getattr intent
18683 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18684         $LCTL set_param fail_loc=0x170
18685         local sz=`stat -c %s $DIR/$tfile`
18686
18687         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18688
18689         rm -rf $DIR/$tfile
18690 }
18691 run_test 207a "can refresh layout at glimpse"
18692
18693 test_207b() {
18694         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18695         local cksum=`md5sum $DIR/$tfile`
18696         local fsz=`stat -c %s $DIR/$tfile`
18697         cancel_lru_locks mdc
18698         cancel_lru_locks osc
18699
18700         # do not return layout in getattr intent
18701 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18702         $LCTL set_param fail_loc=0x171
18703
18704         # it will refresh layout after the file is opened but before read issues
18705         echo checksum is "$cksum"
18706         echo "$cksum" |md5sum -c --quiet || error "file differs"
18707
18708         rm -rf $DIR/$tfile
18709 }
18710 run_test 207b "can refresh layout at open"
18711
18712 test_208() {
18713         # FIXME: in this test suite, only RD lease is used. This is okay
18714         # for now as only exclusive open is supported. After generic lease
18715         # is done, this test suite should be revised. - Jinshan
18716
18717         remote_mds_nodsh && skip "remote MDS with nodsh"
18718         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18719                 skip "Need MDS version at least 2.4.52"
18720
18721         echo "==== test 1: verify get lease work"
18722         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18723
18724         echo "==== test 2: verify lease can be broken by upcoming open"
18725         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18726         local PID=$!
18727         sleep 2
18728
18729         $MULTIOP $DIR/$tfile oO_RDWR:c
18730         kill -USR1 $PID && wait $PID || error "break lease error"
18731
18732         echo "==== test 3: verify lease can't be granted if an open already exists"
18733         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18734         local PID=$!
18735         sleep 2
18736
18737         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18738         kill -USR1 $PID && wait $PID || error "open file error"
18739
18740         echo "==== test 4: lease can sustain over recovery"
18741         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18742         PID=$!
18743         sleep 2
18744
18745         fail mds1
18746
18747         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18748
18749         echo "==== test 5: lease broken can't be regained by replay"
18750         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18751         PID=$!
18752         sleep 2
18753
18754         # open file to break lease and then recovery
18755         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18756         fail mds1
18757
18758         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18759
18760         rm -f $DIR/$tfile
18761 }
18762 run_test 208 "Exclusive open"
18763
18764 test_209() {
18765         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18766                 skip_env "must have disp_stripe"
18767
18768         touch $DIR/$tfile
18769         sync; sleep 5; sync;
18770
18771         echo 3 > /proc/sys/vm/drop_caches
18772         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18773                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18774         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18775
18776         # open/close 500 times
18777         for i in $(seq 500); do
18778                 cat $DIR/$tfile
18779         done
18780
18781         echo 3 > /proc/sys/vm/drop_caches
18782         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18783                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18784         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18785
18786         echo "before: $req_before, after: $req_after"
18787         [ $((req_after - req_before)) -ge 300 ] &&
18788                 error "open/close requests are not freed"
18789         return 0
18790 }
18791 run_test 209 "read-only open/close requests should be freed promptly"
18792
18793 test_210() {
18794         local pid
18795
18796         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18797         pid=$!
18798         sleep 1
18799
18800         $LFS getstripe $DIR/$tfile
18801         kill -USR1 $pid
18802         wait $pid || error "multiop failed"
18803
18804         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18805         pid=$!
18806         sleep 1
18807
18808         $LFS getstripe $DIR/$tfile
18809         kill -USR1 $pid
18810         wait $pid || error "multiop failed"
18811 }
18812 run_test 210 "lfs getstripe does not break leases"
18813
18814 test_212() {
18815         size=`date +%s`
18816         size=$((size % 8192 + 1))
18817         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18818         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18819         rm -f $DIR/f212 $DIR/f212.xyz
18820 }
18821 run_test 212 "Sendfile test ============================================"
18822
18823 test_213() {
18824         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18825         cancel_lru_locks osc
18826         lctl set_param fail_loc=0x8000040f
18827         # generate a read lock
18828         cat $DIR/$tfile > /dev/null
18829         # write to the file, it will try to cancel the above read lock.
18830         cat /etc/hosts >> $DIR/$tfile
18831 }
18832 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18833
18834 test_214() { # for bug 20133
18835         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18836         for (( i=0; i < 340; i++ )) ; do
18837                 touch $DIR/$tdir/d214c/a$i
18838         done
18839
18840         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18841         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18842         ls $DIR/d214c || error "ls $DIR/d214c failed"
18843         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18844         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18845 }
18846 run_test 214 "hash-indexed directory test - bug 20133"
18847
18848 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18849 create_lnet_proc_files() {
18850         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18851 }
18852
18853 # counterpart of create_lnet_proc_files
18854 remove_lnet_proc_files() {
18855         rm -f $TMP/lnet_$1.sys
18856 }
18857
18858 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18859 # 3rd arg as regexp for body
18860 check_lnet_proc_stats() {
18861         local l=$(cat "$TMP/lnet_$1" |wc -l)
18862         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18863
18864         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18865 }
18866
18867 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18868 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18869 # optional and can be regexp for 2nd line (lnet.routes case)
18870 check_lnet_proc_entry() {
18871         local blp=2          # blp stands for 'position of 1st line of body'
18872         [ -z "$5" ] || blp=3 # lnet.routes case
18873
18874         local l=$(cat "$TMP/lnet_$1" |wc -l)
18875         # subtracting one from $blp because the body can be empty
18876         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18877
18878         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18879                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18880
18881         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18882                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18883
18884         # bail out if any unexpected line happened
18885         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18886         [ "$?" != 0 ] || error "$2 misformatted"
18887 }
18888
18889 test_215() { # for bugs 18102, 21079, 21517
18890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18891
18892         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18893         local P='[1-9][0-9]*'           # positive numeric
18894         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18895         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18896         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18897         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18898
18899         local L1 # regexp for 1st line
18900         local L2 # regexp for 2nd line (optional)
18901         local BR # regexp for the rest (body)
18902
18903         # lnet.stats should look as 11 space-separated non-negative numerics
18904         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18905         create_lnet_proc_files "stats"
18906         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18907         remove_lnet_proc_files "stats"
18908
18909         # lnet.routes should look like this:
18910         # Routing disabled/enabled
18911         # net hops priority state router
18912         # where net is a string like tcp0, hops > 0, priority >= 0,
18913         # state is up/down,
18914         # router is a string like 192.168.1.1@tcp2
18915         L1="^Routing (disabled|enabled)$"
18916         L2="^net +hops +priority +state +router$"
18917         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18918         create_lnet_proc_files "routes"
18919         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18920         remove_lnet_proc_files "routes"
18921
18922         # lnet.routers should look like this:
18923         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18924         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18925         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18926         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18927         L1="^ref +rtr_ref +alive +router$"
18928         BR="^$P +$P +(up|down) +$NID$"
18929         create_lnet_proc_files "routers"
18930         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18931         remove_lnet_proc_files "routers"
18932
18933         # lnet.peers should look like this:
18934         # nid refs state last max rtr min tx min queue
18935         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18936         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18937         # numeric (0 or >0 or <0), queue >= 0.
18938         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18939         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18940         create_lnet_proc_files "peers"
18941         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18942         remove_lnet_proc_files "peers"
18943
18944         # lnet.buffers  should look like this:
18945         # pages count credits min
18946         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18947         L1="^pages +count +credits +min$"
18948         BR="^ +$N +$N +$I +$I$"
18949         create_lnet_proc_files "buffers"
18950         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18951         remove_lnet_proc_files "buffers"
18952
18953         # lnet.nis should look like this:
18954         # nid status alive refs peer rtr max tx min
18955         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18956         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18957         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18958         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18959         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18960         create_lnet_proc_files "nis"
18961         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18962         remove_lnet_proc_files "nis"
18963
18964         # can we successfully write to lnet.stats?
18965         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18966 }
18967 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18968
18969 test_216() { # bug 20317
18970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18971         remote_ost_nodsh && skip "remote OST with nodsh"
18972
18973         local node
18974         local facets=$(get_facets OST)
18975         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18976
18977         save_lustre_params client "osc.*.contention_seconds" > $p
18978         save_lustre_params $facets \
18979                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18980         save_lustre_params $facets \
18981                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18982         save_lustre_params $facets \
18983                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18984         clear_stats osc.*.osc_stats
18985
18986         # agressive lockless i/o settings
18987         do_nodes $(comma_list $(osts_nodes)) \
18988                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18989                         ldlm.namespaces.filter-*.contended_locks=0 \
18990                         ldlm.namespaces.filter-*.contention_seconds=60"
18991         lctl set_param -n osc.*.contention_seconds=60
18992
18993         $DIRECTIO write $DIR/$tfile 0 10 4096
18994         $CHECKSTAT -s 40960 $DIR/$tfile
18995
18996         # disable lockless i/o
18997         do_nodes $(comma_list $(osts_nodes)) \
18998                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18999                         ldlm.namespaces.filter-*.contended_locks=32 \
19000                         ldlm.namespaces.filter-*.contention_seconds=0"
19001         lctl set_param -n osc.*.contention_seconds=0
19002         clear_stats osc.*.osc_stats
19003
19004         dd if=/dev/zero of=$DIR/$tfile count=0
19005         $CHECKSTAT -s 0 $DIR/$tfile
19006
19007         restore_lustre_params <$p
19008         rm -f $p
19009         rm $DIR/$tfile
19010 }
19011 run_test 216 "check lockless direct write updates file size and kms correctly"
19012
19013 test_217() { # bug 22430
19014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19015
19016         local node
19017         local nid
19018
19019         for node in $(nodes_list); do
19020                 nid=$(host_nids_address $node $NETTYPE)
19021                 if [[ $nid = *-* ]] ; then
19022                         echo "lctl ping $(h2nettype $nid)"
19023                         lctl ping $(h2nettype $nid)
19024                 else
19025                         echo "skipping $node (no hyphen detected)"
19026                 fi
19027         done
19028 }
19029 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19030
19031 test_218() {
19032        # do directio so as not to populate the page cache
19033        log "creating a 10 Mb file"
19034        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19035        log "starting reads"
19036        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19037        log "truncating the file"
19038        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19039        log "killing dd"
19040        kill %+ || true # reads might have finished
19041        echo "wait until dd is finished"
19042        wait
19043        log "removing the temporary file"
19044        rm -rf $DIR/$tfile || error "tmp file removal failed"
19045 }
19046 run_test 218 "parallel read and truncate should not deadlock"
19047
19048 test_219() {
19049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19050
19051         # write one partial page
19052         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19053         # set no grant so vvp_io_commit_write will do sync write
19054         $LCTL set_param fail_loc=0x411
19055         # write a full page at the end of file
19056         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19057
19058         $LCTL set_param fail_loc=0
19059         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19060         $LCTL set_param fail_loc=0x411
19061         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19062
19063         # LU-4201
19064         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19065         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19066 }
19067 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19068
19069 test_220() { #LU-325
19070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19071         remote_ost_nodsh && skip "remote OST with nodsh"
19072         remote_mds_nodsh && skip "remote MDS with nodsh"
19073         remote_mgs_nodsh && skip "remote MGS with nodsh"
19074
19075         local OSTIDX=0
19076
19077         # create on MDT0000 so the last_id and next_id are correct
19078         mkdir_on_mdt0 $DIR/$tdir
19079         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19080         OST=${OST%_UUID}
19081
19082         # on the mdt's osc
19083         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19084         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19085                         osp.$mdtosc_proc1.prealloc_last_id)
19086         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19087                         osp.$mdtosc_proc1.prealloc_next_id)
19088
19089         $LFS df -i
19090
19091         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19092         #define OBD_FAIL_OST_ENOINO              0x229
19093         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19094         create_pool $FSNAME.$TESTNAME || return 1
19095         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19096
19097         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19098
19099         MDSOBJS=$((last_id - next_id))
19100         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19101
19102         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19103         echo "OST still has $count kbytes free"
19104
19105         echo "create $MDSOBJS files @next_id..."
19106         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19107
19108         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19109                         osp.$mdtosc_proc1.prealloc_last_id)
19110         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19111                         osp.$mdtosc_proc1.prealloc_next_id)
19112
19113         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19114         $LFS df -i
19115
19116         echo "cleanup..."
19117
19118         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19119         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19120
19121         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19122                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19123         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19124                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19125         echo "unlink $MDSOBJS files @$next_id..."
19126         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19127 }
19128 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19129
19130 test_221() {
19131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19132
19133         dd if=`which date` of=$MOUNT/date oflag=sync
19134         chmod +x $MOUNT/date
19135
19136         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19137         $LCTL set_param fail_loc=0x80001401
19138
19139         $MOUNT/date > /dev/null
19140         rm -f $MOUNT/date
19141 }
19142 run_test 221 "make sure fault and truncate race to not cause OOM"
19143
19144 test_222a () {
19145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19146
19147         rm -rf $DIR/$tdir
19148         test_mkdir $DIR/$tdir
19149         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19150         createmany -o $DIR/$tdir/$tfile 10
19151         cancel_lru_locks mdc
19152         cancel_lru_locks osc
19153         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19154         $LCTL set_param fail_loc=0x31a
19155         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19156         $LCTL set_param fail_loc=0
19157         rm -r $DIR/$tdir
19158 }
19159 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19160
19161 test_222b () {
19162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19163
19164         rm -rf $DIR/$tdir
19165         test_mkdir $DIR/$tdir
19166         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19167         createmany -o $DIR/$tdir/$tfile 10
19168         cancel_lru_locks mdc
19169         cancel_lru_locks osc
19170         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19171         $LCTL set_param fail_loc=0x31a
19172         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19173         $LCTL set_param fail_loc=0
19174 }
19175 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19176
19177 test_223 () {
19178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19179
19180         rm -rf $DIR/$tdir
19181         test_mkdir $DIR/$tdir
19182         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19183         createmany -o $DIR/$tdir/$tfile 10
19184         cancel_lru_locks mdc
19185         cancel_lru_locks osc
19186         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19187         $LCTL set_param fail_loc=0x31b
19188         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19189         $LCTL set_param fail_loc=0
19190         rm -r $DIR/$tdir
19191 }
19192 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19193
19194 test_224a() { # LU-1039, MRP-303
19195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19196         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19197         $LCTL set_param fail_loc=0x508
19198         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19199         $LCTL set_param fail_loc=0
19200         df $DIR
19201 }
19202 run_test 224a "Don't panic on bulk IO failure"
19203
19204 test_224bd_sub() { # LU-1039, MRP-303
19205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19206         local timeout=$1
19207
19208         shift
19209         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19210
19211         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19212
19213         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19214         cancel_lru_locks osc
19215         set_checksums 0
19216         stack_trap "set_checksums $ORIG_CSUM" EXIT
19217         local at_max_saved=0
19218
19219         # adaptive timeouts may prevent seeing the issue
19220         if at_is_enabled; then
19221                 at_max_saved=$(at_max_get mds)
19222                 at_max_set 0 mds client
19223                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19224         fi
19225
19226         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19227         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19228         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19229
19230         do_facet ost1 $LCTL set_param fail_loc=0
19231         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19232         df $DIR
19233 }
19234
19235 test_224b() {
19236         test_224bd_sub 3 error "dd failed"
19237 }
19238 run_test 224b "Don't panic on bulk IO failure"
19239
19240 test_224c() { # LU-6441
19241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19242         remote_mds_nodsh && skip "remote MDS with nodsh"
19243
19244         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19245         save_writethrough $p
19246         set_cache writethrough on
19247
19248         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19249         local at_max=$($LCTL get_param -n at_max)
19250         local timeout=$($LCTL get_param -n timeout)
19251         local test_at="at_max"
19252         local param_at="$FSNAME.sys.at_max"
19253         local test_timeout="timeout"
19254         local param_timeout="$FSNAME.sys.timeout"
19255
19256         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19257
19258         set_persistent_param_and_check client "$test_at" "$param_at" 0
19259         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19260
19261         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19262         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19263         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19264         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19265         sync
19266         do_facet ost1 "$LCTL set_param fail_loc=0"
19267
19268         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19269         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19270                 $timeout
19271
19272         $LCTL set_param -n $pages_per_rpc
19273         restore_lustre_params < $p
19274         rm -f $p
19275 }
19276 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19277
19278 test_224d() { # LU-11169
19279         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19280 }
19281 run_test 224d "Don't corrupt data on bulk IO timeout"
19282
19283 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19284 test_225a () {
19285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19286         if [ -z ${MDSSURVEY} ]; then
19287                 skip_env "mds-survey not found"
19288         fi
19289         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19290                 skip "Need MDS version at least 2.2.51"
19291
19292         local mds=$(facet_host $SINGLEMDS)
19293         local target=$(do_nodes $mds 'lctl dl' |
19294                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19295
19296         local cmd1="file_count=1000 thrhi=4"
19297         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19298         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19299         local cmd="$cmd1 $cmd2 $cmd3"
19300
19301         rm -f ${TMP}/mds_survey*
19302         echo + $cmd
19303         eval $cmd || error "mds-survey with zero-stripe failed"
19304         cat ${TMP}/mds_survey*
19305         rm -f ${TMP}/mds_survey*
19306 }
19307 run_test 225a "Metadata survey sanity with zero-stripe"
19308
19309 test_225b () {
19310         if [ -z ${MDSSURVEY} ]; then
19311                 skip_env "mds-survey not found"
19312         fi
19313         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19314                 skip "Need MDS version at least 2.2.51"
19315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19316         remote_mds_nodsh && skip "remote MDS with nodsh"
19317         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19318                 skip_env "Need to mount OST to test"
19319         fi
19320
19321         local mds=$(facet_host $SINGLEMDS)
19322         local target=$(do_nodes $mds 'lctl dl' |
19323                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19324
19325         local cmd1="file_count=1000 thrhi=4"
19326         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19327         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19328         local cmd="$cmd1 $cmd2 $cmd3"
19329
19330         rm -f ${TMP}/mds_survey*
19331         echo + $cmd
19332         eval $cmd || error "mds-survey with stripe_count failed"
19333         cat ${TMP}/mds_survey*
19334         rm -f ${TMP}/mds_survey*
19335 }
19336 run_test 225b "Metadata survey sanity with stripe_count = 1"
19337
19338 mcreate_path2fid () {
19339         local mode=$1
19340         local major=$2
19341         local minor=$3
19342         local name=$4
19343         local desc=$5
19344         local path=$DIR/$tdir/$name
19345         local fid
19346         local rc
19347         local fid_path
19348
19349         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19350                 error "cannot create $desc"
19351
19352         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19353         rc=$?
19354         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19355
19356         fid_path=$($LFS fid2path $MOUNT $fid)
19357         rc=$?
19358         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19359
19360         [ "$path" == "$fid_path" ] ||
19361                 error "fid2path returned $fid_path, expected $path"
19362
19363         echo "pass with $path and $fid"
19364 }
19365
19366 test_226a () {
19367         rm -rf $DIR/$tdir
19368         mkdir -p $DIR/$tdir
19369
19370         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19371         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19372         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19373         mcreate_path2fid 0040666 0 0 dir "directory"
19374         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19375         mcreate_path2fid 0100666 0 0 file "regular file"
19376         mcreate_path2fid 0120666 0 0 link "symbolic link"
19377         mcreate_path2fid 0140666 0 0 sock "socket"
19378 }
19379 run_test 226a "call path2fid and fid2path on files of all type"
19380
19381 test_226b () {
19382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19383
19384         local MDTIDX=1
19385
19386         rm -rf $DIR/$tdir
19387         mkdir -p $DIR/$tdir
19388         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19389                 error "create remote directory failed"
19390         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19391         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19392                                 "character special file (null)"
19393         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19394                                 "character special file (no device)"
19395         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19396         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19397                                 "block special file (loop)"
19398         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19399         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19400         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19401 }
19402 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19403
19404 test_226c () {
19405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19406         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19407                 skip "Need MDS version at least 2.13.55"
19408
19409         local submnt=/mnt/submnt
19410         local srcfile=/etc/passwd
19411         local dstfile=$submnt/passwd
19412         local path
19413         local fid
19414
19415         rm -rf $DIR/$tdir
19416         rm -rf $submnt
19417         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19418                 error "create remote directory failed"
19419         mkdir -p $submnt || error "create $submnt failed"
19420         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19421                 error "mount $submnt failed"
19422         stack_trap "umount $submnt" EXIT
19423
19424         cp $srcfile $dstfile
19425         fid=$($LFS path2fid $dstfile)
19426         path=$($LFS fid2path $submnt "$fid")
19427         [ "$path" = "$dstfile" ] ||
19428                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19429 }
19430 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19431
19432 # LU-1299 Executing or running ldd on a truncated executable does not
19433 # cause an out-of-memory condition.
19434 test_227() {
19435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19436         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19437
19438         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19439         chmod +x $MOUNT/date
19440
19441         $MOUNT/date > /dev/null
19442         ldd $MOUNT/date > /dev/null
19443         rm -f $MOUNT/date
19444 }
19445 run_test 227 "running truncated executable does not cause OOM"
19446
19447 # LU-1512 try to reuse idle OI blocks
19448 test_228a() {
19449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19450         remote_mds_nodsh && skip "remote MDS with nodsh"
19451         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19452
19453         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19454         local myDIR=$DIR/$tdir
19455
19456         mkdir -p $myDIR
19457         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19458         $LCTL set_param fail_loc=0x80001002
19459         createmany -o $myDIR/t- 10000
19460         $LCTL set_param fail_loc=0
19461         # The guard is current the largest FID holder
19462         touch $myDIR/guard
19463         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19464                     tr -d '[')
19465         local IDX=$(($SEQ % 64))
19466
19467         do_facet $SINGLEMDS sync
19468         # Make sure journal flushed.
19469         sleep 6
19470         local blk1=$(do_facet $SINGLEMDS \
19471                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19472                      grep Blockcount | awk '{print $4}')
19473
19474         # Remove old files, some OI blocks will become idle.
19475         unlinkmany $myDIR/t- 10000
19476         # Create new files, idle OI blocks should be reused.
19477         createmany -o $myDIR/t- 2000
19478         do_facet $SINGLEMDS sync
19479         # Make sure journal flushed.
19480         sleep 6
19481         local blk2=$(do_facet $SINGLEMDS \
19482                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19483                      grep Blockcount | awk '{print $4}')
19484
19485         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19486 }
19487 run_test 228a "try to reuse idle OI blocks"
19488
19489 test_228b() {
19490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19491         remote_mds_nodsh && skip "remote MDS with nodsh"
19492         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19493
19494         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19495         local myDIR=$DIR/$tdir
19496
19497         mkdir -p $myDIR
19498         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19499         $LCTL set_param fail_loc=0x80001002
19500         createmany -o $myDIR/t- 10000
19501         $LCTL set_param fail_loc=0
19502         # The guard is current the largest FID holder
19503         touch $myDIR/guard
19504         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19505                     tr -d '[')
19506         local IDX=$(($SEQ % 64))
19507
19508         do_facet $SINGLEMDS sync
19509         # Make sure journal flushed.
19510         sleep 6
19511         local blk1=$(do_facet $SINGLEMDS \
19512                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19513                      grep Blockcount | awk '{print $4}')
19514
19515         # Remove old files, some OI blocks will become idle.
19516         unlinkmany $myDIR/t- 10000
19517
19518         # stop the MDT
19519         stop $SINGLEMDS || error "Fail to stop MDT."
19520         # remount the MDT
19521         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19522                 error "Fail to start MDT."
19523
19524         df $MOUNT || error "Fail to df."
19525         # Create new files, idle OI blocks should be reused.
19526         createmany -o $myDIR/t- 2000
19527         do_facet $SINGLEMDS sync
19528         # Make sure journal flushed.
19529         sleep 6
19530         local blk2=$(do_facet $SINGLEMDS \
19531                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19532                      grep Blockcount | awk '{print $4}')
19533
19534         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19535 }
19536 run_test 228b "idle OI blocks can be reused after MDT restart"
19537
19538 #LU-1881
19539 test_228c() {
19540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19541         remote_mds_nodsh && skip "remote MDS with nodsh"
19542         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19543
19544         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19545         local myDIR=$DIR/$tdir
19546
19547         mkdir -p $myDIR
19548         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19549         $LCTL set_param fail_loc=0x80001002
19550         # 20000 files can guarantee there are index nodes in the OI file
19551         createmany -o $myDIR/t- 20000
19552         $LCTL set_param fail_loc=0
19553         # The guard is current the largest FID holder
19554         touch $myDIR/guard
19555         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19556                     tr -d '[')
19557         local IDX=$(($SEQ % 64))
19558
19559         do_facet $SINGLEMDS sync
19560         # Make sure journal flushed.
19561         sleep 6
19562         local blk1=$(do_facet $SINGLEMDS \
19563                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19564                      grep Blockcount | awk '{print $4}')
19565
19566         # Remove old files, some OI blocks will become idle.
19567         unlinkmany $myDIR/t- 20000
19568         rm -f $myDIR/guard
19569         # The OI file should become empty now
19570
19571         # Create new files, idle OI blocks should be reused.
19572         createmany -o $myDIR/t- 2000
19573         do_facet $SINGLEMDS sync
19574         # Make sure journal flushed.
19575         sleep 6
19576         local blk2=$(do_facet $SINGLEMDS \
19577                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19578                      grep Blockcount | awk '{print $4}')
19579
19580         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19581 }
19582 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19583
19584 test_229() { # LU-2482, LU-3448
19585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19586         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19587         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19588                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19589
19590         rm -f $DIR/$tfile
19591
19592         # Create a file with a released layout and stripe count 2.
19593         $MULTIOP $DIR/$tfile H2c ||
19594                 error "failed to create file with released layout"
19595
19596         $LFS getstripe -v $DIR/$tfile
19597
19598         local pattern=$($LFS getstripe -L $DIR/$tfile)
19599         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19600
19601         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19602                 error "getstripe"
19603         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19604         stat $DIR/$tfile || error "failed to stat released file"
19605
19606         chown $RUNAS_ID $DIR/$tfile ||
19607                 error "chown $RUNAS_ID $DIR/$tfile failed"
19608
19609         chgrp $RUNAS_ID $DIR/$tfile ||
19610                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19611
19612         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19613         rm $DIR/$tfile || error "failed to remove released file"
19614 }
19615 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19616
19617 test_230a() {
19618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19620         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19621                 skip "Need MDS version at least 2.11.52"
19622
19623         local MDTIDX=1
19624
19625         test_mkdir $DIR/$tdir
19626         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19627         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19628         [ $mdt_idx -ne 0 ] &&
19629                 error "create local directory on wrong MDT $mdt_idx"
19630
19631         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19632                         error "create remote directory failed"
19633         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19634         [ $mdt_idx -ne $MDTIDX ] &&
19635                 error "create remote directory on wrong MDT $mdt_idx"
19636
19637         createmany -o $DIR/$tdir/test_230/t- 10 ||
19638                 error "create files on remote directory failed"
19639         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19640         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19641         rm -r $DIR/$tdir || error "unlink remote directory failed"
19642 }
19643 run_test 230a "Create remote directory and files under the remote directory"
19644
19645 test_230b() {
19646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19648         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19649                 skip "Need MDS version at least 2.11.52"
19650
19651         local MDTIDX=1
19652         local mdt_index
19653         local i
19654         local file
19655         local pid
19656         local stripe_count
19657         local migrate_dir=$DIR/$tdir/migrate_dir
19658         local other_dir=$DIR/$tdir/other_dir
19659
19660         test_mkdir $DIR/$tdir
19661         test_mkdir -i0 -c1 $migrate_dir
19662         test_mkdir -i0 -c1 $other_dir
19663         for ((i=0; i<10; i++)); do
19664                 mkdir -p $migrate_dir/dir_${i}
19665                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19666                         error "create files under remote dir failed $i"
19667         done
19668
19669         cp /etc/passwd $migrate_dir/$tfile
19670         cp /etc/passwd $other_dir/$tfile
19671         chattr +SAD $migrate_dir
19672         chattr +SAD $migrate_dir/$tfile
19673
19674         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19675         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19676         local old_dir_mode=$(stat -c%f $migrate_dir)
19677         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19678
19679         mkdir -p $migrate_dir/dir_default_stripe2
19680         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19681         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19682
19683         mkdir -p $other_dir
19684         ln $migrate_dir/$tfile $other_dir/luna
19685         ln $migrate_dir/$tfile $migrate_dir/sofia
19686         ln $other_dir/$tfile $migrate_dir/david
19687         ln -s $migrate_dir/$tfile $other_dir/zachary
19688         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19689         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19690
19691         local len
19692         local lnktgt
19693
19694         # inline symlink
19695         for len in 58 59 60; do
19696                 lnktgt=$(str_repeat 'l' $len)
19697                 touch $migrate_dir/$lnktgt
19698                 ln -s $lnktgt $migrate_dir/${len}char_ln
19699         done
19700
19701         # PATH_MAX
19702         for len in 4094 4095; do
19703                 lnktgt=$(str_repeat 'l' $len)
19704                 ln -s $lnktgt $migrate_dir/${len}char_ln
19705         done
19706
19707         # NAME_MAX
19708         for len in 254 255; do
19709                 touch $migrate_dir/$(str_repeat 'l' $len)
19710         done
19711
19712         $LFS migrate -m $MDTIDX $migrate_dir ||
19713                 error "fails on migrating remote dir to MDT1"
19714
19715         echo "migratate to MDT1, then checking.."
19716         for ((i = 0; i < 10; i++)); do
19717                 for file in $(find $migrate_dir/dir_${i}); do
19718                         mdt_index=$($LFS getstripe -m $file)
19719                         # broken symlink getstripe will fail
19720                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19721                                 error "$file is not on MDT${MDTIDX}"
19722                 done
19723         done
19724
19725         # the multiple link file should still in MDT0
19726         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19727         [ $mdt_index == 0 ] ||
19728                 error "$file is not on MDT${MDTIDX}"
19729
19730         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19731         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19732                 error " expect $old_dir_flag get $new_dir_flag"
19733
19734         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19735         [ "$old_file_flag" = "$new_file_flag" ] ||
19736                 error " expect $old_file_flag get $new_file_flag"
19737
19738         local new_dir_mode=$(stat -c%f $migrate_dir)
19739         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19740                 error "expect mode $old_dir_mode get $new_dir_mode"
19741
19742         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19743         [ "$old_file_mode" = "$new_file_mode" ] ||
19744                 error "expect mode $old_file_mode get $new_file_mode"
19745
19746         diff /etc/passwd $migrate_dir/$tfile ||
19747                 error "$tfile different after migration"
19748
19749         diff /etc/passwd $other_dir/luna ||
19750                 error "luna different after migration"
19751
19752         diff /etc/passwd $migrate_dir/sofia ||
19753                 error "sofia different after migration"
19754
19755         diff /etc/passwd $migrate_dir/david ||
19756                 error "david different after migration"
19757
19758         diff /etc/passwd $other_dir/zachary ||
19759                 error "zachary different after migration"
19760
19761         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19762                 error "${tfile}_ln different after migration"
19763
19764         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19765                 error "${tfile}_ln_other different after migration"
19766
19767         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19768         [ $stripe_count = 2 ] ||
19769                 error "dir strpe_count $d != 2 after migration."
19770
19771         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19772         [ $stripe_count = 2 ] ||
19773                 error "file strpe_count $d != 2 after migration."
19774
19775         #migrate back to MDT0
19776         MDTIDX=0
19777
19778         $LFS migrate -m $MDTIDX $migrate_dir ||
19779                 error "fails on migrating remote dir to MDT0"
19780
19781         echo "migrate back to MDT0, checking.."
19782         for file in $(find $migrate_dir); do
19783                 mdt_index=$($LFS getstripe -m $file)
19784                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19785                         error "$file is not on MDT${MDTIDX}"
19786         done
19787
19788         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19789         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19790                 error " expect $old_dir_flag get $new_dir_flag"
19791
19792         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19793         [ "$old_file_flag" = "$new_file_flag" ] ||
19794                 error " expect $old_file_flag get $new_file_flag"
19795
19796         local new_dir_mode=$(stat -c%f $migrate_dir)
19797         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19798                 error "expect mode $old_dir_mode get $new_dir_mode"
19799
19800         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19801         [ "$old_file_mode" = "$new_file_mode" ] ||
19802                 error "expect mode $old_file_mode get $new_file_mode"
19803
19804         diff /etc/passwd ${migrate_dir}/$tfile ||
19805                 error "$tfile different after migration"
19806
19807         diff /etc/passwd ${other_dir}/luna ||
19808                 error "luna different after migration"
19809
19810         diff /etc/passwd ${migrate_dir}/sofia ||
19811                 error "sofia different after migration"
19812
19813         diff /etc/passwd ${other_dir}/zachary ||
19814                 error "zachary different after migration"
19815
19816         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19817                 error "${tfile}_ln different after migration"
19818
19819         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19820                 error "${tfile}_ln_other different after migration"
19821
19822         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19823         [ $stripe_count = 2 ] ||
19824                 error "dir strpe_count $d != 2 after migration."
19825
19826         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19827         [ $stripe_count = 2 ] ||
19828                 error "file strpe_count $d != 2 after migration."
19829
19830         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19831 }
19832 run_test 230b "migrate directory"
19833
19834 test_230c() {
19835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19836         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19837         remote_mds_nodsh && skip "remote MDS with nodsh"
19838         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19839                 skip "Need MDS version at least 2.11.52"
19840
19841         local MDTIDX=1
19842         local total=3
19843         local mdt_index
19844         local file
19845         local migrate_dir=$DIR/$tdir/migrate_dir
19846
19847         #If migrating directory fails in the middle, all entries of
19848         #the directory is still accessiable.
19849         test_mkdir $DIR/$tdir
19850         test_mkdir -i0 -c1 $migrate_dir
19851         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19852         stat $migrate_dir
19853         createmany -o $migrate_dir/f $total ||
19854                 error "create files under ${migrate_dir} failed"
19855
19856         # fail after migrating top dir, and this will fail only once, so the
19857         # first sub file migration will fail (currently f3), others succeed.
19858         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19859         do_facet mds1 lctl set_param fail_loc=0x1801
19860         local t=$(ls $migrate_dir | wc -l)
19861         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19862                 error "migrate should fail"
19863         local u=$(ls $migrate_dir | wc -l)
19864         [ "$u" == "$t" ] || error "$u != $t during migration"
19865
19866         # add new dir/file should succeed
19867         mkdir $migrate_dir/dir ||
19868                 error "mkdir failed under migrating directory"
19869         touch $migrate_dir/file ||
19870                 error "create file failed under migrating directory"
19871
19872         # add file with existing name should fail
19873         for file in $migrate_dir/f*; do
19874                 stat $file > /dev/null || error "stat $file failed"
19875                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19876                         error "open(O_CREAT|O_EXCL) $file should fail"
19877                 $MULTIOP $file m && error "create $file should fail"
19878                 touch $DIR/$tdir/remote_dir/$tfile ||
19879                         error "touch $tfile failed"
19880                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19881                         error "link $file should fail"
19882                 mdt_index=$($LFS getstripe -m $file)
19883                 if [ $mdt_index == 0 ]; then
19884                         # file failed to migrate is not allowed to rename to
19885                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19886                                 error "rename to $file should fail"
19887                 else
19888                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19889                                 error "rename to $file failed"
19890                 fi
19891                 echo hello >> $file || error "write $file failed"
19892         done
19893
19894         # resume migration with different options should fail
19895         $LFS migrate -m 0 $migrate_dir &&
19896                 error "migrate -m 0 $migrate_dir should fail"
19897
19898         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19899                 error "migrate -c 2 $migrate_dir should fail"
19900
19901         # resume migration should succeed
19902         $LFS migrate -m $MDTIDX $migrate_dir ||
19903                 error "migrate $migrate_dir failed"
19904
19905         echo "Finish migration, then checking.."
19906         for file in $(find $migrate_dir); do
19907                 mdt_index=$($LFS getstripe -m $file)
19908                 [ $mdt_index == $MDTIDX ] ||
19909                         error "$file is not on MDT${MDTIDX}"
19910         done
19911
19912         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19913 }
19914 run_test 230c "check directory accessiblity if migration failed"
19915
19916 test_230d() {
19917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19919         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19920                 skip "Need MDS version at least 2.11.52"
19921         # LU-11235
19922         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19923
19924         local migrate_dir=$DIR/$tdir/migrate_dir
19925         local old_index
19926         local new_index
19927         local old_count
19928         local new_count
19929         local new_hash
19930         local mdt_index
19931         local i
19932         local j
19933
19934         old_index=$((RANDOM % MDSCOUNT))
19935         old_count=$((MDSCOUNT - old_index))
19936         new_index=$((RANDOM % MDSCOUNT))
19937         new_count=$((MDSCOUNT - new_index))
19938         new_hash=1 # for all_char
19939
19940         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19941         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19942
19943         test_mkdir $DIR/$tdir
19944         test_mkdir -i $old_index -c $old_count $migrate_dir
19945
19946         for ((i=0; i<100; i++)); do
19947                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19948                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19949                         error "create files under remote dir failed $i"
19950         done
19951
19952         echo -n "Migrate from MDT$old_index "
19953         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19954         echo -n "to MDT$new_index"
19955         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19956         echo
19957
19958         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19959         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19960                 error "migrate remote dir error"
19961
19962         echo "Finish migration, then checking.."
19963         for file in $(find $migrate_dir -maxdepth 1); do
19964                 mdt_index=$($LFS getstripe -m $file)
19965                 if [ $mdt_index -lt $new_index ] ||
19966                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19967                         error "$file is on MDT$mdt_index"
19968                 fi
19969         done
19970
19971         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19972 }
19973 run_test 230d "check migrate big directory"
19974
19975 test_230e() {
19976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19978         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19979                 skip "Need MDS version at least 2.11.52"
19980
19981         local i
19982         local j
19983         local a_fid
19984         local b_fid
19985
19986         mkdir_on_mdt0 $DIR/$tdir
19987         mkdir $DIR/$tdir/migrate_dir
19988         mkdir $DIR/$tdir/other_dir
19989         touch $DIR/$tdir/migrate_dir/a
19990         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19991         ls $DIR/$tdir/other_dir
19992
19993         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19994                 error "migrate dir fails"
19995
19996         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19997         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19998
19999         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20000         [ $mdt_index == 0 ] || error "a is not on MDT0"
20001
20002         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20003                 error "migrate dir fails"
20004
20005         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20006         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20007
20008         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20009         [ $mdt_index == 1 ] || error "a is not on MDT1"
20010
20011         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20012         [ $mdt_index == 1 ] || error "b is not on MDT1"
20013
20014         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20015         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20016
20017         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20018
20019         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20020 }
20021 run_test 230e "migrate mulitple local link files"
20022
20023 test_230f() {
20024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20025         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20026         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20027                 skip "Need MDS version at least 2.11.52"
20028
20029         local a_fid
20030         local ln_fid
20031
20032         mkdir -p $DIR/$tdir
20033         mkdir $DIR/$tdir/migrate_dir
20034         $LFS mkdir -i1 $DIR/$tdir/other_dir
20035         touch $DIR/$tdir/migrate_dir/a
20036         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20037         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20038         ls $DIR/$tdir/other_dir
20039
20040         # a should be migrated to MDT1, since no other links on MDT0
20041         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20042                 error "#1 migrate dir fails"
20043         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20044         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20045         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20046         [ $mdt_index == 1 ] || error "a is not on MDT1"
20047
20048         # a should stay on MDT1, because it is a mulitple link file
20049         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20050                 error "#2 migrate dir fails"
20051         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20052         [ $mdt_index == 1 ] || error "a is not on MDT1"
20053
20054         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20055                 error "#3 migrate dir fails"
20056
20057         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20058         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20059         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20060
20061         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20062         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20063
20064         # a should be migrated to MDT0, since no other links on MDT1
20065         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20066                 error "#4 migrate dir fails"
20067         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20068         [ $mdt_index == 0 ] || error "a is not on MDT0"
20069
20070         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20071 }
20072 run_test 230f "migrate mulitple remote link files"
20073
20074 test_230g() {
20075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20077         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20078                 skip "Need MDS version at least 2.11.52"
20079
20080         mkdir -p $DIR/$tdir/migrate_dir
20081
20082         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20083                 error "migrating dir to non-exist MDT succeeds"
20084         true
20085 }
20086 run_test 230g "migrate dir to non-exist MDT"
20087
20088 test_230h() {
20089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20091         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20092                 skip "Need MDS version at least 2.11.52"
20093
20094         local mdt_index
20095
20096         mkdir -p $DIR/$tdir/migrate_dir
20097
20098         $LFS migrate -m1 $DIR &&
20099                 error "migrating mountpoint1 should fail"
20100
20101         $LFS migrate -m1 $DIR/$tdir/.. &&
20102                 error "migrating mountpoint2 should fail"
20103
20104         # same as mv
20105         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20106                 error "migrating $tdir/migrate_dir/.. should fail"
20107
20108         true
20109 }
20110 run_test 230h "migrate .. and root"
20111
20112 test_230i() {
20113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20114         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20115         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20116                 skip "Need MDS version at least 2.11.52"
20117
20118         mkdir -p $DIR/$tdir/migrate_dir
20119
20120         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20121                 error "migration fails with a tailing slash"
20122
20123         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20124                 error "migration fails with two tailing slashes"
20125 }
20126 run_test 230i "lfs migrate -m tolerates trailing slashes"
20127
20128 test_230j() {
20129         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20130         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20131                 skip "Need MDS version at least 2.11.52"
20132
20133         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20134         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20135                 error "create $tfile failed"
20136         cat /etc/passwd > $DIR/$tdir/$tfile
20137
20138         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20139
20140         cmp /etc/passwd $DIR/$tdir/$tfile ||
20141                 error "DoM file mismatch after migration"
20142 }
20143 run_test 230j "DoM file data not changed after dir migration"
20144
20145 test_230k() {
20146         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20147         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20148                 skip "Need MDS version at least 2.11.56"
20149
20150         local total=20
20151         local files_on_starting_mdt=0
20152
20153         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20154         $LFS getdirstripe $DIR/$tdir
20155         for i in $(seq $total); do
20156                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20157                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20158                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20159         done
20160
20161         echo "$files_on_starting_mdt files on MDT0"
20162
20163         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20164         $LFS getdirstripe $DIR/$tdir
20165
20166         files_on_starting_mdt=0
20167         for i in $(seq $total); do
20168                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20169                         error "file $tfile.$i mismatch after migration"
20170                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20171                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20172         done
20173
20174         echo "$files_on_starting_mdt files on MDT1 after migration"
20175         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20176
20177         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20178         $LFS getdirstripe $DIR/$tdir
20179
20180         files_on_starting_mdt=0
20181         for i in $(seq $total); do
20182                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20183                         error "file $tfile.$i mismatch after 2nd migration"
20184                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20185                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20186         done
20187
20188         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20189         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20190
20191         true
20192 }
20193 run_test 230k "file data not changed after dir migration"
20194
20195 test_230l() {
20196         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20197         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20198                 skip "Need MDS version at least 2.11.56"
20199
20200         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20201         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20202                 error "create files under remote dir failed $i"
20203         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20204 }
20205 run_test 230l "readdir between MDTs won't crash"
20206
20207 test_230m() {
20208         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20209         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20210                 skip "Need MDS version at least 2.11.56"
20211
20212         local MDTIDX=1
20213         local mig_dir=$DIR/$tdir/migrate_dir
20214         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20215         local shortstr="b"
20216         local val
20217
20218         echo "Creating files and dirs with xattrs"
20219         test_mkdir $DIR/$tdir
20220         test_mkdir -i0 -c1 $mig_dir
20221         mkdir $mig_dir/dir
20222         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20223                 error "cannot set xattr attr1 on dir"
20224         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20225                 error "cannot set xattr attr2 on dir"
20226         touch $mig_dir/dir/f0
20227         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20228                 error "cannot set xattr attr1 on file"
20229         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20230                 error "cannot set xattr attr2 on file"
20231         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20232         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20233         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20234         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20235         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20236         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20237         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20238         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20239         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20240
20241         echo "Migrating to MDT1"
20242         $LFS migrate -m $MDTIDX $mig_dir ||
20243                 error "fails on migrating dir to MDT1"
20244
20245         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20246         echo "Checking xattrs"
20247         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20248         [ "$val" = $longstr ] ||
20249                 error "expecting xattr1 $longstr on dir, found $val"
20250         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20251         [ "$val" = $shortstr ] ||
20252                 error "expecting xattr2 $shortstr on dir, found $val"
20253         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20254         [ "$val" = $longstr ] ||
20255                 error "expecting xattr1 $longstr on file, found $val"
20256         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20257         [ "$val" = $shortstr ] ||
20258                 error "expecting xattr2 $shortstr on file, found $val"
20259 }
20260 run_test 230m "xattrs not changed after dir migration"
20261
20262 test_230n() {
20263         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20264         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20265                 skip "Need MDS version at least 2.13.53"
20266
20267         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20268         cat /etc/hosts > $DIR/$tdir/$tfile
20269         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20270         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20271
20272         cmp /etc/hosts $DIR/$tdir/$tfile ||
20273                 error "File data mismatch after migration"
20274 }
20275 run_test 230n "Dir migration with mirrored file"
20276
20277 test_230o() {
20278         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20279         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20280                 skip "Need MDS version at least 2.13.52"
20281
20282         local mdts=$(comma_list $(mdts_nodes))
20283         local timeout=100
20284         local restripe_status
20285         local delta
20286         local i
20287
20288         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20289
20290         # in case "crush" hash type is not set
20291         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20292
20293         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20294                            mdt.*MDT0000.enable_dir_restripe)
20295         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20296         stack_trap "do_nodes $mdts $LCTL set_param \
20297                     mdt.*.enable_dir_restripe=$restripe_status"
20298
20299         mkdir $DIR/$tdir
20300         createmany -m $DIR/$tdir/f 100 ||
20301                 error "create files under remote dir failed $i"
20302         createmany -d $DIR/$tdir/d 100 ||
20303                 error "create dirs under remote dir failed $i"
20304
20305         for i in $(seq 2 $MDSCOUNT); do
20306                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20307                 $LFS setdirstripe -c $i $DIR/$tdir ||
20308                         error "split -c $i $tdir failed"
20309                 wait_update $HOSTNAME \
20310                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20311                         error "dir split not finished"
20312                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20313                         awk '/migrate/ {sum += $2} END { print sum }')
20314                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20315                 # delta is around total_files/stripe_count
20316                 (( $delta < 200 / (i - 1) + 4 )) ||
20317                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20318         done
20319 }
20320 run_test 230o "dir split"
20321
20322 test_230p() {
20323         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20324         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20325                 skip "Need MDS version at least 2.13.52"
20326
20327         local mdts=$(comma_list $(mdts_nodes))
20328         local timeout=100
20329         local restripe_status
20330         local delta
20331         local c
20332
20333         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20334
20335         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20336
20337         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20338                            mdt.*MDT0000.enable_dir_restripe)
20339         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20340         stack_trap "do_nodes $mdts $LCTL set_param \
20341                     mdt.*.enable_dir_restripe=$restripe_status"
20342
20343         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20344         createmany -m $DIR/$tdir/f 100 ||
20345                 error "create files under remote dir failed"
20346         createmany -d $DIR/$tdir/d 100 ||
20347                 error "create dirs under remote dir failed"
20348
20349         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20350                 local mdt_hash="crush"
20351
20352                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20353                 $LFS setdirstripe -c $c $DIR/$tdir ||
20354                         error "split -c $c $tdir failed"
20355                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20356                         mdt_hash="$mdt_hash,fixed"
20357                 elif [ $c -eq 1 ]; then
20358                         mdt_hash="none"
20359                 fi
20360                 wait_update $HOSTNAME \
20361                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20362                         error "dir merge not finished"
20363                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20364                         awk '/migrate/ {sum += $2} END { print sum }')
20365                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20366                 # delta is around total_files/stripe_count
20367                 (( delta < 200 / c + 4 )) ||
20368                         error "$delta files migrated >= $((200 / c + 4))"
20369         done
20370 }
20371 run_test 230p "dir merge"
20372
20373 test_230q() {
20374         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20375         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20376                 skip "Need MDS version at least 2.13.52"
20377
20378         local mdts=$(comma_list $(mdts_nodes))
20379         local saved_threshold=$(do_facet mds1 \
20380                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20381         local saved_delta=$(do_facet mds1 \
20382                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20383         local threshold=100
20384         local delta=2
20385         local total=0
20386         local stripe_count=0
20387         local stripe_index
20388         local nr_files
20389         local create
20390
20391         # test with fewer files on ZFS
20392         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20393
20394         stack_trap "do_nodes $mdts $LCTL set_param \
20395                     mdt.*.dir_split_count=$saved_threshold"
20396         stack_trap "do_nodes $mdts $LCTL set_param \
20397                     mdt.*.dir_split_delta=$saved_delta"
20398         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20399         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20400         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20401         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20402         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20403         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20404
20405         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20406         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20407
20408         create=$((threshold * 3 / 2))
20409         while [ $stripe_count -lt $MDSCOUNT ]; do
20410                 createmany -m $DIR/$tdir/f $total $create ||
20411                         error "create sub files failed"
20412                 stat $DIR/$tdir > /dev/null
20413                 total=$((total + create))
20414                 stripe_count=$((stripe_count + delta))
20415                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20416
20417                 wait_update $HOSTNAME \
20418                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20419                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20420
20421                 wait_update $HOSTNAME \
20422                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20423                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20424
20425                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20426                 echo "$nr_files/$total files on MDT$stripe_index after split"
20427                 # allow 10% margin of imbalance with crush hash
20428                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20429                         error "$nr_files files on MDT$stripe_index after split"
20430
20431                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20432                 [ $nr_files -eq $total ] ||
20433                         error "total sub files $nr_files != $total"
20434         done
20435
20436         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20437
20438         echo "fixed layout directory won't auto split"
20439         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20440         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20441                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20442         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20443                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20444 }
20445 run_test 230q "dir auto split"
20446
20447 test_230r() {
20448         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20449         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20450         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20451                 skip "Need MDS version at least 2.13.54"
20452
20453         # maximum amount of local locks:
20454         # parent striped dir - 2 locks
20455         # new stripe in parent to migrate to - 1 lock
20456         # source and target - 2 locks
20457         # Total 5 locks for regular file
20458         mkdir -p $DIR/$tdir
20459         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20460         touch $DIR/$tdir/dir1/eee
20461
20462         # create 4 hardlink for 4 more locks
20463         # Total: 9 locks > RS_MAX_LOCKS (8)
20464         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20465         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20466         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20467         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20468         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20469         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20470         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20471         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20472
20473         cancel_lru_locks mdc
20474
20475         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20476                 error "migrate dir fails"
20477
20478         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20479 }
20480 run_test 230r "migrate with too many local locks"
20481
20482 test_230s() {
20483         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20484                 skip "Need MDS version at least 2.14.52"
20485
20486         local mdts=$(comma_list $(mdts_nodes))
20487         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20488                                 mdt.*MDT0000.enable_dir_restripe)
20489
20490         stack_trap "do_nodes $mdts $LCTL set_param \
20491                     mdt.*.enable_dir_restripe=$restripe_status"
20492
20493         local st
20494         for st in 0 1; do
20495                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20496                 test_mkdir $DIR/$tdir
20497                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20498                         error "$LFS mkdir should return EEXIST if target exists"
20499                 rmdir $DIR/$tdir
20500         done
20501 }
20502 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20503
20504 test_230t()
20505 {
20506         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20507         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20508                 skip "Need MDS version at least 2.14.50"
20509
20510         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20511         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20512         $LFS project -p 1 -s $DIR/$tdir ||
20513                 error "set $tdir project id failed"
20514         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20515                 error "set subdir project id failed"
20516         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20517 }
20518 run_test 230t "migrate directory with project ID set"
20519
20520 test_230u()
20521 {
20522         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20523         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20524                 skip "Need MDS version at least 2.14.53"
20525
20526         local count
20527
20528         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20529         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20530         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20531         for i in $(seq 0 $((MDSCOUNT - 1))); do
20532                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20533                 echo "$count dirs migrated to MDT$i"
20534         done
20535         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20536         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20537 }
20538 run_test 230u "migrate directory by QOS"
20539
20540 test_230v()
20541 {
20542         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20543         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20544                 skip "Need MDS version at least 2.14.53"
20545
20546         local count
20547
20548         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20549         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20550         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20551         for i in $(seq 0 $((MDSCOUNT - 1))); do
20552                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20553                 echo "$count subdirs migrated to MDT$i"
20554                 (( i == 3 )) && (( count > 0 )) &&
20555                         error "subdir shouldn't be migrated to MDT3"
20556         done
20557         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20558         (( count == 3 )) || error "dirs migrated to $count MDTs"
20559 }
20560 run_test 230v "subdir migrated to the MDT where its parent is located"
20561
20562 test_230w() {
20563         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20564         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20565                 skip "Need MDS version at least 2.14.53"
20566
20567         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20568
20569         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20570                 error "migrate failed"
20571
20572         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20573                 error "$tdir stripe count mismatch"
20574
20575         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20576                 error "$tdir/sub is striped"
20577 }
20578 run_test 230w "non-recursive mode dir migration"
20579
20580 test_231a()
20581 {
20582         # For simplicity this test assumes that max_pages_per_rpc
20583         # is the same across all OSCs
20584         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20585         local bulk_size=$((max_pages * PAGE_SIZE))
20586         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20587                                        head -n 1)
20588
20589         mkdir -p $DIR/$tdir
20590         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20591                 error "failed to set stripe with -S ${brw_size}M option"
20592
20593         # clear the OSC stats
20594         $LCTL set_param osc.*.stats=0 &>/dev/null
20595         stop_writeback
20596
20597         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20598         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20599                 oflag=direct &>/dev/null || error "dd failed"
20600
20601         sync; sleep 1; sync # just to be safe
20602         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20603         if [ x$nrpcs != "x1" ]; then
20604                 $LCTL get_param osc.*.stats
20605                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20606         fi
20607
20608         start_writeback
20609         # Drop the OSC cache, otherwise we will read from it
20610         cancel_lru_locks osc
20611
20612         # clear the OSC stats
20613         $LCTL set_param osc.*.stats=0 &>/dev/null
20614
20615         # Client reads $bulk_size.
20616         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20617                 iflag=direct &>/dev/null || error "dd failed"
20618
20619         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20620         if [ x$nrpcs != "x1" ]; then
20621                 $LCTL get_param osc.*.stats
20622                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20623         fi
20624 }
20625 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20626
20627 test_231b() {
20628         mkdir -p $DIR/$tdir
20629         local i
20630         for i in {0..1023}; do
20631                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20632                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20633                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20634         done
20635         sync
20636 }
20637 run_test 231b "must not assert on fully utilized OST request buffer"
20638
20639 test_232a() {
20640         mkdir -p $DIR/$tdir
20641         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20642
20643         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20644         do_facet ost1 $LCTL set_param fail_loc=0x31c
20645
20646         # ignore dd failure
20647         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20648
20649         do_facet ost1 $LCTL set_param fail_loc=0
20650         umount_client $MOUNT || error "umount failed"
20651         mount_client $MOUNT || error "mount failed"
20652         stop ost1 || error "cannot stop ost1"
20653         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20654 }
20655 run_test 232a "failed lock should not block umount"
20656
20657 test_232b() {
20658         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20659                 skip "Need MDS version at least 2.10.58"
20660
20661         mkdir -p $DIR/$tdir
20662         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20663         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20664         sync
20665         cancel_lru_locks osc
20666
20667         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20668         do_facet ost1 $LCTL set_param fail_loc=0x31c
20669
20670         # ignore failure
20671         $LFS data_version $DIR/$tdir/$tfile || true
20672
20673         do_facet ost1 $LCTL set_param fail_loc=0
20674         umount_client $MOUNT || error "umount failed"
20675         mount_client $MOUNT || error "mount failed"
20676         stop ost1 || error "cannot stop ost1"
20677         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20678 }
20679 run_test 232b "failed data version lock should not block umount"
20680
20681 test_233a() {
20682         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20683                 skip "Need MDS version at least 2.3.64"
20684         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20685
20686         local fid=$($LFS path2fid $MOUNT)
20687
20688         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20689                 error "cannot access $MOUNT using its FID '$fid'"
20690 }
20691 run_test 233a "checking that OBF of the FS root succeeds"
20692
20693 test_233b() {
20694         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20695                 skip "Need MDS version at least 2.5.90"
20696         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20697
20698         local fid=$($LFS path2fid $MOUNT/.lustre)
20699
20700         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20701                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20702
20703         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20704         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20705                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20706 }
20707 run_test 233b "checking that OBF of the FS .lustre succeeds"
20708
20709 test_234() {
20710         local p="$TMP/sanityN-$TESTNAME.parameters"
20711         save_lustre_params client "llite.*.xattr_cache" > $p
20712         lctl set_param llite.*.xattr_cache 1 ||
20713                 skip_env "xattr cache is not supported"
20714
20715         mkdir -p $DIR/$tdir || error "mkdir failed"
20716         touch $DIR/$tdir/$tfile || error "touch failed"
20717         # OBD_FAIL_LLITE_XATTR_ENOMEM
20718         $LCTL set_param fail_loc=0x1405
20719         getfattr -n user.attr $DIR/$tdir/$tfile &&
20720                 error "getfattr should have failed with ENOMEM"
20721         $LCTL set_param fail_loc=0x0
20722         rm -rf $DIR/$tdir
20723
20724         restore_lustre_params < $p
20725         rm -f $p
20726 }
20727 run_test 234 "xattr cache should not crash on ENOMEM"
20728
20729 test_235() {
20730         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20731                 skip "Need MDS version at least 2.4.52"
20732
20733         flock_deadlock $DIR/$tfile
20734         local RC=$?
20735         case $RC in
20736                 0)
20737                 ;;
20738                 124) error "process hangs on a deadlock"
20739                 ;;
20740                 *) error "error executing flock_deadlock $DIR/$tfile"
20741                 ;;
20742         esac
20743 }
20744 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20745
20746 #LU-2935
20747 test_236() {
20748         check_swap_layouts_support
20749
20750         local ref1=/etc/passwd
20751         local ref2=/etc/group
20752         local file1=$DIR/$tdir/f1
20753         local file2=$DIR/$tdir/f2
20754
20755         test_mkdir -c1 $DIR/$tdir
20756         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20757         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20758         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20759         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20760         local fd=$(free_fd)
20761         local cmd="exec $fd<>$file2"
20762         eval $cmd
20763         rm $file2
20764         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20765                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20766         cmd="exec $fd>&-"
20767         eval $cmd
20768         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20769
20770         #cleanup
20771         rm -rf $DIR/$tdir
20772 }
20773 run_test 236 "Layout swap on open unlinked file"
20774
20775 # LU-4659 linkea consistency
20776 test_238() {
20777         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20778                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20779                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20780                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20781
20782         touch $DIR/$tfile
20783         ln $DIR/$tfile $DIR/$tfile.lnk
20784         touch $DIR/$tfile.new
20785         mv $DIR/$tfile.new $DIR/$tfile
20786         local fid1=$($LFS path2fid $DIR/$tfile)
20787         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20788         local path1=$($LFS fid2path $FSNAME "$fid1")
20789         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20790         local path2=$($LFS fid2path $FSNAME "$fid2")
20791         [ $tfile.lnk == $path2 ] ||
20792                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20793         rm -f $DIR/$tfile*
20794 }
20795 run_test 238 "Verify linkea consistency"
20796
20797 test_239A() { # was test_239
20798         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20799                 skip "Need MDS version at least 2.5.60"
20800
20801         local list=$(comma_list $(mdts_nodes))
20802
20803         mkdir -p $DIR/$tdir
20804         createmany -o $DIR/$tdir/f- 5000
20805         unlinkmany $DIR/$tdir/f- 5000
20806         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20807                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20808         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20809                         osp.*MDT*.sync_in_flight" | calc_sum)
20810         [ "$changes" -eq 0 ] || error "$changes not synced"
20811 }
20812 run_test 239A "osp_sync test"
20813
20814 test_239a() { #LU-5297
20815         remote_mds_nodsh && skip "remote MDS with nodsh"
20816
20817         touch $DIR/$tfile
20818         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20819         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20820         chgrp $RUNAS_GID $DIR/$tfile
20821         wait_delete_completed
20822 }
20823 run_test 239a "process invalid osp sync record correctly"
20824
20825 test_239b() { #LU-5297
20826         remote_mds_nodsh && skip "remote MDS with nodsh"
20827
20828         touch $DIR/$tfile1
20829         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20830         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20831         chgrp $RUNAS_GID $DIR/$tfile1
20832         wait_delete_completed
20833         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20834         touch $DIR/$tfile2
20835         chgrp $RUNAS_GID $DIR/$tfile2
20836         wait_delete_completed
20837 }
20838 run_test 239b "process osp sync record with ENOMEM error correctly"
20839
20840 test_240() {
20841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20842         remote_mds_nodsh && skip "remote MDS with nodsh"
20843
20844         mkdir -p $DIR/$tdir
20845
20846         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20847                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20848         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20849                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20850
20851         umount_client $MOUNT || error "umount failed"
20852         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20853         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20854         mount_client $MOUNT || error "failed to mount client"
20855
20856         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20857         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20858 }
20859 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20860
20861 test_241_bio() {
20862         local count=$1
20863         local bsize=$2
20864
20865         for LOOP in $(seq $count); do
20866                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20867                 cancel_lru_locks $OSC || true
20868         done
20869 }
20870
20871 test_241_dio() {
20872         local count=$1
20873         local bsize=$2
20874
20875         for LOOP in $(seq $1); do
20876                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20877                         2>/dev/null
20878         done
20879 }
20880
20881 test_241a() { # was test_241
20882         local bsize=$PAGE_SIZE
20883
20884         (( bsize < 40960 )) && bsize=40960
20885         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20886         ls -la $DIR/$tfile
20887         cancel_lru_locks $OSC
20888         test_241_bio 1000 $bsize &
20889         PID=$!
20890         test_241_dio 1000 $bsize
20891         wait $PID
20892 }
20893 run_test 241a "bio vs dio"
20894
20895 test_241b() {
20896         local bsize=$PAGE_SIZE
20897
20898         (( bsize < 40960 )) && bsize=40960
20899         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20900         ls -la $DIR/$tfile
20901         test_241_dio 1000 $bsize &
20902         PID=$!
20903         test_241_dio 1000 $bsize
20904         wait $PID
20905 }
20906 run_test 241b "dio vs dio"
20907
20908 test_242() {
20909         remote_mds_nodsh && skip "remote MDS with nodsh"
20910
20911         mkdir_on_mdt0 $DIR/$tdir
20912         touch $DIR/$tdir/$tfile
20913
20914         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20915         do_facet mds1 lctl set_param fail_loc=0x105
20916         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20917
20918         do_facet mds1 lctl set_param fail_loc=0
20919         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20920 }
20921 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20922
20923 test_243()
20924 {
20925         test_mkdir $DIR/$tdir
20926         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20927 }
20928 run_test 243 "various group lock tests"
20929
20930 test_244a()
20931 {
20932         test_mkdir $DIR/$tdir
20933         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20934         sendfile_grouplock $DIR/$tdir/$tfile || \
20935                 error "sendfile+grouplock failed"
20936         rm -rf $DIR/$tdir
20937 }
20938 run_test 244a "sendfile with group lock tests"
20939
20940 test_244b()
20941 {
20942         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20943
20944         local threads=50
20945         local size=$((1024*1024))
20946
20947         test_mkdir $DIR/$tdir
20948         for i in $(seq 1 $threads); do
20949                 local file=$DIR/$tdir/file_$((i / 10))
20950                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20951                 local pids[$i]=$!
20952         done
20953         for i in $(seq 1 $threads); do
20954                 wait ${pids[$i]}
20955         done
20956 }
20957 run_test 244b "multi-threaded write with group lock"
20958
20959 test_245a() {
20960         local flagname="multi_mod_rpcs"
20961         local connect_data_name="max_mod_rpcs"
20962         local out
20963
20964         # check if multiple modify RPCs flag is set
20965         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20966                 grep "connect_flags:")
20967         echo "$out"
20968
20969         echo "$out" | grep -qw $flagname
20970         if [ $? -ne 0 ]; then
20971                 echo "connect flag $flagname is not set"
20972                 return
20973         fi
20974
20975         # check if multiple modify RPCs data is set
20976         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20977         echo "$out"
20978
20979         echo "$out" | grep -qw $connect_data_name ||
20980                 error "import should have connect data $connect_data_name"
20981 }
20982 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
20983
20984 test_245b() {
20985         local flagname="multi_mod_rpcs"
20986         local connect_data_name="max_mod_rpcs"
20987         local out
20988
20989         remote_mds_nodsh && skip "remote MDS with nodsh"
20990         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
20991
20992         # check if multiple modify RPCs flag is set
20993         out=$(do_facet mds1 \
20994               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
20995               grep "connect_flags:")
20996         echo "$out"
20997
20998         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
20999
21000         # check if multiple modify RPCs data is set
21001         out=$(do_facet mds1 \
21002               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21003
21004         [[ "$out" =~ $connect_data_name ]] ||
21005                 {
21006                         echo "$out"
21007                         error "missing connect data $connect_data_name"
21008                 }
21009 }
21010 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21011
21012 cleanup_247() {
21013         local submount=$1
21014
21015         trap 0
21016         umount_client $submount
21017         rmdir $submount
21018 }
21019
21020 test_247a() {
21021         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21022                 grep -q subtree ||
21023                 skip_env "Fileset feature is not supported"
21024
21025         local submount=${MOUNT}_$tdir
21026
21027         mkdir $MOUNT/$tdir
21028         mkdir -p $submount || error "mkdir $submount failed"
21029         FILESET="$FILESET/$tdir" mount_client $submount ||
21030                 error "mount $submount failed"
21031         trap "cleanup_247 $submount" EXIT
21032         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21033         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21034                 error "read $MOUNT/$tdir/$tfile failed"
21035         cleanup_247 $submount
21036 }
21037 run_test 247a "mount subdir as fileset"
21038
21039 test_247b() {
21040         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21041                 skip_env "Fileset feature is not supported"
21042
21043         local submount=${MOUNT}_$tdir
21044
21045         rm -rf $MOUNT/$tdir
21046         mkdir -p $submount || error "mkdir $submount failed"
21047         SKIP_FILESET=1
21048         FILESET="$FILESET/$tdir" mount_client $submount &&
21049                 error "mount $submount should fail"
21050         rmdir $submount
21051 }
21052 run_test 247b "mount subdir that dose not exist"
21053
21054 test_247c() {
21055         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21056                 skip_env "Fileset feature is not supported"
21057
21058         local submount=${MOUNT}_$tdir
21059
21060         mkdir -p $MOUNT/$tdir/dir1
21061         mkdir -p $submount || error "mkdir $submount failed"
21062         trap "cleanup_247 $submount" EXIT
21063         FILESET="$FILESET/$tdir" mount_client $submount ||
21064                 error "mount $submount failed"
21065         local fid=$($LFS path2fid $MOUNT/)
21066         $LFS fid2path $submount $fid && error "fid2path should fail"
21067         cleanup_247 $submount
21068 }
21069 run_test 247c "running fid2path outside subdirectory root"
21070
21071 test_247d() {
21072         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21073                 skip "Fileset feature is not supported"
21074
21075         local submount=${MOUNT}_$tdir
21076
21077         mkdir -p $MOUNT/$tdir/dir1
21078         mkdir -p $submount || error "mkdir $submount failed"
21079         FILESET="$FILESET/$tdir" mount_client $submount ||
21080                 error "mount $submount failed"
21081         trap "cleanup_247 $submount" EXIT
21082
21083         local td=$submount/dir1
21084         local fid=$($LFS path2fid $td)
21085         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21086
21087         # check that we get the same pathname back
21088         local rootpath
21089         local found
21090         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21091                 echo "$rootpath $fid"
21092                 found=$($LFS fid2path $rootpath "$fid")
21093                 [ -n "$found" ] || error "fid2path should succeed"
21094                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21095         done
21096         # check wrong root path format
21097         rootpath=$submount"_wrong"
21098         found=$($LFS fid2path $rootpath "$fid")
21099         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21100
21101         cleanup_247 $submount
21102 }
21103 run_test 247d "running fid2path inside subdirectory root"
21104
21105 # LU-8037
21106 test_247e() {
21107         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21108                 grep -q subtree ||
21109                 skip "Fileset feature is not supported"
21110
21111         local submount=${MOUNT}_$tdir
21112
21113         mkdir $MOUNT/$tdir
21114         mkdir -p $submount || error "mkdir $submount failed"
21115         FILESET="$FILESET/.." mount_client $submount &&
21116                 error "mount $submount should fail"
21117         rmdir $submount
21118 }
21119 run_test 247e "mount .. as fileset"
21120
21121 test_247f() {
21122         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21123         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21124                 skip "Need at least version 2.13.52"
21125         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21126                 skip "Need at least version 2.14.50"
21127         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21128                 grep -q subtree ||
21129                 skip "Fileset feature is not supported"
21130
21131         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21132         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21133                 error "mkdir remote failed"
21134         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21135                 error "mkdir remote/subdir failed"
21136         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21137                 error "mkdir striped failed"
21138         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21139
21140         local submount=${MOUNT}_$tdir
21141
21142         mkdir -p $submount || error "mkdir $submount failed"
21143         stack_trap "rmdir $submount"
21144
21145         local dir
21146         local stat
21147         local fileset=$FILESET
21148         local mdts=$(comma_list $(mdts_nodes))
21149
21150         stat=$(do_facet mds1 $LCTL get_param -n \
21151                 mdt.*MDT0000.enable_remote_subdir_mount)
21152         stack_trap "do_nodes $mdts $LCTL set_param \
21153                 mdt.*.enable_remote_subdir_mount=$stat"
21154
21155         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21156         stack_trap "umount_client $submount"
21157         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21158                 error "mount remote dir $dir should fail"
21159
21160         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21161                 $tdir/striped/. ; do
21162                 FILESET="$fileset/$dir" mount_client $submount ||
21163                         error "mount $dir failed"
21164                 umount_client $submount
21165         done
21166
21167         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21168         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21169                 error "mount $tdir/remote failed"
21170 }
21171 run_test 247f "mount striped or remote directory as fileset"
21172
21173 test_247g() {
21174         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21175         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21176                 skip "Need at least version 2.14.50"
21177
21178         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21179                 error "mkdir $tdir failed"
21180         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21181
21182         local submount=${MOUNT}_$tdir
21183
21184         mkdir -p $submount || error "mkdir $submount failed"
21185         stack_trap "rmdir $submount"
21186
21187         FILESET="$fileset/$tdir" mount_client $submount ||
21188                 error "mount $dir failed"
21189         stack_trap "umount $submount"
21190
21191         local mdts=$(comma_list $(mdts_nodes))
21192
21193         local nrpcs
21194
21195         stat $submount > /dev/null
21196         cancel_lru_locks $MDC
21197         stat $submount > /dev/null
21198         stat $submount/$tfile > /dev/null
21199         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21200         stat $submount/$tfile > /dev/null
21201         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21202                 awk '/getattr/ {sum += $2} END {print sum}')
21203
21204         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21205 }
21206 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21207
21208 test_248a() {
21209         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21210         [ -z "$fast_read_sav" ] && skip "no fast read support"
21211
21212         # create a large file for fast read verification
21213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21214
21215         # make sure the file is created correctly
21216         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21217                 { rm -f $DIR/$tfile; skip "file creation error"; }
21218
21219         echo "Test 1: verify that fast read is 4 times faster on cache read"
21220
21221         # small read with fast read enabled
21222         $LCTL set_param -n llite.*.fast_read=1
21223         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21224                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21225                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21226         # small read with fast read disabled
21227         $LCTL set_param -n llite.*.fast_read=0
21228         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21229                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21230                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21231
21232         # verify that fast read is 4 times faster for cache read
21233         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21234                 error_not_in_vm "fast read was not 4 times faster: " \
21235                            "$t_fast vs $t_slow"
21236
21237         echo "Test 2: verify the performance between big and small read"
21238         $LCTL set_param -n llite.*.fast_read=1
21239
21240         # 1k non-cache read
21241         cancel_lru_locks osc
21242         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21243                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21244                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21245
21246         # 1M non-cache read
21247         cancel_lru_locks osc
21248         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21249                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21250                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21251
21252         # verify that big IO is not 4 times faster than small IO
21253         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21254                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21255
21256         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21257         rm -f $DIR/$tfile
21258 }
21259 run_test 248a "fast read verification"
21260
21261 test_248b() {
21262         # Default short_io_bytes=16384, try both smaller and larger sizes.
21263         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21264         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21265         echo "bs=53248 count=113 normal buffered write"
21266         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21267                 error "dd of initial data file failed"
21268         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21269
21270         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21271         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21272                 error "dd with sync normal writes failed"
21273         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21274
21275         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21276         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21277                 error "dd with sync small writes failed"
21278         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21279
21280         cancel_lru_locks osc
21281
21282         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21283         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21284         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21285         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21286                 iflag=direct || error "dd with O_DIRECT small read failed"
21287         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21288         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21289                 error "compare $TMP/$tfile.1 failed"
21290
21291         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21292         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21293
21294         # just to see what the maximum tunable value is, and test parsing
21295         echo "test invalid parameter 2MB"
21296         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21297                 error "too-large short_io_bytes allowed"
21298         echo "test maximum parameter 512KB"
21299         # if we can set a larger short_io_bytes, run test regardless of version
21300         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21301                 # older clients may not allow setting it this large, that's OK
21302                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21303                         skip "Need at least client version 2.13.50"
21304                 error "medium short_io_bytes failed"
21305         fi
21306         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21307         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21308
21309         echo "test large parameter 64KB"
21310         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21311         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21312
21313         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21314         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21315                 error "dd with sync large writes failed"
21316         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21317
21318         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21319         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21320         num=$((113 * 4096 / PAGE_SIZE))
21321         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21322         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21323                 error "dd with O_DIRECT large writes failed"
21324         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21325                 error "compare $DIR/$tfile.3 failed"
21326
21327         cancel_lru_locks osc
21328
21329         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21330         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21331                 error "dd with O_DIRECT large read failed"
21332         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21333                 error "compare $TMP/$tfile.2 failed"
21334
21335         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21336         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21337                 error "dd with O_DIRECT large read failed"
21338         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21339                 error "compare $TMP/$tfile.3 failed"
21340 }
21341 run_test 248b "test short_io read and write for both small and large sizes"
21342
21343 test_249() { # LU-7890
21344         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21345                 skip "Need at least version 2.8.54"
21346
21347         rm -f $DIR/$tfile
21348         $LFS setstripe -c 1 $DIR/$tfile
21349         # Offset 2T == 4k * 512M
21350         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21351                 error "dd to 2T offset failed"
21352 }
21353 run_test 249 "Write above 2T file size"
21354
21355 test_250() {
21356         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21357          && skip "no 16TB file size limit on ZFS"
21358
21359         $LFS setstripe -c 1 $DIR/$tfile
21360         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21361         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21362         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21363         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21364                 conv=notrunc,fsync && error "append succeeded"
21365         return 0
21366 }
21367 run_test 250 "Write above 16T limit"
21368
21369 test_251() {
21370         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21371
21372         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21373         #Skip once - writing the first stripe will succeed
21374         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21375         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21376                 error "short write happened"
21377
21378         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21379         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21380                 error "short read happened"
21381
21382         rm -f $DIR/$tfile
21383 }
21384 run_test 251 "Handling short read and write correctly"
21385
21386 test_252() {
21387         remote_mds_nodsh && skip "remote MDS with nodsh"
21388         remote_ost_nodsh && skip "remote OST with nodsh"
21389         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21390                 skip_env "ldiskfs only test"
21391         fi
21392
21393         local tgt
21394         local dev
21395         local out
21396         local uuid
21397         local num
21398         local gen
21399
21400         # check lr_reader on OST0000
21401         tgt=ost1
21402         dev=$(facet_device $tgt)
21403         out=$(do_facet $tgt $LR_READER $dev)
21404         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21405         echo "$out"
21406         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21407         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21408                 error "Invalid uuid returned by $LR_READER on target $tgt"
21409         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21410
21411         # check lr_reader -c on MDT0000
21412         tgt=mds1
21413         dev=$(facet_device $tgt)
21414         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21415                 skip "$LR_READER does not support additional options"
21416         fi
21417         out=$(do_facet $tgt $LR_READER -c $dev)
21418         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21419         echo "$out"
21420         num=$(echo "$out" | grep -c "mdtlov")
21421         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21422                 error "Invalid number of mdtlov clients returned by $LR_READER"
21423         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21424
21425         # check lr_reader -cr on MDT0000
21426         out=$(do_facet $tgt $LR_READER -cr $dev)
21427         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21428         echo "$out"
21429         echo "$out" | grep -q "^reply_data:$" ||
21430                 error "$LR_READER should have returned 'reply_data' section"
21431         num=$(echo "$out" | grep -c "client_generation")
21432         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21433 }
21434 run_test 252 "check lr_reader tool"
21435
21436 test_253() {
21437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21438         remote_mds_nodsh && skip "remote MDS with nodsh"
21439         remote_mgs_nodsh && skip "remote MGS with nodsh"
21440
21441         local ostidx=0
21442         local rc=0
21443         local ost_name=$(ostname_from_index $ostidx)
21444
21445         # on the mdt's osc
21446         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21447         do_facet $SINGLEMDS $LCTL get_param -n \
21448                 osp.$mdtosc_proc1.reserved_mb_high ||
21449                 skip  "remote MDS does not support reserved_mb_high"
21450
21451         rm -rf $DIR/$tdir
21452         wait_mds_ost_sync
21453         wait_delete_completed
21454         mkdir $DIR/$tdir
21455
21456         pool_add $TESTNAME || error "Pool creation failed"
21457         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21458
21459         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21460                 error "Setstripe failed"
21461
21462         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21463
21464         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21465                     grep "watermarks")
21466         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21467
21468         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21469                         osp.$mdtosc_proc1.prealloc_status)
21470         echo "prealloc_status $oa_status"
21471
21472         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21473                 error "File creation should fail"
21474
21475         #object allocation was stopped, but we still able to append files
21476         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21477                 oflag=append || error "Append failed"
21478
21479         rm -f $DIR/$tdir/$tfile.0
21480
21481         # For this test, we want to delete the files we created to go out of
21482         # space but leave the watermark, so we remain nearly out of space
21483         ost_watermarks_enospc_delete_files $tfile $ostidx
21484
21485         wait_delete_completed
21486
21487         sleep_maxage
21488
21489         for i in $(seq 10 12); do
21490                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21491                         2>/dev/null || error "File creation failed after rm"
21492         done
21493
21494         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21495                         osp.$mdtosc_proc1.prealloc_status)
21496         echo "prealloc_status $oa_status"
21497
21498         if (( oa_status != 0 )); then
21499                 error "Object allocation still disable after rm"
21500         fi
21501 }
21502 run_test 253 "Check object allocation limit"
21503
21504 test_254() {
21505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21506         remote_mds_nodsh && skip "remote MDS with nodsh"
21507
21508         local mdt=$(facet_svc $SINGLEMDS)
21509
21510         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21511                 skip "MDS does not support changelog_size"
21512
21513         local cl_user
21514
21515         changelog_register || error "changelog_register failed"
21516
21517         changelog_clear 0 || error "changelog_clear failed"
21518
21519         local size1=$(do_facet $SINGLEMDS \
21520                       $LCTL get_param -n mdd.$mdt.changelog_size)
21521         echo "Changelog size $size1"
21522
21523         rm -rf $DIR/$tdir
21524         $LFS mkdir -i 0 $DIR/$tdir
21525         # change something
21526         mkdir -p $DIR/$tdir/pics/2008/zachy
21527         touch $DIR/$tdir/pics/2008/zachy/timestamp
21528         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21529         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21530         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21531         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21532         rm $DIR/$tdir/pics/desktop.jpg
21533
21534         local size2=$(do_facet $SINGLEMDS \
21535                       $LCTL get_param -n mdd.$mdt.changelog_size)
21536         echo "Changelog size after work $size2"
21537
21538         (( $size2 > $size1 )) ||
21539                 error "new Changelog size=$size2 less than old size=$size1"
21540 }
21541 run_test 254 "Check changelog size"
21542
21543 ladvise_no_type()
21544 {
21545         local type=$1
21546         local file=$2
21547
21548         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21549                 awk -F: '{print $2}' | grep $type > /dev/null
21550         if [ $? -ne 0 ]; then
21551                 return 0
21552         fi
21553         return 1
21554 }
21555
21556 ladvise_no_ioctl()
21557 {
21558         local file=$1
21559
21560         lfs ladvise -a willread $file > /dev/null 2>&1
21561         if [ $? -eq 0 ]; then
21562                 return 1
21563         fi
21564
21565         lfs ladvise -a willread $file 2>&1 |
21566                 grep "Inappropriate ioctl for device" > /dev/null
21567         if [ $? -eq 0 ]; then
21568                 return 0
21569         fi
21570         return 1
21571 }
21572
21573 percent() {
21574         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21575 }
21576
21577 # run a random read IO workload
21578 # usage: random_read_iops <filename> <filesize> <iosize>
21579 random_read_iops() {
21580         local file=$1
21581         local fsize=$2
21582         local iosize=${3:-4096}
21583
21584         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21585                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21586 }
21587
21588 drop_file_oss_cache() {
21589         local file="$1"
21590         local nodes="$2"
21591
21592         $LFS ladvise -a dontneed $file 2>/dev/null ||
21593                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21594 }
21595
21596 ladvise_willread_performance()
21597 {
21598         local repeat=10
21599         local average_origin=0
21600         local average_cache=0
21601         local average_ladvise=0
21602
21603         for ((i = 1; i <= $repeat; i++)); do
21604                 echo "Iter $i/$repeat: reading without willread hint"
21605                 cancel_lru_locks osc
21606                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21607                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21608                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21609                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21610
21611                 cancel_lru_locks osc
21612                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21613                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21614                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21615
21616                 cancel_lru_locks osc
21617                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21618                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21619                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21620                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21621                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21622         done
21623         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21624         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21625         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21626
21627         speedup_cache=$(percent $average_cache $average_origin)
21628         speedup_ladvise=$(percent $average_ladvise $average_origin)
21629
21630         echo "Average uncached read: $average_origin"
21631         echo "Average speedup with OSS cached read: " \
21632                 "$average_cache = +$speedup_cache%"
21633         echo "Average speedup with ladvise willread: " \
21634                 "$average_ladvise = +$speedup_ladvise%"
21635
21636         local lowest_speedup=20
21637         if (( ${average_cache%.*} < $lowest_speedup )); then
21638                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21639                      " got $average_cache%. Skipping ladvise willread check."
21640                 return 0
21641         fi
21642
21643         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21644         # it is still good to run until then to exercise 'ladvise willread'
21645         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21646                 [ "$ost1_FSTYPE" = "zfs" ] &&
21647                 echo "osd-zfs does not support dontneed or drop_caches" &&
21648                 return 0
21649
21650         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21651         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21652                 error_not_in_vm "Speedup with willread is less than " \
21653                         "$lowest_speedup%, got $average_ladvise%"
21654 }
21655
21656 test_255a() {
21657         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21658                 skip "lustre < 2.8.54 does not support ladvise "
21659         remote_ost_nodsh && skip "remote OST with nodsh"
21660
21661         stack_trap "rm -f $DIR/$tfile"
21662         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21663
21664         ladvise_no_type willread $DIR/$tfile &&
21665                 skip "willread ladvise is not supported"
21666
21667         ladvise_no_ioctl $DIR/$tfile &&
21668                 skip "ladvise ioctl is not supported"
21669
21670         local size_mb=100
21671         local size=$((size_mb * 1048576))
21672         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21673                 error "dd to $DIR/$tfile failed"
21674
21675         lfs ladvise -a willread $DIR/$tfile ||
21676                 error "Ladvise failed with no range argument"
21677
21678         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21679                 error "Ladvise failed with no -l or -e argument"
21680
21681         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21682                 error "Ladvise failed with only -e argument"
21683
21684         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21685                 error "Ladvise failed with only -l argument"
21686
21687         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21688                 error "End offset should not be smaller than start offset"
21689
21690         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21691                 error "End offset should not be equal to start offset"
21692
21693         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21694                 error "Ladvise failed with overflowing -s argument"
21695
21696         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21697                 error "Ladvise failed with overflowing -e argument"
21698
21699         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21700                 error "Ladvise failed with overflowing -l argument"
21701
21702         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21703                 error "Ladvise succeeded with conflicting -l and -e arguments"
21704
21705         echo "Synchronous ladvise should wait"
21706         local delay=4
21707 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21708         do_nodes $(comma_list $(osts_nodes)) \
21709                 $LCTL set_param fail_val=$delay fail_loc=0x237
21710
21711         local start_ts=$SECONDS
21712         lfs ladvise -a willread $DIR/$tfile ||
21713                 error "Ladvise failed with no range argument"
21714         local end_ts=$SECONDS
21715         local inteval_ts=$((end_ts - start_ts))
21716
21717         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21718                 error "Synchronous advice didn't wait reply"
21719         fi
21720
21721         echo "Asynchronous ladvise shouldn't wait"
21722         local start_ts=$SECONDS
21723         lfs ladvise -a willread -b $DIR/$tfile ||
21724                 error "Ladvise failed with no range argument"
21725         local end_ts=$SECONDS
21726         local inteval_ts=$((end_ts - start_ts))
21727
21728         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21729                 error "Asynchronous advice blocked"
21730         fi
21731
21732         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21733         ladvise_willread_performance
21734 }
21735 run_test 255a "check 'lfs ladvise -a willread'"
21736
21737 facet_meminfo() {
21738         local facet=$1
21739         local info=$2
21740
21741         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21742 }
21743
21744 test_255b() {
21745         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21746                 skip "lustre < 2.8.54 does not support ladvise "
21747         remote_ost_nodsh && skip "remote OST with nodsh"
21748
21749         stack_trap "rm -f $DIR/$tfile"
21750         lfs setstripe -c 1 -i 0 $DIR/$tfile
21751
21752         ladvise_no_type dontneed $DIR/$tfile &&
21753                 skip "dontneed ladvise is not supported"
21754
21755         ladvise_no_ioctl $DIR/$tfile &&
21756                 skip "ladvise ioctl is not supported"
21757
21758         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21759                 [ "$ost1_FSTYPE" = "zfs" ] &&
21760                 skip "zfs-osd does not support 'ladvise dontneed'"
21761
21762         local size_mb=100
21763         local size=$((size_mb * 1048576))
21764         # In order to prevent disturbance of other processes, only check 3/4
21765         # of the memory usage
21766         local kibibytes=$((size_mb * 1024 * 3 / 4))
21767
21768         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21769                 error "dd to $DIR/$tfile failed"
21770
21771         #force write to complete before dropping OST cache & checking memory
21772         sync
21773
21774         local total=$(facet_meminfo ost1 MemTotal)
21775         echo "Total memory: $total KiB"
21776
21777         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21778         local before_read=$(facet_meminfo ost1 Cached)
21779         echo "Cache used before read: $before_read KiB"
21780
21781         lfs ladvise -a willread $DIR/$tfile ||
21782                 error "Ladvise willread failed"
21783         local after_read=$(facet_meminfo ost1 Cached)
21784         echo "Cache used after read: $after_read KiB"
21785
21786         lfs ladvise -a dontneed $DIR/$tfile ||
21787                 error "Ladvise dontneed again failed"
21788         local no_read=$(facet_meminfo ost1 Cached)
21789         echo "Cache used after dontneed ladvise: $no_read KiB"
21790
21791         if [ $total -lt $((before_read + kibibytes)) ]; then
21792                 echo "Memory is too small, abort checking"
21793                 return 0
21794         fi
21795
21796         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21797                 error "Ladvise willread should use more memory" \
21798                         "than $kibibytes KiB"
21799         fi
21800
21801         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21802                 error "Ladvise dontneed should release more memory" \
21803                         "than $kibibytes KiB"
21804         fi
21805 }
21806 run_test 255b "check 'lfs ladvise -a dontneed'"
21807
21808 test_255c() {
21809         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21810                 skip "lustre < 2.10.50 does not support lockahead"
21811
21812         local ost1_imp=$(get_osc_import_name client ost1)
21813         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21814                          cut -d'.' -f2)
21815         local count
21816         local new_count
21817         local difference
21818         local i
21819         local rc
21820
21821         test_mkdir -p $DIR/$tdir
21822         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21823
21824         #test 10 returns only success/failure
21825         i=10
21826         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21827         rc=$?
21828         if [ $rc -eq 255 ]; then
21829                 error "Ladvise test${i} failed, ${rc}"
21830         fi
21831
21832         #test 11 counts lock enqueue requests, all others count new locks
21833         i=11
21834         count=$(do_facet ost1 \
21835                 $LCTL get_param -n ost.OSS.ost.stats)
21836         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21837
21838         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21839         rc=$?
21840         if [ $rc -eq 255 ]; then
21841                 error "Ladvise test${i} failed, ${rc}"
21842         fi
21843
21844         new_count=$(do_facet ost1 \
21845                 $LCTL get_param -n ost.OSS.ost.stats)
21846         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21847                    awk '{ print $2 }')
21848
21849         difference="$((new_count - count))"
21850         if [ $difference -ne $rc ]; then
21851                 error "Ladvise test${i}, bad enqueue count, returned " \
21852                       "${rc}, actual ${difference}"
21853         fi
21854
21855         for i in $(seq 12 21); do
21856                 # If we do not do this, we run the risk of having too many
21857                 # locks and starting lock cancellation while we are checking
21858                 # lock counts.
21859                 cancel_lru_locks osc
21860
21861                 count=$($LCTL get_param -n \
21862                        ldlm.namespaces.$imp_name.lock_unused_count)
21863
21864                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21865                 rc=$?
21866                 if [ $rc -eq 255 ]; then
21867                         error "Ladvise test ${i} failed, ${rc}"
21868                 fi
21869
21870                 new_count=$($LCTL get_param -n \
21871                        ldlm.namespaces.$imp_name.lock_unused_count)
21872                 difference="$((new_count - count))"
21873
21874                 # Test 15 output is divided by 100 to map down to valid return
21875                 if [ $i -eq 15 ]; then
21876                         rc="$((rc * 100))"
21877                 fi
21878
21879                 if [ $difference -ne $rc ]; then
21880                         error "Ladvise test ${i}, bad lock count, returned " \
21881                               "${rc}, actual ${difference}"
21882                 fi
21883         done
21884
21885         #test 22 returns only success/failure
21886         i=22
21887         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21888         rc=$?
21889         if [ $rc -eq 255 ]; then
21890                 error "Ladvise test${i} failed, ${rc}"
21891         fi
21892 }
21893 run_test 255c "suite of ladvise lockahead tests"
21894
21895 test_256() {
21896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21897         remote_mds_nodsh && skip "remote MDS with nodsh"
21898         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21899         changelog_users $SINGLEMDS | grep "^cl" &&
21900                 skip "active changelog user"
21901
21902         local cl_user
21903         local cat_sl
21904         local mdt_dev
21905
21906         mdt_dev=$(facet_device $SINGLEMDS)
21907         echo $mdt_dev
21908
21909         changelog_register || error "changelog_register failed"
21910
21911         rm -rf $DIR/$tdir
21912         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21913
21914         changelog_clear 0 || error "changelog_clear failed"
21915
21916         # change something
21917         touch $DIR/$tdir/{1..10}
21918
21919         # stop the MDT
21920         stop $SINGLEMDS || error "Fail to stop MDT"
21921
21922         # remount the MDT
21923         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21924                 error "Fail to start MDT"
21925
21926         #after mount new plainllog is used
21927         touch $DIR/$tdir/{11..19}
21928         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21929         stack_trap "rm -f $tmpfile"
21930         cat_sl=$(do_facet $SINGLEMDS "sync; \
21931                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21932                  llog_reader $tmpfile | grep -c type=1064553b")
21933         do_facet $SINGLEMDS llog_reader $tmpfile
21934
21935         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21936
21937         changelog_clear 0 || error "changelog_clear failed"
21938
21939         cat_sl=$(do_facet $SINGLEMDS "sync; \
21940                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21941                  llog_reader $tmpfile | grep -c type=1064553b")
21942
21943         if (( cat_sl == 2 )); then
21944                 error "Empty plain llog was not deleted from changelog catalog"
21945         elif (( cat_sl != 1 )); then
21946                 error "Active plain llog shouldn't be deleted from catalog"
21947         fi
21948 }
21949 run_test 256 "Check llog delete for empty and not full state"
21950
21951 test_257() {
21952         remote_mds_nodsh && skip "remote MDS with nodsh"
21953         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21954                 skip "Need MDS version at least 2.8.55"
21955
21956         test_mkdir $DIR/$tdir
21957
21958         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21959                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21960         stat $DIR/$tdir
21961
21962 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21963         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21964         local facet=mds$((mdtidx + 1))
21965         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21966         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21967
21968         stop $facet || error "stop MDS failed"
21969         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21970                 error "start MDS fail"
21971         wait_recovery_complete $facet
21972 }
21973 run_test 257 "xattr locks are not lost"
21974
21975 # Verify we take the i_mutex when security requires it
21976 test_258a() {
21977 #define OBD_FAIL_IMUTEX_SEC 0x141c
21978         $LCTL set_param fail_loc=0x141c
21979         touch $DIR/$tfile
21980         chmod u+s $DIR/$tfile
21981         chmod a+rwx $DIR/$tfile
21982         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21983         RC=$?
21984         if [ $RC -ne 0 ]; then
21985                 error "error, failed to take i_mutex, rc=$?"
21986         fi
21987         rm -f $DIR/$tfile
21988 }
21989 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21990
21991 # Verify we do NOT take the i_mutex in the normal case
21992 test_258b() {
21993 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21994         $LCTL set_param fail_loc=0x141d
21995         touch $DIR/$tfile
21996         chmod a+rwx $DIR
21997         chmod a+rw $DIR/$tfile
21998         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21999         RC=$?
22000         if [ $RC -ne 0 ]; then
22001                 error "error, took i_mutex unnecessarily, rc=$?"
22002         fi
22003         rm -f $DIR/$tfile
22004
22005 }
22006 run_test 258b "verify i_mutex security behavior"
22007
22008 test_259() {
22009         local file=$DIR/$tfile
22010         local before
22011         local after
22012
22013         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22014
22015         stack_trap "rm -f $file" EXIT
22016
22017         wait_delete_completed
22018         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22019         echo "before: $before"
22020
22021         $LFS setstripe -i 0 -c 1 $file
22022         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22023         sync_all_data
22024         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22025         echo "after write: $after"
22026
22027 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22028         do_facet ost1 $LCTL set_param fail_loc=0x2301
22029         $TRUNCATE $file 0
22030         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22031         echo "after truncate: $after"
22032
22033         stop ost1
22034         do_facet ost1 $LCTL set_param fail_loc=0
22035         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22036         sleep 2
22037         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22038         echo "after restart: $after"
22039         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22040                 error "missing truncate?"
22041
22042         return 0
22043 }
22044 run_test 259 "crash at delayed truncate"
22045
22046 test_260() {
22047 #define OBD_FAIL_MDC_CLOSE               0x806
22048         $LCTL set_param fail_loc=0x80000806
22049         touch $DIR/$tfile
22050
22051 }
22052 run_test 260 "Check mdc_close fail"
22053
22054 ### Data-on-MDT sanity tests ###
22055 test_270a() {
22056         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22057                 skip "Need MDS version at least 2.10.55 for DoM"
22058
22059         # create DoM file
22060         local dom=$DIR/$tdir/dom_file
22061         local tmp=$DIR/$tdir/tmp_file
22062
22063         mkdir_on_mdt0 $DIR/$tdir
22064
22065         # basic checks for DoM component creation
22066         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22067                 error "Can set MDT layout to non-first entry"
22068
22069         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22070                 error "Can define multiple entries as MDT layout"
22071
22072         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22073
22074         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22075         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22076         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22077
22078         local mdtidx=$($LFS getstripe -m $dom)
22079         local mdtname=MDT$(printf %04x $mdtidx)
22080         local facet=mds$((mdtidx + 1))
22081         local space_check=1
22082
22083         # Skip free space checks with ZFS
22084         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22085
22086         # write
22087         sync
22088         local size_tmp=$((65536 * 3))
22089         local mdtfree1=$(do_facet $facet \
22090                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22091
22092         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22093         # check also direct IO along write
22094         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22095         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22096         sync
22097         cmp $tmp $dom || error "file data is different"
22098         [ $(stat -c%s $dom) == $size_tmp ] ||
22099                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22100         if [ $space_check == 1 ]; then
22101                 local mdtfree2=$(do_facet $facet \
22102                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22103
22104                 # increase in usage from by $size_tmp
22105                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22106                         error "MDT free space wrong after write: " \
22107                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22108         fi
22109
22110         # truncate
22111         local size_dom=10000
22112
22113         $TRUNCATE $dom $size_dom
22114         [ $(stat -c%s $dom) == $size_dom ] ||
22115                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22116         if [ $space_check == 1 ]; then
22117                 mdtfree1=$(do_facet $facet \
22118                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22119                 # decrease in usage from $size_tmp to new $size_dom
22120                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22121                   $(((size_tmp - size_dom) / 1024)) ] ||
22122                         error "MDT free space is wrong after truncate: " \
22123                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22124         fi
22125
22126         # append
22127         cat $tmp >> $dom
22128         sync
22129         size_dom=$((size_dom + size_tmp))
22130         [ $(stat -c%s $dom) == $size_dom ] ||
22131                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22132         if [ $space_check == 1 ]; then
22133                 mdtfree2=$(do_facet $facet \
22134                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22135                 # increase in usage by $size_tmp from previous
22136                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22137                         error "MDT free space is wrong after append: " \
22138                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22139         fi
22140
22141         # delete
22142         rm $dom
22143         if [ $space_check == 1 ]; then
22144                 mdtfree1=$(do_facet $facet \
22145                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22146                 # decrease in usage by $size_dom from previous
22147                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22148                         error "MDT free space is wrong after removal: " \
22149                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22150         fi
22151
22152         # combined striping
22153         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22154                 error "Can't create DoM + OST striping"
22155
22156         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22157         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22158         # check also direct IO along write
22159         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22160         sync
22161         cmp $tmp $dom || error "file data is different"
22162         [ $(stat -c%s $dom) == $size_tmp ] ||
22163                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22164         rm $dom $tmp
22165
22166         return 0
22167 }
22168 run_test 270a "DoM: basic functionality tests"
22169
22170 test_270b() {
22171         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22172                 skip "Need MDS version at least 2.10.55"
22173
22174         local dom=$DIR/$tdir/dom_file
22175         local max_size=1048576
22176
22177         mkdir -p $DIR/$tdir
22178         $LFS setstripe -E $max_size -L mdt $dom
22179
22180         # truncate over the limit
22181         $TRUNCATE $dom $(($max_size + 1)) &&
22182                 error "successful truncate over the maximum size"
22183         # write over the limit
22184         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22185                 error "successful write over the maximum size"
22186         # append over the limit
22187         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22188         echo "12345" >> $dom && error "successful append over the maximum size"
22189         rm $dom
22190
22191         return 0
22192 }
22193 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22194
22195 test_270c() {
22196         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22197                 skip "Need MDS version at least 2.10.55"
22198
22199         mkdir -p $DIR/$tdir
22200         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22201
22202         # check files inherit DoM EA
22203         touch $DIR/$tdir/first
22204         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22205                 error "bad pattern"
22206         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22207                 error "bad stripe count"
22208         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22209                 error "bad stripe size"
22210
22211         # check directory inherits DoM EA and uses it as default
22212         mkdir $DIR/$tdir/subdir
22213         touch $DIR/$tdir/subdir/second
22214         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22215                 error "bad pattern in sub-directory"
22216         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22217                 error "bad stripe count in sub-directory"
22218         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22219                 error "bad stripe size in sub-directory"
22220         return 0
22221 }
22222 run_test 270c "DoM: DoM EA inheritance tests"
22223
22224 test_270d() {
22225         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22226                 skip "Need MDS version at least 2.10.55"
22227
22228         mkdir -p $DIR/$tdir
22229         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22230
22231         # inherit default DoM striping
22232         mkdir $DIR/$tdir/subdir
22233         touch $DIR/$tdir/subdir/f1
22234
22235         # change default directory striping
22236         $LFS setstripe -c 1 $DIR/$tdir/subdir
22237         touch $DIR/$tdir/subdir/f2
22238         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22239                 error "wrong default striping in file 2"
22240         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22241                 error "bad pattern in file 2"
22242         return 0
22243 }
22244 run_test 270d "DoM: change striping from DoM to RAID0"
22245
22246 test_270e() {
22247         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22248                 skip "Need MDS version at least 2.10.55"
22249
22250         mkdir -p $DIR/$tdir/dom
22251         mkdir -p $DIR/$tdir/norm
22252         DOMFILES=20
22253         NORMFILES=10
22254         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22255         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22256
22257         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22258         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22259
22260         # find DoM files by layout
22261         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22262         [ $NUM -eq  $DOMFILES ] ||
22263                 error "lfs find -L: found $NUM, expected $DOMFILES"
22264         echo "Test 1: lfs find 20 DOM files by layout: OK"
22265
22266         # there should be 1 dir with default DOM striping
22267         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22268         [ $NUM -eq  1 ] ||
22269                 error "lfs find -L: found $NUM, expected 1 dir"
22270         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22271
22272         # find DoM files by stripe size
22273         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22274         [ $NUM -eq  $DOMFILES ] ||
22275                 error "lfs find -S: found $NUM, expected $DOMFILES"
22276         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22277
22278         # find files by stripe offset except DoM files
22279         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22280         [ $NUM -eq  $NORMFILES ] ||
22281                 error "lfs find -i: found $NUM, expected $NORMFILES"
22282         echo "Test 5: lfs find no DOM files by stripe index: OK"
22283         return 0
22284 }
22285 run_test 270e "DoM: lfs find with DoM files test"
22286
22287 test_270f() {
22288         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22289                 skip "Need MDS version at least 2.10.55"
22290
22291         local mdtname=${FSNAME}-MDT0000-mdtlov
22292         local dom=$DIR/$tdir/dom_file
22293         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22294                                                 lod.$mdtname.dom_stripesize)
22295         local dom_limit=131072
22296
22297         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22298         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22299                                                 lod.$mdtname.dom_stripesize)
22300         [ ${dom_limit} -eq ${dom_current} ] ||
22301                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22302
22303         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22304         $LFS setstripe -d $DIR/$tdir
22305         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22306                 error "Can't set directory default striping"
22307
22308         # exceed maximum stripe size
22309         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22310                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22311         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22312                 error "Able to create DoM component size more than LOD limit"
22313
22314         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22315         dom_current=$(do_facet mds1 $LCTL get_param -n \
22316                                                 lod.$mdtname.dom_stripesize)
22317         [ 0 -eq ${dom_current} ] ||
22318                 error "Can't set zero DoM stripe limit"
22319         rm $dom
22320
22321         # attempt to create DoM file on server with disabled DoM should
22322         # remove DoM entry from layout and be succeed
22323         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22324                 error "Can't create DoM file (DoM is disabled)"
22325         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22326                 error "File has DoM component while DoM is disabled"
22327         rm $dom
22328
22329         # attempt to create DoM file with only DoM stripe should return error
22330         $LFS setstripe -E $dom_limit -L mdt $dom &&
22331                 error "Able to create DoM-only file while DoM is disabled"
22332
22333         # too low values to be aligned with smallest stripe size 64K
22334         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22335         dom_current=$(do_facet mds1 $LCTL get_param -n \
22336                                                 lod.$mdtname.dom_stripesize)
22337         [ 30000 -eq ${dom_current} ] &&
22338                 error "Can set too small DoM stripe limit"
22339
22340         # 64K is a minimal stripe size in Lustre, expect limit of that size
22341         [ 65536 -eq ${dom_current} ] ||
22342                 error "Limit is not set to 64K but ${dom_current}"
22343
22344         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22345         dom_current=$(do_facet mds1 $LCTL get_param -n \
22346                                                 lod.$mdtname.dom_stripesize)
22347         echo $dom_current
22348         [ 2147483648 -eq ${dom_current} ] &&
22349                 error "Can set too large DoM stripe limit"
22350
22351         do_facet mds1 $LCTL set_param -n \
22352                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22353         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22354                 error "Can't create DoM component size after limit change"
22355         do_facet mds1 $LCTL set_param -n \
22356                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22357         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22358                 error "Can't create DoM file after limit decrease"
22359         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22360                 error "Can create big DoM component after limit decrease"
22361         touch ${dom}_def ||
22362                 error "Can't create file with old default layout"
22363
22364         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22365         return 0
22366 }
22367 run_test 270f "DoM: maximum DoM stripe size checks"
22368
22369 test_270g() {
22370         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22371                 skip "Need MDS version at least 2.13.52"
22372         local dom=$DIR/$tdir/$tfile
22373
22374         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22375         local lodname=${FSNAME}-MDT0000-mdtlov
22376
22377         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22378         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22379         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22380         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22381
22382         local dom_limit=1024
22383         local dom_threshold="50%"
22384
22385         $LFS setstripe -d $DIR/$tdir
22386         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22387                 error "Can't set directory default striping"
22388
22389         do_facet mds1 $LCTL set_param -n \
22390                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22391         # set 0 threshold and create DOM file to change tunable stripesize
22392         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22393         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22394                 error "Failed to create $dom file"
22395         # now tunable dom_cur_stripesize should reach maximum
22396         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22397                                         lod.${lodname}.dom_stripesize_cur_kb)
22398         [[ $dom_current == $dom_limit ]] ||
22399                 error "Current DOM stripesize is not maximum"
22400         rm $dom
22401
22402         # set threshold for further tests
22403         do_facet mds1 $LCTL set_param -n \
22404                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22405         echo "DOM threshold is $dom_threshold free space"
22406         local dom_def
22407         local dom_set
22408         # Spoof bfree to exceed threshold
22409         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22410         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22411         for spfree in 40 20 0 15 30 55; do
22412                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22413                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22414                         error "Failed to create $dom file"
22415                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22416                                         lod.${lodname}.dom_stripesize_cur_kb)
22417                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22418                 [[ $dom_def != $dom_current ]] ||
22419                         error "Default stripe size was not changed"
22420                 if (( spfree > 0 )) ; then
22421                         dom_set=$($LFS getstripe -S $dom)
22422                         (( dom_set == dom_def * 1024 )) ||
22423                                 error "DOM component size is still old"
22424                 else
22425                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22426                                 error "DoM component is set with no free space"
22427                 fi
22428                 rm $dom
22429                 dom_current=$dom_def
22430         done
22431 }
22432 run_test 270g "DoM: default DoM stripe size depends on free space"
22433
22434 test_270h() {
22435         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22436                 skip "Need MDS version at least 2.13.53"
22437
22438         local mdtname=${FSNAME}-MDT0000-mdtlov
22439         local dom=$DIR/$tdir/$tfile
22440         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22441
22442         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22443         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22444
22445         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22446         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22447                 error "can't create OST file"
22448         # mirrored file with DOM entry in the second mirror
22449         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22450                 error "can't create mirror with DoM component"
22451
22452         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22453
22454         # DOM component in the middle and has other enries in the same mirror,
22455         # should succeed but lost DoM component
22456         $LFS setstripe --copy=${dom}_1 $dom ||
22457                 error "Can't create file from OST|DOM mirror layout"
22458         # check new file has no DoM layout after all
22459         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22460                 error "File has DoM component while DoM is disabled"
22461 }
22462 run_test 270h "DoM: DoM stripe removal when disabled on server"
22463
22464 test_270i() {
22465         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22466                 skip "Need MDS version at least 2.14.54"
22467
22468         mkdir $DIR/$tdir
22469         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22470                 error "setstripe should fail" || true
22471 }
22472 run_test 270i "DoM: setting invalid DoM striping should fail"
22473
22474 test_271a() {
22475         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22476                 skip "Need MDS version at least 2.10.55"
22477
22478         local dom=$DIR/$tdir/dom
22479
22480         mkdir -p $DIR/$tdir
22481
22482         $LFS setstripe -E 1024K -L mdt $dom
22483
22484         lctl set_param -n mdc.*.stats=clear
22485         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22486         cat $dom > /dev/null
22487         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22488         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22489         ls $dom
22490         rm -f $dom
22491 }
22492 run_test 271a "DoM: data is cached for read after write"
22493
22494 test_271b() {
22495         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22496                 skip "Need MDS version at least 2.10.55"
22497
22498         local dom=$DIR/$tdir/dom
22499
22500         mkdir -p $DIR/$tdir
22501
22502         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22503
22504         lctl set_param -n mdc.*.stats=clear
22505         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22506         cancel_lru_locks mdc
22507         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22508         # second stat to check size is cached on client
22509         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22510         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22511         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22512         rm -f $dom
22513 }
22514 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22515
22516 test_271ba() {
22517         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22518                 skip "Need MDS version at least 2.10.55"
22519
22520         local dom=$DIR/$tdir/dom
22521
22522         mkdir -p $DIR/$tdir
22523
22524         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22525
22526         lctl set_param -n mdc.*.stats=clear
22527         lctl set_param -n osc.*.stats=clear
22528         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22529         cancel_lru_locks mdc
22530         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22531         # second stat to check size is cached on client
22532         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22533         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22534         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22535         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22536         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22537         rm -f $dom
22538 }
22539 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22540
22541
22542 get_mdc_stats() {
22543         local mdtidx=$1
22544         local param=$2
22545         local mdt=MDT$(printf %04x $mdtidx)
22546
22547         if [ -z $param ]; then
22548                 lctl get_param -n mdc.*$mdt*.stats
22549         else
22550                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22551         fi
22552 }
22553
22554 test_271c() {
22555         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22556                 skip "Need MDS version at least 2.10.55"
22557
22558         local dom=$DIR/$tdir/dom
22559
22560         mkdir -p $DIR/$tdir
22561
22562         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22563
22564         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22565         local facet=mds$((mdtidx + 1))
22566
22567         cancel_lru_locks mdc
22568         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22569         createmany -o $dom 1000
22570         lctl set_param -n mdc.*.stats=clear
22571         smalliomany -w $dom 1000 200
22572         get_mdc_stats $mdtidx
22573         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22574         # Each file has 1 open, 1 IO enqueues, total 2000
22575         # but now we have also +1 getxattr for security.capability, total 3000
22576         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22577         unlinkmany $dom 1000
22578
22579         cancel_lru_locks mdc
22580         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22581         createmany -o $dom 1000
22582         lctl set_param -n mdc.*.stats=clear
22583         smalliomany -w $dom 1000 200
22584         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22585         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22586         # for OPEN and IO lock.
22587         [ $((enq - enq_2)) -ge 1000 ] ||
22588                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22589         unlinkmany $dom 1000
22590         return 0
22591 }
22592 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22593
22594 cleanup_271def_tests() {
22595         trap 0
22596         rm -f $1
22597 }
22598
22599 test_271d() {
22600         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22601                 skip "Need MDS version at least 2.10.57"
22602
22603         local dom=$DIR/$tdir/dom
22604         local tmp=$TMP/$tfile
22605         trap "cleanup_271def_tests $tmp" EXIT
22606
22607         mkdir -p $DIR/$tdir
22608
22609         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22610
22611         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22612
22613         cancel_lru_locks mdc
22614         dd if=/dev/urandom of=$tmp bs=1000 count=1
22615         dd if=$tmp of=$dom bs=1000 count=1
22616         cancel_lru_locks mdc
22617
22618         cat /etc/hosts >> $tmp
22619         lctl set_param -n mdc.*.stats=clear
22620
22621         # append data to the same file it should update local page
22622         echo "Append to the same page"
22623         cat /etc/hosts >> $dom
22624         local num=$(get_mdc_stats $mdtidx ost_read)
22625         local ra=$(get_mdc_stats $mdtidx req_active)
22626         local rw=$(get_mdc_stats $mdtidx req_waittime)
22627
22628         [ -z $num ] || error "$num READ RPC occured"
22629         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22630         echo "... DONE"
22631
22632         # compare content
22633         cmp $tmp $dom || error "file miscompare"
22634
22635         cancel_lru_locks mdc
22636         lctl set_param -n mdc.*.stats=clear
22637
22638         echo "Open and read file"
22639         cat $dom > /dev/null
22640         local num=$(get_mdc_stats $mdtidx ost_read)
22641         local ra=$(get_mdc_stats $mdtidx req_active)
22642         local rw=$(get_mdc_stats $mdtidx req_waittime)
22643
22644         [ -z $num ] || error "$num READ RPC occured"
22645         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22646         echo "... DONE"
22647
22648         # compare content
22649         cmp $tmp $dom || error "file miscompare"
22650
22651         return 0
22652 }
22653 run_test 271d "DoM: read on open (1K file in reply buffer)"
22654
22655 test_271f() {
22656         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22657                 skip "Need MDS version at least 2.10.57"
22658
22659         local dom=$DIR/$tdir/dom
22660         local tmp=$TMP/$tfile
22661         trap "cleanup_271def_tests $tmp" EXIT
22662
22663         mkdir -p $DIR/$tdir
22664
22665         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22666
22667         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22668
22669         cancel_lru_locks mdc
22670         dd if=/dev/urandom of=$tmp bs=265000 count=1
22671         dd if=$tmp of=$dom bs=265000 count=1
22672         cancel_lru_locks mdc
22673         cat /etc/hosts >> $tmp
22674         lctl set_param -n mdc.*.stats=clear
22675
22676         echo "Append to the same page"
22677         cat /etc/hosts >> $dom
22678         local num=$(get_mdc_stats $mdtidx ost_read)
22679         local ra=$(get_mdc_stats $mdtidx req_active)
22680         local rw=$(get_mdc_stats $mdtidx req_waittime)
22681
22682         [ -z $num ] || error "$num READ RPC occured"
22683         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22684         echo "... DONE"
22685
22686         # compare content
22687         cmp $tmp $dom || error "file miscompare"
22688
22689         cancel_lru_locks mdc
22690         lctl set_param -n mdc.*.stats=clear
22691
22692         echo "Open and read file"
22693         cat $dom > /dev/null
22694         local num=$(get_mdc_stats $mdtidx ost_read)
22695         local ra=$(get_mdc_stats $mdtidx req_active)
22696         local rw=$(get_mdc_stats $mdtidx req_waittime)
22697
22698         [ -z $num ] && num=0
22699         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22700         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22701         echo "... DONE"
22702
22703         # compare content
22704         cmp $tmp $dom || error "file miscompare"
22705
22706         return 0
22707 }
22708 run_test 271f "DoM: read on open (200K file and read tail)"
22709
22710 test_271g() {
22711         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22712                 skip "Skipping due to old client or server version"
22713
22714         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22715         # to get layout
22716         $CHECKSTAT -t file $DIR1/$tfile
22717
22718         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22719         MULTIOP_PID=$!
22720         sleep 1
22721         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22722         $LCTL set_param fail_loc=0x80000314
22723         rm $DIR1/$tfile || error "Unlink fails"
22724         RC=$?
22725         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22726         [ $RC -eq 0 ] || error "Failed write to stale object"
22727 }
22728 run_test 271g "Discard DoM data vs client flush race"
22729
22730 test_272a() {
22731         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22732                 skip "Need MDS version at least 2.11.50"
22733
22734         local dom=$DIR/$tdir/dom
22735         mkdir -p $DIR/$tdir
22736
22737         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22738         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22739                 error "failed to write data into $dom"
22740         local old_md5=$(md5sum $dom)
22741
22742         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22743                 error "failed to migrate to the same DoM component"
22744
22745         local new_md5=$(md5sum $dom)
22746
22747         [ "$old_md5" == "$new_md5" ] ||
22748                 error "md5sum differ: $old_md5, $new_md5"
22749
22750         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22751                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22752 }
22753 run_test 272a "DoM migration: new layout with the same DOM component"
22754
22755 test_272b() {
22756         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22757                 skip "Need MDS version at least 2.11.50"
22758
22759         local dom=$DIR/$tdir/dom
22760         mkdir -p $DIR/$tdir
22761         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22762
22763         local mdtidx=$($LFS getstripe -m $dom)
22764         local mdtname=MDT$(printf %04x $mdtidx)
22765         local facet=mds$((mdtidx + 1))
22766
22767         local mdtfree1=$(do_facet $facet \
22768                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22769         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22770                 error "failed to write data into $dom"
22771         local old_md5=$(md5sum $dom)
22772         cancel_lru_locks mdc
22773         local mdtfree1=$(do_facet $facet \
22774                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22775
22776         $LFS migrate -c2 $dom ||
22777                 error "failed to migrate to the new composite layout"
22778         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22779                 error "MDT stripe was not removed"
22780
22781         cancel_lru_locks mdc
22782         local new_md5=$(md5sum $dom)
22783         [ "$old_md5" == "$new_md5" ] ||
22784                 error "$old_md5 != $new_md5"
22785
22786         # Skip free space checks with ZFS
22787         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22788                 local mdtfree2=$(do_facet $facet \
22789                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22790                 [ $mdtfree2 -gt $mdtfree1 ] ||
22791                         error "MDT space is not freed after migration"
22792         fi
22793         return 0
22794 }
22795 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22796
22797 test_272c() {
22798         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22799                 skip "Need MDS version at least 2.11.50"
22800
22801         local dom=$DIR/$tdir/$tfile
22802         mkdir -p $DIR/$tdir
22803         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22804
22805         local mdtidx=$($LFS getstripe -m $dom)
22806         local mdtname=MDT$(printf %04x $mdtidx)
22807         local facet=mds$((mdtidx + 1))
22808
22809         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22810                 error "failed to write data into $dom"
22811         local old_md5=$(md5sum $dom)
22812         cancel_lru_locks mdc
22813         local mdtfree1=$(do_facet $facet \
22814                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22815
22816         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22817                 error "failed to migrate to the new composite layout"
22818         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22819                 error "MDT stripe was not removed"
22820
22821         cancel_lru_locks mdc
22822         local new_md5=$(md5sum $dom)
22823         [ "$old_md5" == "$new_md5" ] ||
22824                 error "$old_md5 != $new_md5"
22825
22826         # Skip free space checks with ZFS
22827         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22828                 local mdtfree2=$(do_facet $facet \
22829                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22830                 [ $mdtfree2 -gt $mdtfree1 ] ||
22831                         error "MDS space is not freed after migration"
22832         fi
22833         return 0
22834 }
22835 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22836
22837 test_272d() {
22838         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22839                 skip "Need MDS version at least 2.12.55"
22840
22841         local dom=$DIR/$tdir/$tfile
22842         mkdir -p $DIR/$tdir
22843         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22844
22845         local mdtidx=$($LFS getstripe -m $dom)
22846         local mdtname=MDT$(printf %04x $mdtidx)
22847         local facet=mds$((mdtidx + 1))
22848
22849         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22850                 error "failed to write data into $dom"
22851         local old_md5=$(md5sum $dom)
22852         cancel_lru_locks mdc
22853         local mdtfree1=$(do_facet $facet \
22854                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22855
22856         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22857                 error "failed mirroring to the new composite layout"
22858         $LFS mirror resync $dom ||
22859                 error "failed mirror resync"
22860         $LFS mirror split --mirror-id 1 -d $dom ||
22861                 error "failed mirror split"
22862
22863         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22864                 error "MDT stripe was not removed"
22865
22866         cancel_lru_locks mdc
22867         local new_md5=$(md5sum $dom)
22868         [ "$old_md5" == "$new_md5" ] ||
22869                 error "$old_md5 != $new_md5"
22870
22871         # Skip free space checks with ZFS
22872         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22873                 local mdtfree2=$(do_facet $facet \
22874                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22875                 [ $mdtfree2 -gt $mdtfree1 ] ||
22876                         error "MDS space is not freed after DOM mirror deletion"
22877         fi
22878         return 0
22879 }
22880 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22881
22882 test_272e() {
22883         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22884                 skip "Need MDS version at least 2.12.55"
22885
22886         local dom=$DIR/$tdir/$tfile
22887         mkdir -p $DIR/$tdir
22888         $LFS setstripe -c 2 $dom
22889
22890         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22891                 error "failed to write data into $dom"
22892         local old_md5=$(md5sum $dom)
22893         cancel_lru_locks
22894
22895         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22896                 error "failed mirroring to the DOM layout"
22897         $LFS mirror resync $dom ||
22898                 error "failed mirror resync"
22899         $LFS mirror split --mirror-id 1 -d $dom ||
22900                 error "failed mirror split"
22901
22902         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22903                 error "MDT stripe wasn't set"
22904
22905         cancel_lru_locks
22906         local new_md5=$(md5sum $dom)
22907         [ "$old_md5" == "$new_md5" ] ||
22908                 error "$old_md5 != $new_md5"
22909
22910         return 0
22911 }
22912 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22913
22914 test_272f() {
22915         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22916                 skip "Need MDS version at least 2.12.55"
22917
22918         local dom=$DIR/$tdir/$tfile
22919         mkdir -p $DIR/$tdir
22920         $LFS setstripe -c 2 $dom
22921
22922         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22923                 error "failed to write data into $dom"
22924         local old_md5=$(md5sum $dom)
22925         cancel_lru_locks
22926
22927         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22928                 error "failed migrating to the DOM file"
22929
22930         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22931                 error "MDT stripe wasn't set"
22932
22933         cancel_lru_locks
22934         local new_md5=$(md5sum $dom)
22935         [ "$old_md5" != "$new_md5" ] &&
22936                 error "$old_md5 != $new_md5"
22937
22938         return 0
22939 }
22940 run_test 272f "DoM migration: OST-striped file to DOM file"
22941
22942 test_273a() {
22943         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22944                 skip "Need MDS version at least 2.11.50"
22945
22946         # Layout swap cannot be done if either file has DOM component,
22947         # this will never be supported, migration should be used instead
22948
22949         local dom=$DIR/$tdir/$tfile
22950         mkdir -p $DIR/$tdir
22951
22952         $LFS setstripe -c2 ${dom}_plain
22953         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22954         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22955                 error "can swap layout with DoM component"
22956         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22957                 error "can swap layout with DoM component"
22958
22959         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22960         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22961                 error "can swap layout with DoM component"
22962         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22963                 error "can swap layout with DoM component"
22964         return 0
22965 }
22966 run_test 273a "DoM: layout swapping should fail with DOM"
22967
22968 test_273b() {
22969         mkdir -p $DIR/$tdir
22970         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22971
22972 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22973         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22974
22975         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22976 }
22977 run_test 273b "DoM: race writeback and object destroy"
22978
22979 test_275() {
22980         remote_ost_nodsh && skip "remote OST with nodsh"
22981         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22982                 skip "Need OST version >= 2.10.57"
22983
22984         local file=$DIR/$tfile
22985         local oss
22986
22987         oss=$(comma_list $(osts_nodes))
22988
22989         dd if=/dev/urandom of=$file bs=1M count=2 ||
22990                 error "failed to create a file"
22991         cancel_lru_locks osc
22992
22993         #lock 1
22994         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22995                 error "failed to read a file"
22996
22997 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22998         $LCTL set_param fail_loc=0x8000031f
22999
23000         cancel_lru_locks osc &
23001         sleep 1
23002
23003 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23004         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23005         #IO takes another lock, but matches the PENDING one
23006         #and places it to the IO RPC
23007         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23008                 error "failed to read a file with PENDING lock"
23009 }
23010 run_test 275 "Read on a canceled duplicate lock"
23011
23012 test_276() {
23013         remote_ost_nodsh && skip "remote OST with nodsh"
23014         local pid
23015
23016         do_facet ost1 "(while true; do \
23017                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23018                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23019         pid=$!
23020
23021         for LOOP in $(seq 20); do
23022                 stop ost1
23023                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23024         done
23025         kill -9 $pid
23026         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23027                 rm $TMP/sanity_276_pid"
23028 }
23029 run_test 276 "Race between mount and obd_statfs"
23030
23031 test_277() {
23032         $LCTL set_param ldlm.namespaces.*.lru_size=0
23033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23034         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23035                         grep ^used_mb | awk '{print $2}')
23036         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23038                 oflag=direct conv=notrunc
23039         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23040                         grep ^used_mb | awk '{print $2}')
23041         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23042 }
23043 run_test 277 "Direct IO shall drop page cache"
23044
23045 test_278() {
23046         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23047         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23048         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23049                 skip "needs the same host for mdt1 mdt2" && return
23050
23051         local pid1
23052         local pid2
23053
23054 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23055         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23056         stop mds2 &
23057         pid2=$!
23058
23059         stop mds1
23060
23061         echo "Starting MDTs"
23062         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23063         wait $pid2
23064 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23065 #will return NULL
23066         do_facet mds2 $LCTL set_param fail_loc=0
23067
23068         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23069         wait_recovery_complete mds2
23070 }
23071 run_test 278 "Race starting MDS between MDTs stop/start"
23072
23073 test_280() {
23074         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23075                 skip "Need MGS version at least 2.13.52"
23076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23077         combined_mgs_mds || skip "needs combined MGS/MDT"
23078
23079         umount_client $MOUNT
23080 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23081         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23082
23083         mount_client $MOUNT &
23084         sleep 1
23085         stop mgs || error "stop mgs failed"
23086         #for a race mgs would crash
23087         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23088         # make sure we unmount client before remounting
23089         wait
23090         umount_client $MOUNT
23091         mount_client $MOUNT || error "mount client failed"
23092 }
23093 run_test 280 "Race between MGS umount and client llog processing"
23094
23095 cleanup_test_300() {
23096         trap 0
23097         umask $SAVE_UMASK
23098 }
23099 test_striped_dir() {
23100         local mdt_index=$1
23101         local stripe_count
23102         local stripe_index
23103
23104         mkdir -p $DIR/$tdir
23105
23106         SAVE_UMASK=$(umask)
23107         trap cleanup_test_300 RETURN EXIT
23108
23109         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23110                                                 $DIR/$tdir/striped_dir ||
23111                 error "set striped dir error"
23112
23113         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23114         [ "$mode" = "755" ] || error "expect 755 got $mode"
23115
23116         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23117                 error "getdirstripe failed"
23118         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23119         if [ "$stripe_count" != "2" ]; then
23120                 error "1:stripe_count is $stripe_count, expect 2"
23121         fi
23122         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23123         if [ "$stripe_count" != "2" ]; then
23124                 error "2:stripe_count is $stripe_count, expect 2"
23125         fi
23126
23127         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23128         if [ "$stripe_index" != "$mdt_index" ]; then
23129                 error "stripe_index is $stripe_index, expect $mdt_index"
23130         fi
23131
23132         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23133                 error "nlink error after create striped dir"
23134
23135         mkdir $DIR/$tdir/striped_dir/a
23136         mkdir $DIR/$tdir/striped_dir/b
23137
23138         stat $DIR/$tdir/striped_dir/a ||
23139                 error "create dir under striped dir failed"
23140         stat $DIR/$tdir/striped_dir/b ||
23141                 error "create dir under striped dir failed"
23142
23143         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23144                 error "nlink error after mkdir"
23145
23146         rmdir $DIR/$tdir/striped_dir/a
23147         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23148                 error "nlink error after rmdir"
23149
23150         rmdir $DIR/$tdir/striped_dir/b
23151         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23152                 error "nlink error after rmdir"
23153
23154         chattr +i $DIR/$tdir/striped_dir
23155         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23156                 error "immutable flags not working under striped dir!"
23157         chattr -i $DIR/$tdir/striped_dir
23158
23159         rmdir $DIR/$tdir/striped_dir ||
23160                 error "rmdir striped dir error"
23161
23162         cleanup_test_300
23163
23164         true
23165 }
23166
23167 test_300a() {
23168         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23169                 skip "skipped for lustre < 2.7.0"
23170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23172
23173         test_striped_dir 0 || error "failed on striped dir on MDT0"
23174         test_striped_dir 1 || error "failed on striped dir on MDT0"
23175 }
23176 run_test 300a "basic striped dir sanity test"
23177
23178 test_300b() {
23179         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23180                 skip "skipped for lustre < 2.7.0"
23181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23182         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23183
23184         local i
23185         local mtime1
23186         local mtime2
23187         local mtime3
23188
23189         test_mkdir $DIR/$tdir || error "mkdir fail"
23190         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23191                 error "set striped dir error"
23192         for i in {0..9}; do
23193                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23194                 sleep 1
23195                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23196                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23197                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23198                 sleep 1
23199                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23200                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23201                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23202         done
23203         true
23204 }
23205 run_test 300b "check ctime/mtime for striped dir"
23206
23207 test_300c() {
23208         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23209                 skip "skipped for lustre < 2.7.0"
23210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23212
23213         local file_count
23214
23215         mkdir_on_mdt0 $DIR/$tdir
23216         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23217                 error "set striped dir error"
23218
23219         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23220                 error "chown striped dir failed"
23221
23222         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23223                 error "create 5k files failed"
23224
23225         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23226
23227         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23228
23229         rm -rf $DIR/$tdir
23230 }
23231 run_test 300c "chown && check ls under striped directory"
23232
23233 test_300d() {
23234         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23235                 skip "skipped for lustre < 2.7.0"
23236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23237         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23238
23239         local stripe_count
23240         local file
23241
23242         mkdir -p $DIR/$tdir
23243         $LFS setstripe -c 2 $DIR/$tdir
23244
23245         #local striped directory
23246         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23247                 error "set striped dir error"
23248         #look at the directories for debug purposes
23249         ls -l $DIR/$tdir
23250         $LFS getdirstripe $DIR/$tdir
23251         ls -l $DIR/$tdir/striped_dir
23252         $LFS getdirstripe $DIR/$tdir/striped_dir
23253         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23254                 error "create 10 files failed"
23255
23256         #remote striped directory
23257         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23258                 error "set striped dir error"
23259         #look at the directories for debug purposes
23260         ls -l $DIR/$tdir
23261         $LFS getdirstripe $DIR/$tdir
23262         ls -l $DIR/$tdir/remote_striped_dir
23263         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23264         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23265                 error "create 10 files failed"
23266
23267         for file in $(find $DIR/$tdir); do
23268                 stripe_count=$($LFS getstripe -c $file)
23269                 [ $stripe_count -eq 2 ] ||
23270                         error "wrong stripe $stripe_count for $file"
23271         done
23272
23273         rm -rf $DIR/$tdir
23274 }
23275 run_test 300d "check default stripe under striped directory"
23276
23277 test_300e() {
23278         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23279                 skip "Need MDS version at least 2.7.55"
23280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23281         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23282
23283         local stripe_count
23284         local file
23285
23286         mkdir -p $DIR/$tdir
23287
23288         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23289                 error "set striped dir error"
23290
23291         touch $DIR/$tdir/striped_dir/a
23292         touch $DIR/$tdir/striped_dir/b
23293         touch $DIR/$tdir/striped_dir/c
23294
23295         mkdir $DIR/$tdir/striped_dir/dir_a
23296         mkdir $DIR/$tdir/striped_dir/dir_b
23297         mkdir $DIR/$tdir/striped_dir/dir_c
23298
23299         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23300                 error "set striped adir under striped dir error"
23301
23302         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23303                 error "set striped bdir under striped dir error"
23304
23305         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23306                 error "set striped cdir under striped dir error"
23307
23308         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23309                 error "rename dir under striped dir fails"
23310
23311         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23312                 error "rename dir under different stripes fails"
23313
23314         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23315                 error "rename file under striped dir should succeed"
23316
23317         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23318                 error "rename dir under striped dir should succeed"
23319
23320         rm -rf $DIR/$tdir
23321 }
23322 run_test 300e "check rename under striped directory"
23323
23324 test_300f() {
23325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23327         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23328                 skip "Need MDS version at least 2.7.55"
23329
23330         local stripe_count
23331         local file
23332
23333         rm -rf $DIR/$tdir
23334         mkdir -p $DIR/$tdir
23335
23336         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23337                 error "set striped dir error"
23338
23339         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23340                 error "set striped dir error"
23341
23342         touch $DIR/$tdir/striped_dir/a
23343         mkdir $DIR/$tdir/striped_dir/dir_a
23344         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23345                 error "create striped dir under striped dir fails"
23346
23347         touch $DIR/$tdir/striped_dir1/b
23348         mkdir $DIR/$tdir/striped_dir1/dir_b
23349         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23350                 error "create striped dir under striped dir fails"
23351
23352         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23353                 error "rename dir under different striped dir should fail"
23354
23355         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23356                 error "rename striped dir under diff striped dir should fail"
23357
23358         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23359                 error "rename file under diff striped dirs fails"
23360
23361         rm -rf $DIR/$tdir
23362 }
23363 run_test 300f "check rename cross striped directory"
23364
23365 test_300_check_default_striped_dir()
23366 {
23367         local dirname=$1
23368         local default_count=$2
23369         local default_index=$3
23370         local stripe_count
23371         local stripe_index
23372         local dir_stripe_index
23373         local dir
23374
23375         echo "checking $dirname $default_count $default_index"
23376         $LFS setdirstripe -D -c $default_count -i $default_index \
23377                                 -H all_char $DIR/$tdir/$dirname ||
23378                 error "set default stripe on striped dir error"
23379         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23380         [ $stripe_count -eq $default_count ] ||
23381                 error "expect $default_count get $stripe_count for $dirname"
23382
23383         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23384         [ $stripe_index -eq $default_index ] ||
23385                 error "expect $default_index get $stripe_index for $dirname"
23386
23387         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23388                                                 error "create dirs failed"
23389
23390         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23391         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23392         for dir in $(find $DIR/$tdir/$dirname/*); do
23393                 stripe_count=$($LFS getdirstripe -c $dir)
23394                 (( $stripe_count == $default_count )) ||
23395                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23396                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23397                 error "stripe count $default_count != $stripe_count for $dir"
23398
23399                 stripe_index=$($LFS getdirstripe -i $dir)
23400                 [ $default_index -eq -1 ] ||
23401                         [ $stripe_index -eq $default_index ] ||
23402                         error "$stripe_index != $default_index for $dir"
23403
23404                 #check default stripe
23405                 stripe_count=$($LFS getdirstripe -D -c $dir)
23406                 [ $stripe_count -eq $default_count ] ||
23407                 error "default count $default_count != $stripe_count for $dir"
23408
23409                 stripe_index=$($LFS getdirstripe -D -i $dir)
23410                 [ $stripe_index -eq $default_index ] ||
23411                 error "default index $default_index != $stripe_index for $dir"
23412         done
23413         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23414 }
23415
23416 test_300g() {
23417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23418         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23419                 skip "Need MDS version at least 2.7.55"
23420
23421         local dir
23422         local stripe_count
23423         local stripe_index
23424
23425         mkdir_on_mdt0 $DIR/$tdir
23426         mkdir $DIR/$tdir/normal_dir
23427
23428         #Checking when client cache stripe index
23429         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23430         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23431                 error "create striped_dir failed"
23432
23433         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23434                 error "create dir0 fails"
23435         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23436         [ $stripe_index -eq 0 ] ||
23437                 error "dir0 expect index 0 got $stripe_index"
23438
23439         mkdir $DIR/$tdir/striped_dir/dir1 ||
23440                 error "create dir1 fails"
23441         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23442         [ $stripe_index -eq 1 ] ||
23443                 error "dir1 expect index 1 got $stripe_index"
23444
23445         #check default stripe count/stripe index
23446         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23447         test_300_check_default_striped_dir normal_dir 1 0
23448         test_300_check_default_striped_dir normal_dir -1 1
23449         test_300_check_default_striped_dir normal_dir 2 -1
23450
23451         #delete default stripe information
23452         echo "delete default stripeEA"
23453         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23454                 error "set default stripe on striped dir error"
23455
23456         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23457         for dir in $(find $DIR/$tdir/normal_dir/*); do
23458                 stripe_count=$($LFS getdirstripe -c $dir)
23459                 [ $stripe_count -eq 0 ] ||
23460                         error "expect 1 get $stripe_count for $dir"
23461         done
23462 }
23463 run_test 300g "check default striped directory for normal directory"
23464
23465 test_300h() {
23466         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23467         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23468                 skip "Need MDS version at least 2.7.55"
23469
23470         local dir
23471         local stripe_count
23472
23473         mkdir $DIR/$tdir
23474         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23475                 error "set striped dir error"
23476
23477         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23478         test_300_check_default_striped_dir striped_dir 1 0
23479         test_300_check_default_striped_dir striped_dir -1 1
23480         test_300_check_default_striped_dir striped_dir 2 -1
23481
23482         #delete default stripe information
23483         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23484                 error "set default stripe on striped dir error"
23485
23486         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23487         for dir in $(find $DIR/$tdir/striped_dir/*); do
23488                 stripe_count=$($LFS getdirstripe -c $dir)
23489                 [ $stripe_count -eq 0 ] ||
23490                         error "expect 1 get $stripe_count for $dir"
23491         done
23492 }
23493 run_test 300h "check default striped directory for striped directory"
23494
23495 test_300i() {
23496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23497         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23498         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23499                 skip "Need MDS version at least 2.7.55"
23500
23501         local stripe_count
23502         local file
23503
23504         mkdir $DIR/$tdir
23505
23506         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23507                 error "set striped dir error"
23508
23509         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23510                 error "create files under striped dir failed"
23511
23512         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23513                 error "set striped hashdir error"
23514
23515         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23516                 error "create dir0 under hash dir failed"
23517         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23518                 error "create dir1 under hash dir failed"
23519         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23520                 error "create dir2 under hash dir failed"
23521
23522         # unfortunately, we need to umount to clear dir layout cache for now
23523         # once we fully implement dir layout, we can drop this
23524         umount_client $MOUNT || error "umount failed"
23525         mount_client $MOUNT || error "mount failed"
23526
23527         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23528         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23529         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23530
23531         #set the stripe to be unknown hash type
23532         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23533         $LCTL set_param fail_loc=0x1901
23534         for ((i = 0; i < 10; i++)); do
23535                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23536                         error "stat f-$i failed"
23537                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23538         done
23539
23540         touch $DIR/$tdir/striped_dir/f0 &&
23541                 error "create under striped dir with unknown hash should fail"
23542
23543         $LCTL set_param fail_loc=0
23544
23545         umount_client $MOUNT || error "umount failed"
23546         mount_client $MOUNT || error "mount failed"
23547
23548         return 0
23549 }
23550 run_test 300i "client handle unknown hash type striped directory"
23551
23552 test_300j() {
23553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23555         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23556                 skip "Need MDS version at least 2.7.55"
23557
23558         local stripe_count
23559         local file
23560
23561         mkdir $DIR/$tdir
23562
23563         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23564         $LCTL set_param fail_loc=0x1702
23565         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23566                 error "set striped dir error"
23567
23568         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23569                 error "create files under striped dir failed"
23570
23571         $LCTL set_param fail_loc=0
23572
23573         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23574
23575         return 0
23576 }
23577 run_test 300j "test large update record"
23578
23579 test_300k() {
23580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23582         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23583                 skip "Need MDS version at least 2.7.55"
23584
23585         # this test needs a huge transaction
23586         local kb
23587         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23588              osd*.$FSNAME-MDT0000.kbytestotal")
23589         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23590
23591         local stripe_count
23592         local file
23593
23594         mkdir $DIR/$tdir
23595
23596         #define OBD_FAIL_LARGE_STRIPE   0x1703
23597         $LCTL set_param fail_loc=0x1703
23598         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23599                 error "set striped dir error"
23600         $LCTL set_param fail_loc=0
23601
23602         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23603                 error "getstripeddir fails"
23604         rm -rf $DIR/$tdir/striped_dir ||
23605                 error "unlink striped dir fails"
23606
23607         return 0
23608 }
23609 run_test 300k "test large striped directory"
23610
23611 test_300l() {
23612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23614         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23615                 skip "Need MDS version at least 2.7.55"
23616
23617         local stripe_index
23618
23619         test_mkdir -p $DIR/$tdir/striped_dir
23620         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23621                         error "chown $RUNAS_ID failed"
23622         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23623                 error "set default striped dir failed"
23624
23625         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23626         $LCTL set_param fail_loc=0x80000158
23627         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23628
23629         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23630         [ $stripe_index -eq 1 ] ||
23631                 error "expect 1 get $stripe_index for $dir"
23632 }
23633 run_test 300l "non-root user to create dir under striped dir with stale layout"
23634
23635 test_300m() {
23636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23637         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23638         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23639                 skip "Need MDS version at least 2.7.55"
23640
23641         mkdir -p $DIR/$tdir/striped_dir
23642         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23643                 error "set default stripes dir error"
23644
23645         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23646
23647         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23648         [ $stripe_count -eq 0 ] ||
23649                         error "expect 0 get $stripe_count for a"
23650
23651         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23652                 error "set default stripes dir error"
23653
23654         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23655
23656         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23657         [ $stripe_count -eq 0 ] ||
23658                         error "expect 0 get $stripe_count for b"
23659
23660         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23661                 error "set default stripes dir error"
23662
23663         mkdir $DIR/$tdir/striped_dir/c &&
23664                 error "default stripe_index is invalid, mkdir c should fails"
23665
23666         rm -rf $DIR/$tdir || error "rmdir fails"
23667 }
23668 run_test 300m "setstriped directory on single MDT FS"
23669
23670 cleanup_300n() {
23671         local list=$(comma_list $(mdts_nodes))
23672
23673         trap 0
23674         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23675 }
23676
23677 test_300n() {
23678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23680         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23681                 skip "Need MDS version at least 2.7.55"
23682         remote_mds_nodsh && skip "remote MDS with nodsh"
23683
23684         local stripe_index
23685         local list=$(comma_list $(mdts_nodes))
23686
23687         trap cleanup_300n RETURN EXIT
23688         mkdir -p $DIR/$tdir
23689         chmod 777 $DIR/$tdir
23690         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23691                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23692                 error "create striped dir succeeds with gid=0"
23693
23694         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23695         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23696                 error "create striped dir fails with gid=-1"
23697
23698         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23699         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23700                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23701                 error "set default striped dir succeeds with gid=0"
23702
23703
23704         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23705         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23706                 error "set default striped dir fails with gid=-1"
23707
23708
23709         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23710         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23711                                         error "create test_dir fails"
23712         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23713                                         error "create test_dir1 fails"
23714         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23715                                         error "create test_dir2 fails"
23716         cleanup_300n
23717 }
23718 run_test 300n "non-root user to create dir under striped dir with default EA"
23719
23720 test_300o() {
23721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23723         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23724                 skip "Need MDS version at least 2.7.55"
23725
23726         local numfree1
23727         local numfree2
23728
23729         mkdir -p $DIR/$tdir
23730
23731         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23732         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23733         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23734                 skip "not enough free inodes $numfree1 $numfree2"
23735         fi
23736
23737         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23738         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23739         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23740                 skip "not enough free space $numfree1 $numfree2"
23741         fi
23742
23743         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23744                 error "setdirstripe fails"
23745
23746         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23747                 error "create dirs fails"
23748
23749         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23750         ls $DIR/$tdir/striped_dir > /dev/null ||
23751                 error "ls striped dir fails"
23752         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23753                 error "unlink big striped dir fails"
23754 }
23755 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23756
23757 test_300p() {
23758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23759         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23760         remote_mds_nodsh && skip "remote MDS with nodsh"
23761
23762         mkdir_on_mdt0 $DIR/$tdir
23763
23764         #define OBD_FAIL_OUT_ENOSPC     0x1704
23765         do_facet mds2 lctl set_param fail_loc=0x80001704
23766         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23767                  && error "create striped directory should fail"
23768
23769         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23770
23771         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23772         true
23773 }
23774 run_test 300p "create striped directory without space"
23775
23776 test_300q() {
23777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23779
23780         local fd=$(free_fd)
23781         local cmd="exec $fd<$tdir"
23782         cd $DIR
23783         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23784         eval $cmd
23785         cmd="exec $fd<&-"
23786         trap "eval $cmd" EXIT
23787         cd $tdir || error "cd $tdir fails"
23788         rmdir  ../$tdir || error "rmdir $tdir fails"
23789         mkdir local_dir && error "create dir succeeds"
23790         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23791         eval $cmd
23792         return 0
23793 }
23794 run_test 300q "create remote directory under orphan directory"
23795
23796 test_300r() {
23797         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23798                 skip "Need MDS version at least 2.7.55" && return
23799         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23800
23801         mkdir $DIR/$tdir
23802
23803         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23804                 error "set striped dir error"
23805
23806         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23807                 error "getstripeddir fails"
23808
23809         local stripe_count
23810         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23811                       awk '/lmv_stripe_count:/ { print $2 }')
23812
23813         [ $MDSCOUNT -ne $stripe_count ] &&
23814                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23815
23816         rm -rf $DIR/$tdir/striped_dir ||
23817                 error "unlink striped dir fails"
23818 }
23819 run_test 300r "test -1 striped directory"
23820
23821 test_300s_helper() {
23822         local count=$1
23823
23824         local stripe_dir=$DIR/$tdir/striped_dir.$count
23825
23826         $LFS mkdir -c $count $stripe_dir ||
23827                 error "lfs mkdir -c error"
23828
23829         $LFS getdirstripe $stripe_dir ||
23830                 error "lfs getdirstripe fails"
23831
23832         local stripe_count
23833         stripe_count=$($LFS getdirstripe $stripe_dir |
23834                       awk '/lmv_stripe_count:/ { print $2 }')
23835
23836         [ $count -ne $stripe_count ] &&
23837                 error_noexit "bad stripe count $stripe_count expected $count"
23838
23839         local dupe_stripes
23840         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23841                 awk '/0x/ {count[$1] += 1}; END {
23842                         for (idx in count) {
23843                                 if (count[idx]>1) {
23844                                         print "index " idx " count " count[idx]
23845                                 }
23846                         }
23847                 }')
23848
23849         if [[ -n "$dupe_stripes" ]] ; then
23850                 lfs getdirstripe $stripe_dir
23851                 error_noexit "Dupe MDT above: $dupe_stripes "
23852         fi
23853
23854         rm -rf $stripe_dir ||
23855                 error_noexit "unlink $stripe_dir fails"
23856 }
23857
23858 test_300s() {
23859         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23860                 skip "Need MDS version at least 2.7.55" && return
23861         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23862
23863         mkdir $DIR/$tdir
23864         for count in $(seq 2 $MDSCOUNT); do
23865                 test_300s_helper $count
23866         done
23867 }
23868 run_test 300s "test lfs mkdir -c without -i"
23869
23870 test_300t() {
23871         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23872                 skip "need MDS 2.14.55 or later"
23873         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23874
23875         local testdir="$DIR/$tdir/striped_dir"
23876         local dir1=$testdir/dir1
23877         local dir2=$testdir/dir2
23878
23879         mkdir -p $testdir
23880
23881         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23882                 error "failed to set default stripe count for $testdir"
23883
23884         mkdir $dir1
23885         local stripe_count=$($LFS getdirstripe -c $dir1)
23886
23887         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23888
23889         local max_count=$((MDSCOUNT - 1))
23890         local mdts=$(comma_list $(mdts_nodes))
23891
23892         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23893         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23894
23895         mkdir $dir2
23896         stripe_count=$($LFS getdirstripe -c $dir2)
23897
23898         (( $stripe_count == $max_count )) || error "wrong stripe count"
23899 }
23900 run_test 300t "test max_mdt_stripecount"
23901
23902 prepare_remote_file() {
23903         mkdir $DIR/$tdir/src_dir ||
23904                 error "create remote source failed"
23905
23906         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23907                  error "cp to remote source failed"
23908         touch $DIR/$tdir/src_dir/a
23909
23910         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23911                 error "create remote target dir failed"
23912
23913         touch $DIR/$tdir/tgt_dir/b
23914
23915         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23916                 error "rename dir cross MDT failed!"
23917
23918         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23919                 error "src_child still exists after rename"
23920
23921         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23922                 error "missing file(a) after rename"
23923
23924         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23925                 error "diff after rename"
23926 }
23927
23928 test_310a() {
23929         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23931
23932         local remote_file=$DIR/$tdir/tgt_dir/b
23933
23934         mkdir -p $DIR/$tdir
23935
23936         prepare_remote_file || error "prepare remote file failed"
23937
23938         #open-unlink file
23939         $OPENUNLINK $remote_file $remote_file ||
23940                 error "openunlink $remote_file failed"
23941         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23942 }
23943 run_test 310a "open unlink remote file"
23944
23945 test_310b() {
23946         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23948
23949         local remote_file=$DIR/$tdir/tgt_dir/b
23950
23951         mkdir -p $DIR/$tdir
23952
23953         prepare_remote_file || error "prepare remote file failed"
23954
23955         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23956         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23957         $CHECKSTAT -t file $remote_file || error "check file failed"
23958 }
23959 run_test 310b "unlink remote file with multiple links while open"
23960
23961 test_310c() {
23962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23963         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23964
23965         local remote_file=$DIR/$tdir/tgt_dir/b
23966
23967         mkdir -p $DIR/$tdir
23968
23969         prepare_remote_file || error "prepare remote file failed"
23970
23971         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23972         multiop_bg_pause $remote_file O_uc ||
23973                         error "mulitop failed for remote file"
23974         MULTIPID=$!
23975         $MULTIOP $DIR/$tfile Ouc
23976         kill -USR1 $MULTIPID
23977         wait $MULTIPID
23978 }
23979 run_test 310c "open-unlink remote file with multiple links"
23980
23981 #LU-4825
23982 test_311() {
23983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23984         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23985         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23986                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23987         remote_mds_nodsh && skip "remote MDS with nodsh"
23988
23989         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23990         local mdts=$(comma_list $(mdts_nodes))
23991
23992         mkdir -p $DIR/$tdir
23993         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23994         createmany -o $DIR/$tdir/$tfile. 1000
23995
23996         # statfs data is not real time, let's just calculate it
23997         old_iused=$((old_iused + 1000))
23998
23999         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24000                         osp.*OST0000*MDT0000.create_count")
24001         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24002                                 osp.*OST0000*MDT0000.max_create_count")
24003         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24004
24005         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24006         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24007         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24008
24009         unlinkmany $DIR/$tdir/$tfile. 1000
24010
24011         do_nodes $mdts "$LCTL set_param -n \
24012                         osp.*OST0000*.max_create_count=$max_count"
24013         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24014                 do_nodes $mdts "$LCTL set_param -n \
24015                                 osp.*OST0000*.create_count=$count"
24016         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24017                         grep "=0" && error "create_count is zero"
24018
24019         local new_iused
24020         for i in $(seq 120); do
24021                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24022                 # system may be too busy to destroy all objs in time, use
24023                 # a somewhat small value to not fail autotest
24024                 [ $((old_iused - new_iused)) -gt 400 ] && break
24025                 sleep 1
24026         done
24027
24028         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24029         [ $((old_iused - new_iused)) -gt 400 ] ||
24030                 error "objs not destroyed after unlink"
24031 }
24032 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24033
24034 zfs_oid_to_objid()
24035 {
24036         local ost=$1
24037         local objid=$2
24038
24039         local vdevdir=$(dirname $(facet_vdevice $ost))
24040         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24041         local zfs_zapid=$(do_facet $ost $cmd |
24042                           grep -w "/O/0/d$((objid%32))" -C 5 |
24043                           awk '/Object/{getline; print $1}')
24044         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24045                           awk "/$objid = /"'{printf $3}')
24046
24047         echo $zfs_objid
24048 }
24049
24050 zfs_object_blksz() {
24051         local ost=$1
24052         local objid=$2
24053
24054         local vdevdir=$(dirname $(facet_vdevice $ost))
24055         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24056         local blksz=$(do_facet $ost $cmd $objid |
24057                       awk '/dblk/{getline; printf $4}')
24058
24059         case "${blksz: -1}" in
24060                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24061                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24062                 *) ;;
24063         esac
24064
24065         echo $blksz
24066 }
24067
24068 test_312() { # LU-4856
24069         remote_ost_nodsh && skip "remote OST with nodsh"
24070         [ "$ost1_FSTYPE" = "zfs" ] ||
24071                 skip_env "the test only applies to zfs"
24072
24073         local max_blksz=$(do_facet ost1 \
24074                           $ZFS get -p recordsize $(facet_device ost1) |
24075                           awk '!/VALUE/{print $3}')
24076
24077         # to make life a little bit easier
24078         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24079         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24080
24081         local tf=$DIR/$tdir/$tfile
24082         touch $tf
24083         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24084
24085         # Get ZFS object id
24086         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24087         # block size change by sequential overwrite
24088         local bs
24089
24090         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24091                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24092
24093                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24094                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24095         done
24096         rm -f $tf
24097
24098         # block size change by sequential append write
24099         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24100         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24101         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24102         local count
24103
24104         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24105                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24106                         oflag=sync conv=notrunc
24107
24108                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24109                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24110                         error "blksz error, actual $blksz, " \
24111                                 "expected: 2 * $count * $PAGE_SIZE"
24112         done
24113         rm -f $tf
24114
24115         # random write
24116         touch $tf
24117         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24118         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24119
24120         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24121         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24122         [ $blksz -eq $PAGE_SIZE ] ||
24123                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24124
24125         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24126         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24127         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24128
24129         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24130         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24131         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24132 }
24133 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24134
24135 test_313() {
24136         remote_ost_nodsh && skip "remote OST with nodsh"
24137
24138         local file=$DIR/$tfile
24139
24140         rm -f $file
24141         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24142
24143         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24144         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24145         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24146                 error "write should failed"
24147         do_facet ost1 "$LCTL set_param fail_loc=0"
24148         rm -f $file
24149 }
24150 run_test 313 "io should fail after last_rcvd update fail"
24151
24152 test_314() {
24153         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24154
24155         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24156         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24157         rm -f $DIR/$tfile
24158         wait_delete_completed
24159         do_facet ost1 "$LCTL set_param fail_loc=0"
24160 }
24161 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24162
24163 test_315() { # LU-618
24164         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24165
24166         local file=$DIR/$tfile
24167         rm -f $file
24168
24169         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24170                 error "multiop file write failed"
24171         $MULTIOP $file oO_RDONLY:r4063232_c &
24172         PID=$!
24173
24174         sleep 2
24175
24176         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24177         kill -USR1 $PID
24178
24179         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24180         rm -f $file
24181 }
24182 run_test 315 "read should be accounted"
24183
24184 test_316() {
24185         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24186         large_xattr_enabled || skip "ea_inode feature disabled"
24187
24188         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24189         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24190         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24191         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24192
24193         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24194 }
24195 run_test 316 "lfs migrate of file with large_xattr enabled"
24196
24197 test_317() {
24198         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24199                 skip "Need MDS version at least 2.11.53"
24200         if [ "$ost1_FSTYPE" == "zfs" ]; then
24201                 skip "LU-10370: no implementation for ZFS"
24202         fi
24203
24204         local trunc_sz
24205         local grant_blk_size
24206
24207         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24208                         awk '/grant_block_size:/ { print $2; exit; }')
24209         #
24210         # Create File of size 5M. Truncate it to below size's and verify
24211         # blocks count.
24212         #
24213         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24214                 error "Create file $DIR/$tfile failed"
24215         stack_trap "rm -f $DIR/$tfile" EXIT
24216
24217         for trunc_sz in 2097152 4097 4000 509 0; do
24218                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24219                         error "truncate $tfile to $trunc_sz failed"
24220                 local sz=$(stat --format=%s $DIR/$tfile)
24221                 local blk=$(stat --format=%b $DIR/$tfile)
24222                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24223                                      grant_blk_size) * 8))
24224
24225                 if [[ $blk -ne $trunc_blk ]]; then
24226                         $(which stat) $DIR/$tfile
24227                         error "Expected Block $trunc_blk got $blk for $tfile"
24228                 fi
24229
24230                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24231                         error "Expected Size $trunc_sz got $sz for $tfile"
24232         done
24233
24234         #
24235         # sparse file test
24236         # Create file with a hole and write actual 65536 bytes which aligned
24237         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24238         #
24239         local bs=65536
24240         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24241                 error "Create file : $DIR/$tfile"
24242
24243         #
24244         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24245         # blocks. The block count must drop to 8.
24246         #
24247         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24248                 ((bs - grant_blk_size) + 1)))
24249         $TRUNCATE $DIR/$tfile $trunc_sz ||
24250                 error "truncate $tfile to $trunc_sz failed"
24251
24252         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24253         sz=$(stat --format=%s $DIR/$tfile)
24254         blk=$(stat --format=%b $DIR/$tfile)
24255
24256         if [[ $blk -ne $trunc_bsz ]]; then
24257                 $(which stat) $DIR/$tfile
24258                 error "Expected Block $trunc_bsz got $blk for $tfile"
24259         fi
24260
24261         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24262                 error "Expected Size $trunc_sz got $sz for $tfile"
24263 }
24264 run_test 317 "Verify blocks get correctly update after truncate"
24265
24266 test_318() {
24267         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24268         local old_max_active=$($LCTL get_param -n \
24269                             ${llite_name}.max_read_ahead_async_active \
24270                             2>/dev/null)
24271
24272         $LCTL set_param llite.*.max_read_ahead_async_active=256
24273         local max_active=$($LCTL get_param -n \
24274                            ${llite_name}.max_read_ahead_async_active \
24275                            2>/dev/null)
24276         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24277
24278         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24279                 error "set max_read_ahead_async_active should succeed"
24280
24281         $LCTL set_param llite.*.max_read_ahead_async_active=512
24282         max_active=$($LCTL get_param -n \
24283                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24284         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24285
24286         # restore @max_active
24287         [ $old_max_active -ne 0 ] && $LCTL set_param \
24288                 llite.*.max_read_ahead_async_active=$old_max_active
24289
24290         local old_threshold=$($LCTL get_param -n \
24291                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24292         local max_per_file_mb=$($LCTL get_param -n \
24293                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24294
24295         local invalid=$(($max_per_file_mb + 1))
24296         $LCTL set_param \
24297                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24298                         && error "set $invalid should fail"
24299
24300         local valid=$(($invalid - 1))
24301         $LCTL set_param \
24302                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24303                         error "set $valid should succeed"
24304         local threshold=$($LCTL get_param -n \
24305                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24306         [ $threshold -eq $valid ] || error \
24307                 "expect threshold $valid got $threshold"
24308         $LCTL set_param \
24309                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24310 }
24311 run_test 318 "Verify async readahead tunables"
24312
24313 test_319() {
24314         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24315
24316         local before=$(date +%s)
24317         local evict
24318         local mdir=$DIR/$tdir
24319         local file=$mdir/xxx
24320
24321         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24322         touch $file
24323
24324 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24325         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24326         $LFS migrate -m1 $mdir &
24327
24328         sleep 1
24329         dd if=$file of=/dev/null
24330         wait
24331         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24332           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24333
24334         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24335 }
24336 run_test 319 "lost lease lock on migrate error"
24337
24338 test_398a() { # LU-4198
24339         local ost1_imp=$(get_osc_import_name client ost1)
24340         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24341                          cut -d'.' -f2)
24342
24343         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24344         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24345
24346         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24347         # request a new lock on client
24348         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24349
24350         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24351         #local lock_count=$($LCTL get_param -n \
24352         #                  ldlm.namespaces.$imp_name.lru_size)
24353         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24354
24355         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24356
24357         # no lock cached, should use lockless DIO and not enqueue new lock
24358         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24359                 conv=notrunc ||
24360                 error "dio write failed"
24361         lock_count=$($LCTL get_param -n \
24362                      ldlm.namespaces.$imp_name.lru_size)
24363         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24364
24365         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24366
24367         # no lock cached, should use locked DIO append
24368         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24369                 conv=notrunc || error "DIO append failed"
24370         lock_count=$($LCTL get_param -n \
24371                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24372         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24373 }
24374 run_test 398a "direct IO should cancel lock otherwise lockless"
24375
24376 test_398b() { # LU-4198
24377         which fio || skip_env "no fio installed"
24378         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24379
24380         local size=48
24381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24382
24383         local njobs=4
24384         # Single page, multiple pages, stripe size, 4*stripe size
24385         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24386                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24387                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24388                         --numjobs=$njobs --fallocate=none \
24389                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24390                         --filename=$DIR/$tfile &
24391                 bg_pid=$!
24392
24393                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24394                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24395                         --numjobs=$njobs --fallocate=none \
24396                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24397                         --filename=$DIR/$tfile || true
24398                 wait $bg_pid
24399         done
24400
24401         evict=$(do_facet client $LCTL get_param \
24402                 osc.$FSNAME-OST*-osc-*/state |
24403             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24404
24405         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24406                 (do_facet client $LCTL get_param \
24407                         osc.$FSNAME-OST*-osc-*/state;
24408                     error "eviction happened: $evict before:$before")
24409
24410         rm -f $DIR/$tfile
24411 }
24412 run_test 398b "DIO and buffer IO race"
24413
24414 test_398c() { # LU-4198
24415         local ost1_imp=$(get_osc_import_name client ost1)
24416         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24417                          cut -d'.' -f2)
24418
24419         which fio || skip_env "no fio installed"
24420
24421         saved_debug=$($LCTL get_param -n debug)
24422         $LCTL set_param debug=0
24423
24424         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24425         ((size /= 1024)) # by megabytes
24426         ((size /= 2)) # write half of the OST at most
24427         [ $size -gt 40 ] && size=40 #reduce test time anyway
24428
24429         $LFS setstripe -c 1 $DIR/$tfile
24430
24431         # it seems like ldiskfs reserves more space than necessary if the
24432         # writing blocks are not mapped, so it extends the file firstly
24433         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24434         cancel_lru_locks osc
24435
24436         # clear and verify rpc_stats later
24437         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24438
24439         local njobs=4
24440         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24441         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24442                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24443                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24444                 --filename=$DIR/$tfile
24445         [ $? -eq 0 ] || error "fio write error"
24446
24447         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24448                 error "Locks were requested while doing AIO"
24449
24450         # get the percentage of 1-page I/O
24451         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24452                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24453                 awk '{print $7}')
24454         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24455
24456         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24457         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24458                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24459                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24460                 --filename=$DIR/$tfile
24461         [ $? -eq 0 ] || error "fio mixed read write error"
24462
24463         echo "AIO with large block size ${size}M"
24464         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24465                 --numjobs=1 --fallocate=none --ioengine=libaio \
24466                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24467                 --filename=$DIR/$tfile
24468         [ $? -eq 0 ] || error "fio large block size failed"
24469
24470         rm -f $DIR/$tfile
24471         $LCTL set_param debug="$saved_debug"
24472 }
24473 run_test 398c "run fio to test AIO"
24474
24475 test_398d() { #  LU-13846
24476         which aiocp || skip_env "no aiocp installed"
24477         local aio_file=$DIR/$tfile.aio
24478
24479         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24480
24481         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24482         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24483         stack_trap "rm -f $DIR/$tfile $aio_file"
24484
24485         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24486
24487         # make sure we don't crash and fail properly
24488         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24489                 error "aio not aligned with PAGE SIZE should fail"
24490
24491         rm -f $DIR/$tfile $aio_file
24492 }
24493 run_test 398d "run aiocp to verify block size > stripe size"
24494
24495 test_398e() {
24496         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24497         touch $DIR/$tfile.new
24498         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24499 }
24500 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24501
24502 test_398f() { #  LU-14687
24503         which aiocp || skip_env "no aiocp installed"
24504         local aio_file=$DIR/$tfile.aio
24505
24506         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24507
24508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24509         stack_trap "rm -f $DIR/$tfile $aio_file"
24510
24511         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24512         $LCTL set_param fail_loc=0x1418
24513         # make sure we don't crash and fail properly
24514         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24515                 error "aio with page allocation failure succeeded"
24516         $LCTL set_param fail_loc=0
24517         diff $DIR/$tfile $aio_file
24518         [[ $? != 0 ]] || error "no diff after failed aiocp"
24519 }
24520 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24521
24522 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24523 # stripe and i/o size must be > stripe size
24524 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24525 # single RPC in flight.  This test shows async DIO submission is working by
24526 # showing multiple RPCs in flight.
24527 test_398g() { #  LU-13798
24528         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24529
24530         # We need to do some i/o first to acquire enough grant to put our RPCs
24531         # in flight; otherwise a new connection may not have enough grant
24532         # available
24533         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24534                 error "parallel dio failed"
24535         stack_trap "rm -f $DIR/$tfile"
24536
24537         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24538         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24539         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24540         stack_trap "$LCTL set_param -n $pages_per_rpc"
24541
24542         # Recreate file so it's empty
24543         rm -f $DIR/$tfile
24544         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24545         #Pause rpc completion to guarantee we see multiple rpcs in flight
24546         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24547         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24548         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24549
24550         # Clear rpc stats
24551         $LCTL set_param osc.*.rpc_stats=c
24552
24553         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24554                 error "parallel dio failed"
24555         stack_trap "rm -f $DIR/$tfile"
24556
24557         $LCTL get_param osc.*-OST0000-*.rpc_stats
24558         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24559                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24560                 grep "8:" | awk '{print $8}')
24561         # We look at the "8 rpcs in flight" field, and verify A) it is present
24562         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24563         # as expected for an 8M DIO to a file with 1M stripes.
24564         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24565
24566         # Verify turning off parallel dio works as expected
24567         # Clear rpc stats
24568         $LCTL set_param osc.*.rpc_stats=c
24569         $LCTL set_param llite.*.parallel_dio=0
24570         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24571
24572         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24573                 error "dio with parallel dio disabled failed"
24574
24575         # Ideally, we would see only one RPC in flight here, but there is an
24576         # unavoidable race between i/o completion and RPC in flight counting,
24577         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24578         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24579         # So instead we just verify it's always < 8.
24580         $LCTL get_param osc.*-OST0000-*.rpc_stats
24581         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24582                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24583                 grep '^$' -B1 | grep . | awk '{print $1}')
24584         [ $ret != "8:" ] ||
24585                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24586 }
24587 run_test 398g "verify parallel dio async RPC submission"
24588
24589 test_398h() { #  LU-13798
24590         local dio_file=$DIR/$tfile.dio
24591
24592         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24593
24594         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24595         stack_trap "rm -f $DIR/$tfile $dio_file"
24596
24597         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24598                 error "parallel dio failed"
24599         diff $DIR/$tfile $dio_file
24600         [[ $? == 0 ]] || error "file diff after aiocp"
24601 }
24602 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24603
24604 test_398i() { #  LU-13798
24605         local dio_file=$DIR/$tfile.dio
24606
24607         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24608
24609         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24610         stack_trap "rm -f $DIR/$tfile $dio_file"
24611
24612         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24613         $LCTL set_param fail_loc=0x1418
24614         # make sure we don't crash and fail properly
24615         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24616                 error "parallel dio page allocation failure succeeded"
24617         diff $DIR/$tfile $dio_file
24618         [[ $? != 0 ]] || error "no diff after failed aiocp"
24619 }
24620 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24621
24622 test_398j() { #  LU-13798
24623         # Stripe size > RPC size but less than i/o size tests split across
24624         # stripes and RPCs for individual i/o op
24625         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24626
24627         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24628         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24629         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24630         stack_trap "$LCTL set_param -n $pages_per_rpc"
24631
24632         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24633                 error "parallel dio write failed"
24634         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24635
24636         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24637                 error "parallel dio read failed"
24638         diff $DIR/$tfile $DIR/$tfile.2
24639         [[ $? == 0 ]] || error "file diff after parallel dio read"
24640 }
24641 run_test 398j "test parallel dio where stripe size > rpc_size"
24642
24643 test_398k() { #  LU-13798
24644         wait_delete_completed
24645         wait_mds_ost_sync
24646
24647         # 4 stripe file; we will cause out of space on OST0
24648         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24649
24650         # Fill OST0 (if it's not too large)
24651         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24652                    head -n1)
24653         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24654                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24655         fi
24656         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24657         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24658                 error "dd should fill OST0"
24659         stack_trap "rm -f $DIR/$tfile.1"
24660
24661         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24662         err=$?
24663
24664         ls -la $DIR/$tfile
24665         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24666                 error "file is not 0 bytes in size"
24667
24668         # dd above should not succeed, but don't error until here so we can
24669         # get debug info above
24670         [[ $err != 0 ]] ||
24671                 error "parallel dio write with enospc succeeded"
24672         stack_trap "rm -f $DIR/$tfile"
24673 }
24674 run_test 398k "test enospc on first stripe"
24675
24676 test_398l() { #  LU-13798
24677         wait_delete_completed
24678         wait_mds_ost_sync
24679
24680         # 4 stripe file; we will cause out of space on OST0
24681         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24682         # happens on the second i/o chunk we issue
24683         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24684
24685         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24686         stack_trap "rm -f $DIR/$tfile"
24687
24688         # Fill OST0 (if it's not too large)
24689         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24690                    head -n1)
24691         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24692                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24693         fi
24694         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24695         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24696                 error "dd should fill OST0"
24697         stack_trap "rm -f $DIR/$tfile.1"
24698
24699         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24700         err=$?
24701         stack_trap "rm -f $DIR/$tfile.2"
24702
24703         # Check that short write completed as expected
24704         ls -la $DIR/$tfile.2
24705         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24706                 error "file is not 1M in size"
24707
24708         # dd above should not succeed, but don't error until here so we can
24709         # get debug info above
24710         [[ $err != 0 ]] ||
24711                 error "parallel dio write with enospc succeeded"
24712
24713         # Truncate source file to same length as output file and diff them
24714         $TRUNCATE $DIR/$tfile 1048576
24715         diff $DIR/$tfile $DIR/$tfile.2
24716         [[ $? == 0 ]] || error "data incorrect after short write"
24717 }
24718 run_test 398l "test enospc on intermediate stripe/RPC"
24719
24720 test_398m() { #  LU-13798
24721         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24722
24723         # Set up failure on OST0, the first stripe:
24724         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24725         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24726         # So this fail_val specifies OST0
24727         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24728         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24729
24730         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24731                 error "parallel dio write with failure on first stripe succeeded"
24732         stack_trap "rm -f $DIR/$tfile"
24733         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24734
24735         # Place data in file for read
24736         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24737                 error "parallel dio write failed"
24738
24739         # Fail read on OST0, first stripe
24740         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24741         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24742         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24743                 error "parallel dio read with error on first stripe succeeded"
24744         rm -f $DIR/$tfile.2
24745         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24746
24747         # Switch to testing on OST1, second stripe
24748         # Clear file contents, maintain striping
24749         echo > $DIR/$tfile
24750         # Set up failure on OST1, second stripe:
24751         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24752         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24753
24754         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24755                 error "parallel dio write with failure on first stripe succeeded"
24756         stack_trap "rm -f $DIR/$tfile"
24757         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24758
24759         # Place data in file for read
24760         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24761                 error "parallel dio write failed"
24762
24763         # Fail read on OST1, second stripe
24764         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24765         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24766         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24767                 error "parallel dio read with error on first stripe succeeded"
24768         rm -f $DIR/$tfile.2
24769         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24770 }
24771 run_test 398m "test RPC failures with parallel dio"
24772
24773 # Parallel submission of DIO should not cause problems for append, but it's
24774 # important to verify.
24775 test_398n() { #  LU-13798
24776         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24777
24778         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24779                 error "dd to create source file failed"
24780         stack_trap "rm -f $DIR/$tfile"
24781
24782         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24783                 error "parallel dio write with failure on second stripe succeeded"
24784         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24785         diff $DIR/$tfile $DIR/$tfile.1
24786         [[ $? == 0 ]] || error "data incorrect after append"
24787
24788 }
24789 run_test 398n "test append with parallel DIO"
24790
24791 test_fake_rw() {
24792         local read_write=$1
24793         if [ "$read_write" = "write" ]; then
24794                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24795         elif [ "$read_write" = "read" ]; then
24796                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24797         else
24798                 error "argument error"
24799         fi
24800
24801         # turn off debug for performance testing
24802         local saved_debug=$($LCTL get_param -n debug)
24803         $LCTL set_param debug=0
24804
24805         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24806
24807         # get ost1 size - $FSNAME-OST0000
24808         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24809         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24810         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24811
24812         if [ "$read_write" = "read" ]; then
24813                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24814         fi
24815
24816         local start_time=$(date +%s.%N)
24817         $dd_cmd bs=1M count=$blocks oflag=sync ||
24818                 error "real dd $read_write error"
24819         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24820
24821         if [ "$read_write" = "write" ]; then
24822                 rm -f $DIR/$tfile
24823         fi
24824
24825         # define OBD_FAIL_OST_FAKE_RW           0x238
24826         do_facet ost1 $LCTL set_param fail_loc=0x238
24827
24828         local start_time=$(date +%s.%N)
24829         $dd_cmd bs=1M count=$blocks oflag=sync ||
24830                 error "fake dd $read_write error"
24831         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24832
24833         if [ "$read_write" = "write" ]; then
24834                 # verify file size
24835                 cancel_lru_locks osc
24836                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24837                         error "$tfile size not $blocks MB"
24838         fi
24839         do_facet ost1 $LCTL set_param fail_loc=0
24840
24841         echo "fake $read_write $duration_fake vs. normal $read_write" \
24842                 "$duration in seconds"
24843         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24844                 error_not_in_vm "fake write is slower"
24845
24846         $LCTL set_param -n debug="$saved_debug"
24847         rm -f $DIR/$tfile
24848 }
24849 test_399a() { # LU-7655 for OST fake write
24850         remote_ost_nodsh && skip "remote OST with nodsh"
24851
24852         test_fake_rw write
24853 }
24854 run_test 399a "fake write should not be slower than normal write"
24855
24856 test_399b() { # LU-8726 for OST fake read
24857         remote_ost_nodsh && skip "remote OST with nodsh"
24858         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24859                 skip_env "ldiskfs only test"
24860         fi
24861
24862         test_fake_rw read
24863 }
24864 run_test 399b "fake read should not be slower than normal read"
24865
24866 test_400a() { # LU-1606, was conf-sanity test_74
24867         if ! which $CC > /dev/null 2>&1; then
24868                 skip_env "$CC is not installed"
24869         fi
24870
24871         local extra_flags=''
24872         local out=$TMP/$tfile
24873         local prefix=/usr/include/lustre
24874         local prog
24875
24876         # Oleg removes c files in his test rig so test if any c files exist
24877         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24878                 skip_env "Needed c test files are missing"
24879
24880         if ! [[ -d $prefix ]]; then
24881                 # Assume we're running in tree and fixup the include path.
24882                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24883                 extra_flags+=" -L$LUSTRE/utils/.lib"
24884         fi
24885
24886         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24887                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24888                         error "client api broken"
24889         done
24890         rm -f $out
24891 }
24892 run_test 400a "Lustre client api program can compile and link"
24893
24894 test_400b() { # LU-1606, LU-5011
24895         local header
24896         local out=$TMP/$tfile
24897         local prefix=/usr/include/linux/lustre
24898
24899         # We use a hard coded prefix so that this test will not fail
24900         # when run in tree. There are headers in lustre/include/lustre/
24901         # that are not packaged (like lustre_idl.h) and have more
24902         # complicated include dependencies (like config.h and lnet/types.h).
24903         # Since this test about correct packaging we just skip them when
24904         # they don't exist (see below) rather than try to fixup cppflags.
24905
24906         if ! which $CC > /dev/null 2>&1; then
24907                 skip_env "$CC is not installed"
24908         fi
24909
24910         for header in $prefix/*.h; do
24911                 if ! [[ -f "$header" ]]; then
24912                         continue
24913                 fi
24914
24915                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24916                         continue # lustre_ioctl.h is internal header
24917                 fi
24918
24919                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24920                         error "cannot compile '$header'"
24921         done
24922         rm -f $out
24923 }
24924 run_test 400b "packaged headers can be compiled"
24925
24926 test_401a() { #LU-7437
24927         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24928         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24929
24930         #count the number of parameters by "list_param -R"
24931         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24932         #count the number of parameters by listing proc files
24933         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24934         echo "proc_dirs='$proc_dirs'"
24935         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24936         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24937                       sort -u | wc -l)
24938
24939         [ $params -eq $procs ] ||
24940                 error "found $params parameters vs. $procs proc files"
24941
24942         # test the list_param -D option only returns directories
24943         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24944         #count the number of parameters by listing proc directories
24945         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24946                 sort -u | wc -l)
24947
24948         [ $params -eq $procs ] ||
24949                 error "found $params parameters vs. $procs proc files"
24950 }
24951 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24952
24953 test_401b() {
24954         # jobid_var may not allow arbitrary values, so use jobid_name
24955         # if available
24956         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24957                 local testname=jobid_name tmp='testing%p'
24958         else
24959                 local testname=jobid_var tmp=testing
24960         fi
24961
24962         local save=$($LCTL get_param -n $testname)
24963
24964         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24965                 error "no error returned when setting bad parameters"
24966
24967         local jobid_new=$($LCTL get_param -n foe $testname baz)
24968         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24969
24970         $LCTL set_param -n fog=bam $testname=$save bat=fog
24971         local jobid_old=$($LCTL get_param -n foe $testname bag)
24972         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24973 }
24974 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24975
24976 test_401c() {
24977         # jobid_var may not allow arbitrary values, so use jobid_name
24978         # if available
24979         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24980                 local testname=jobid_name
24981         else
24982                 local testname=jobid_var
24983         fi
24984
24985         local jobid_var_old=$($LCTL get_param -n $testname)
24986         local jobid_var_new
24987
24988         $LCTL set_param $testname= &&
24989                 error "no error returned for 'set_param a='"
24990
24991         jobid_var_new=$($LCTL get_param -n $testname)
24992         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24993                 error "$testname was changed by setting without value"
24994
24995         $LCTL set_param $testname &&
24996                 error "no error returned for 'set_param a'"
24997
24998         jobid_var_new=$($LCTL get_param -n $testname)
24999         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25000                 error "$testname was changed by setting without value"
25001 }
25002 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25003
25004 test_401d() {
25005         # jobid_var may not allow arbitrary values, so use jobid_name
25006         # if available
25007         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25008                 local testname=jobid_name new_value='foo=bar%p'
25009         else
25010                 local testname=jobid_var new_valuie=foo=bar
25011         fi
25012
25013         local jobid_var_old=$($LCTL get_param -n $testname)
25014         local jobid_var_new
25015
25016         $LCTL set_param $testname=$new_value ||
25017                 error "'set_param a=b' did not accept a value containing '='"
25018
25019         jobid_var_new=$($LCTL get_param -n $testname)
25020         [[ "$jobid_var_new" == "$new_value" ]] ||
25021                 error "'set_param a=b' failed on a value containing '='"
25022
25023         # Reset the $testname to test the other format
25024         $LCTL set_param $testname=$jobid_var_old
25025         jobid_var_new=$($LCTL get_param -n $testname)
25026         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25027                 error "failed to reset $testname"
25028
25029         $LCTL set_param $testname $new_value ||
25030                 error "'set_param a b' did not accept a value containing '='"
25031
25032         jobid_var_new=$($LCTL get_param -n $testname)
25033         [[ "$jobid_var_new" == "$new_value" ]] ||
25034                 error "'set_param a b' failed on a value containing '='"
25035
25036         $LCTL set_param $testname $jobid_var_old
25037         jobid_var_new=$($LCTL get_param -n $testname)
25038         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25039                 error "failed to reset $testname"
25040 }
25041 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25042
25043 test_401e() { # LU-14779
25044         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25045                 error "lctl list_param MGC* failed"
25046         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25047         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25048                 error "lctl get_param lru_size failed"
25049 }
25050 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25051
25052 test_402() {
25053         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25054         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25055                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25056         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25057                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25058                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25059         remote_mds_nodsh && skip "remote MDS with nodsh"
25060
25061         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25062 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25063         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25064         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25065                 echo "Touch failed - OK"
25066 }
25067 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25068
25069 test_403() {
25070         local file1=$DIR/$tfile.1
25071         local file2=$DIR/$tfile.2
25072         local tfile=$TMP/$tfile
25073
25074         rm -f $file1 $file2 $tfile
25075
25076         touch $file1
25077         ln $file1 $file2
25078
25079         # 30 sec OBD_TIMEOUT in ll_getattr()
25080         # right before populating st_nlink
25081         $LCTL set_param fail_loc=0x80001409
25082         stat -c %h $file1 > $tfile &
25083
25084         # create an alias, drop all locks and reclaim the dentry
25085         < $file2
25086         cancel_lru_locks mdc
25087         cancel_lru_locks osc
25088         sysctl -w vm.drop_caches=2
25089
25090         wait
25091
25092         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25093
25094         rm -f $tfile $file1 $file2
25095 }
25096 run_test 403 "i_nlink should not drop to zero due to aliasing"
25097
25098 test_404() { # LU-6601
25099         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25100                 skip "Need server version newer than 2.8.52"
25101         remote_mds_nodsh && skip "remote MDS with nodsh"
25102
25103         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25104                 awk '/osp .*-osc-MDT/ { print $4}')
25105
25106         local osp
25107         for osp in $mosps; do
25108                 echo "Deactivate: " $osp
25109                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25110                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25111                         awk -vp=$osp '$4 == p { print $2 }')
25112                 [ $stat = IN ] || {
25113                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25114                         error "deactivate error"
25115                 }
25116                 echo "Activate: " $osp
25117                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25118                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25119                         awk -vp=$osp '$4 == p { print $2 }')
25120                 [ $stat = UP ] || {
25121                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25122                         error "activate error"
25123                 }
25124         done
25125 }
25126 run_test 404 "validate manual {de}activated works properly for OSPs"
25127
25128 test_405() {
25129         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25130         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25131                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25132                         skip "Layout swap lock is not supported"
25133
25134         check_swap_layouts_support
25135         check_swap_layout_no_dom $DIR
25136
25137         test_mkdir $DIR/$tdir
25138         swap_lock_test -d $DIR/$tdir ||
25139                 error "One layout swap locked test failed"
25140 }
25141 run_test 405 "Various layout swap lock tests"
25142
25143 test_406() {
25144         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25145         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25146         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25148         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25149                 skip "Need MDS version at least 2.8.50"
25150
25151         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25152         local test_pool=$TESTNAME
25153
25154         pool_add $test_pool || error "pool_add failed"
25155         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25156                 error "pool_add_targets failed"
25157
25158         save_layout_restore_at_exit $MOUNT
25159
25160         # parent set default stripe count only, child will stripe from both
25161         # parent and fs default
25162         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25163                 error "setstripe $MOUNT failed"
25164         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25165         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25166         for i in $(seq 10); do
25167                 local f=$DIR/$tdir/$tfile.$i
25168                 touch $f || error "touch failed"
25169                 local count=$($LFS getstripe -c $f)
25170                 [ $count -eq $OSTCOUNT ] ||
25171                         error "$f stripe count $count != $OSTCOUNT"
25172                 local offset=$($LFS getstripe -i $f)
25173                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25174                 local size=$($LFS getstripe -S $f)
25175                 [ $size -eq $((def_stripe_size * 2)) ] ||
25176                         error "$f stripe size $size != $((def_stripe_size * 2))"
25177                 local pool=$($LFS getstripe -p $f)
25178                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25179         done
25180
25181         # change fs default striping, delete parent default striping, now child
25182         # will stripe from new fs default striping only
25183         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25184                 error "change $MOUNT default stripe failed"
25185         $LFS setstripe -c 0 $DIR/$tdir ||
25186                 error "delete $tdir default stripe failed"
25187         for i in $(seq 11 20); do
25188                 local f=$DIR/$tdir/$tfile.$i
25189                 touch $f || error "touch $f failed"
25190                 local count=$($LFS getstripe -c $f)
25191                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25192                 local offset=$($LFS getstripe -i $f)
25193                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25194                 local size=$($LFS getstripe -S $f)
25195                 [ $size -eq $def_stripe_size ] ||
25196                         error "$f stripe size $size != $def_stripe_size"
25197                 local pool=$($LFS getstripe -p $f)
25198                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25199         done
25200
25201         unlinkmany $DIR/$tdir/$tfile. 1 20
25202
25203         local f=$DIR/$tdir/$tfile
25204         pool_remove_all_targets $test_pool $f
25205         pool_remove $test_pool $f
25206 }
25207 run_test 406 "DNE support fs default striping"
25208
25209 test_407() {
25210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25211         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25212                 skip "Need MDS version at least 2.8.55"
25213         remote_mds_nodsh && skip "remote MDS with nodsh"
25214
25215         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25216                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25217         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25218                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25219         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25220
25221         #define OBD_FAIL_DT_TXN_STOP    0x2019
25222         for idx in $(seq $MDSCOUNT); do
25223                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25224         done
25225         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25226         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25227                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25228         true
25229 }
25230 run_test 407 "transaction fail should cause operation fail"
25231
25232 test_408() {
25233         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25234
25235         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25236         lctl set_param fail_loc=0x8000040a
25237         # let ll_prepare_partial_page() fail
25238         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25239
25240         rm -f $DIR/$tfile
25241
25242         # create at least 100 unused inodes so that
25243         # shrink_icache_memory(0) should not return 0
25244         touch $DIR/$tfile-{0..100}
25245         rm -f $DIR/$tfile-{0..100}
25246         sync
25247
25248         echo 2 > /proc/sys/vm/drop_caches
25249 }
25250 run_test 408 "drop_caches should not hang due to page leaks"
25251
25252 test_409()
25253 {
25254         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25255
25256         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25257         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25258         touch $DIR/$tdir/guard || error "(2) Fail to create"
25259
25260         local PREFIX=$(str_repeat 'A' 128)
25261         echo "Create 1K hard links start at $(date)"
25262         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25263                 error "(3) Fail to hard link"
25264
25265         echo "Links count should be right although linkEA overflow"
25266         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25267         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25268         [ $linkcount -eq 1001 ] ||
25269                 error "(5) Unexpected hard links count: $linkcount"
25270
25271         echo "List all links start at $(date)"
25272         ls -l $DIR/$tdir/foo > /dev/null ||
25273                 error "(6) Fail to list $DIR/$tdir/foo"
25274
25275         echo "Unlink hard links start at $(date)"
25276         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25277                 error "(7) Fail to unlink"
25278         echo "Unlink hard links finished at $(date)"
25279 }
25280 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25281
25282 test_410()
25283 {
25284         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25285                 skip "Need client version at least 2.9.59"
25286         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25287                 skip "Need MODULES build"
25288
25289         # Create a file, and stat it from the kernel
25290         local testfile=$DIR/$tfile
25291         touch $testfile
25292
25293         local run_id=$RANDOM
25294         local my_ino=$(stat --format "%i" $testfile)
25295
25296         # Try to insert the module. This will always fail as the
25297         # module is designed to not be inserted.
25298         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25299             &> /dev/null
25300
25301         # Anything but success is a test failure
25302         dmesg | grep -q \
25303             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25304             error "no inode match"
25305 }
25306 run_test 410 "Test inode number returned from kernel thread"
25307
25308 cleanup_test411_cgroup() {
25309         trap 0
25310         rmdir "$1"
25311 }
25312
25313 test_411() {
25314         local cg_basedir=/sys/fs/cgroup/memory
25315         # LU-9966
25316         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25317                 skip "no setup for cgroup"
25318
25319         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25320                 error "test file creation failed"
25321         cancel_lru_locks osc
25322
25323         # Create a very small memory cgroup to force a slab allocation error
25324         local cgdir=$cg_basedir/osc_slab_alloc
25325         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25326         trap "cleanup_test411_cgroup $cgdir" EXIT
25327         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25328         echo 1M > $cgdir/memory.limit_in_bytes
25329
25330         # Should not LBUG, just be killed by oom-killer
25331         # dd will return 0 even allocation failure in some environment.
25332         # So don't check return value
25333         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25334         cleanup_test411_cgroup $cgdir
25335
25336         return 0
25337 }
25338 run_test 411 "Slab allocation error with cgroup does not LBUG"
25339
25340 test_412() {
25341         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25342         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25343                 skip "Need server version at least 2.10.55"
25344
25345         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25346                 error "mkdir failed"
25347         $LFS getdirstripe $DIR/$tdir
25348         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25349         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25350                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25351         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25352         [ $stripe_count -eq 2 ] ||
25353                 error "expect 2 get $stripe_count"
25354
25355         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25356
25357         local index
25358         local index2
25359
25360         # subdirs should be on the same MDT as parent
25361         for i in $(seq 0 $((MDSCOUNT - 1))); do
25362                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25363                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25364                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25365                 (( index == i )) || error "mdt$i/sub on MDT$index"
25366         done
25367
25368         # stripe offset -1, ditto
25369         for i in {1..10}; do
25370                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25371                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25372                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25373                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25374                 (( index == index2 )) ||
25375                         error "qos$i on MDT$index, sub on MDT$index2"
25376         done
25377
25378         local testdir=$DIR/$tdir/inherit
25379
25380         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25381         # inherit 2 levels
25382         for i in 1 2; do
25383                 testdir=$testdir/s$i
25384                 mkdir $testdir || error "mkdir $testdir failed"
25385                 index=$($LFS getstripe -m $testdir)
25386                 (( index == 1 )) ||
25387                         error "$testdir on MDT$index"
25388         done
25389
25390         # not inherit any more
25391         testdir=$testdir/s3
25392         mkdir $testdir || error "mkdir $testdir failed"
25393         getfattr -d -m dmv $testdir | grep dmv &&
25394                 error "default LMV set on $testdir" || true
25395 }
25396 run_test 412 "mkdir on specific MDTs"
25397
25398 generate_uneven_mdts() {
25399         local threshold=$1
25400         local lmv_qos_maxage
25401         local lod_qos_maxage
25402         local ffree
25403         local bavail
25404         local max
25405         local min
25406         local max_index
25407         local min_index
25408         local tmp
25409         local i
25410
25411         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25412         $LCTL set_param lmv.*.qos_maxage=1
25413         stack_trap "$LCTL set_param \
25414                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25415         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25416                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25417         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25418                 lod.*.mdt_qos_maxage=1
25419         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25420                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25421
25422         echo
25423         echo "Check for uneven MDTs: "
25424
25425         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25426         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25427         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25428
25429         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25430         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25431         max_index=0
25432         min_index=0
25433         for ((i = 1; i < ${#ffree[@]}; i++)); do
25434                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25435                 if [ $tmp -gt $max ]; then
25436                         max=$tmp
25437                         max_index=$i
25438                 fi
25439                 if [ $tmp -lt $min ]; then
25440                         min=$tmp
25441                         min_index=$i
25442                 fi
25443         done
25444
25445         (( ${ffree[min_index]} > 0 )) ||
25446                 skip "no free files in MDT$min_index"
25447         (( ${ffree[min_index]} < 10000000 )) ||
25448                 skip "too many free files in MDT$min_index"
25449
25450         # Check if we need to generate uneven MDTs
25451         local diff=$(((max - min) * 100 / min))
25452         local testdir=$DIR/$tdir-fillmdt
25453         local start
25454
25455         mkdir -p $testdir
25456
25457         i=0
25458         while (( diff < threshold )); do
25459                 # generate uneven MDTs, create till $threshold% diff
25460                 echo -n "weight diff=$diff% must be > $threshold% ..."
25461                 echo "Fill MDT$min_index with 1000 files: loop $i"
25462                 testdir=$DIR/$tdir-fillmdt/$i
25463                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25464                         error "mkdir $testdir failed"
25465                 $LFS setstripe -E 1M -L mdt $testdir ||
25466                         error "setstripe $testdir failed"
25467                 start=$SECONDS
25468                 for F in f.{0..999}; do
25469                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25470                                 /dev/null 2>&1 || error "dd $F failed"
25471                 done
25472
25473                 # wait for QOS to update
25474                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25475
25476                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25477                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25478                 max=$(((${ffree[max_index]} >> 8) *
25479                         (${bavail[max_index]} * bsize >> 16)))
25480                 min=$(((${ffree[min_index]} >> 8) *
25481                         (${bavail[min_index]} * bsize >> 16)))
25482                 diff=$(((max - min) * 100 / min))
25483                 i=$((i + 1))
25484         done
25485
25486         echo "MDT filesfree available: ${ffree[*]}"
25487         echo "MDT blocks available: ${bavail[*]}"
25488         echo "weight diff=$diff%"
25489 }
25490
25491 test_qos_mkdir() {
25492         local mkdir_cmd=$1
25493         local stripe_count=$2
25494         local mdts=$(comma_list $(mdts_nodes))
25495
25496         local testdir
25497         local lmv_qos_prio_free
25498         local lmv_qos_threshold_rr
25499         local lmv_qos_maxage
25500         local lod_qos_prio_free
25501         local lod_qos_threshold_rr
25502         local lod_qos_maxage
25503         local count
25504         local i
25505
25506         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25507         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25508         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25509                 head -n1)
25510         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25511         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25512         stack_trap "$LCTL set_param \
25513                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25514         stack_trap "$LCTL set_param \
25515                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25516         stack_trap "$LCTL set_param \
25517                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25518
25519         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25520                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25521         lod_qos_prio_free=${lod_qos_prio_free%%%}
25522         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25523                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25524         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25525         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25526                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25527         stack_trap "do_nodes $mdts $LCTL set_param \
25528                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25529         stack_trap "do_nodes $mdts $LCTL set_param \
25530                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25531         stack_trap "do_nodes $mdts $LCTL set_param \
25532                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25533
25534         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25535         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25536
25537         testdir=$DIR/$tdir-s$stripe_count/rr
25538
25539         local stripe_index=$($LFS getstripe -m $testdir)
25540         local test_mkdir_rr=true
25541
25542         getfattr -d -m dmv -e hex $testdir | grep dmv
25543         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25544                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25545                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25546                         test_mkdir_rr=false
25547         fi
25548
25549         echo
25550         $test_mkdir_rr &&
25551                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25552                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25553
25554         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25555         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25556                 eval $mkdir_cmd $testdir/subdir$i ||
25557                         error "$mkdir_cmd subdir$i failed"
25558         done
25559
25560         for (( i = 0; i < $MDSCOUNT; i++ )); do
25561                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25562                 echo "$count directories created on MDT$i"
25563                 if $test_mkdir_rr; then
25564                         (( $count == 100 )) ||
25565                                 error "subdirs are not evenly distributed"
25566                 elif (( $i == $stripe_index )); then
25567                         (( $count == 100 * MDSCOUNT )) ||
25568                                 error "$count subdirs created on MDT$i"
25569                 else
25570                         (( $count == 0 )) ||
25571                                 error "$count subdirs created on MDT$i"
25572                 fi
25573
25574                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25575                         count=$($LFS getdirstripe $testdir/* |
25576                                 grep -c -P "^\s+$i\t")
25577                         echo "$count stripes created on MDT$i"
25578                         # deviation should < 5% of average
25579                         (( $count >= 95 * stripe_count &&
25580                            $count <= 105 * stripe_count)) ||
25581                                 error "stripes are not evenly distributed"
25582                 fi
25583         done
25584
25585         echo
25586         echo "Check for uneven MDTs: "
25587
25588         local ffree
25589         local bavail
25590         local max
25591         local min
25592         local max_index
25593         local min_index
25594         local tmp
25595
25596         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25597         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25598         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25599
25600         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25601         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25602         max_index=0
25603         min_index=0
25604         for ((i = 1; i < ${#ffree[@]}; i++)); do
25605                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25606                 if [ $tmp -gt $max ]; then
25607                         max=$tmp
25608                         max_index=$i
25609                 fi
25610                 if [ $tmp -lt $min ]; then
25611                         min=$tmp
25612                         min_index=$i
25613                 fi
25614         done
25615
25616         (( ${ffree[min_index]} > 0 )) ||
25617                 skip "no free files in MDT$min_index"
25618         (( ${ffree[min_index]} < 10000000 )) ||
25619                 skip "too many free files in MDT$min_index"
25620
25621         echo "MDT filesfree available: ${ffree[*]}"
25622         echo "MDT blocks available: ${bavail[*]}"
25623         echo "weight diff=$(((max - min) * 100 / min))%"
25624         echo
25625         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25626
25627         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25628         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25629         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25630         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25631         # decrease statfs age, so that it can be updated in time
25632         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25633         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25634
25635         sleep 1
25636
25637         testdir=$DIR/$tdir-s$stripe_count/qos
25638         local num=200
25639
25640         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25641         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25642                 eval $mkdir_cmd $testdir/subdir$i ||
25643                         error "$mkdir_cmd subdir$i failed"
25644         done
25645
25646         max=0
25647         for (( i = 0; i < $MDSCOUNT; i++ )); do
25648                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25649                 (( count > max )) && max=$count
25650                 echo "$count directories created on MDT$i"
25651         done
25652
25653         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25654
25655         # D-value should > 10% of averge
25656         (( max - min > num / 10 )) ||
25657                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25658
25659         # ditto for stripes
25660         if (( stripe_count > 1 )); then
25661                 max=0
25662                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25663                         count=$($LFS getdirstripe $testdir/* |
25664                                 grep -c -P "^\s+$i\t")
25665                         (( count > max )) && max=$count
25666                         echo "$count stripes created on MDT$i"
25667                 done
25668
25669                 min=$($LFS getdirstripe $testdir/* |
25670                         grep -c -P "^\s+$min_index\t")
25671                 (( max - min > num * stripe_count / 10 )) ||
25672                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25673         fi
25674 }
25675
25676 most_full_mdt() {
25677         local ffree
25678         local bavail
25679         local bsize
25680         local min
25681         local min_index
25682         local tmp
25683
25684         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25685         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25686         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25687
25688         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25689         min_index=0
25690         for ((i = 1; i < ${#ffree[@]}; i++)); do
25691                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25692                 (( tmp < min )) && min=$tmp && min_index=$i
25693         done
25694
25695         echo -n $min_index
25696 }
25697
25698 test_413a() {
25699         [ $MDSCOUNT -lt 2 ] &&
25700                 skip "We need at least 2 MDTs for this test"
25701
25702         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25703                 skip "Need server version at least 2.12.52"
25704
25705         local stripe_count
25706
25707         generate_uneven_mdts 100
25708         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25709                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25710                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25711                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25712                         error "mkdir failed"
25713                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25714         done
25715 }
25716 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25717
25718 test_413b() {
25719         [ $MDSCOUNT -lt 2 ] &&
25720                 skip "We need at least 2 MDTs for this test"
25721
25722         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25723                 skip "Need server version at least 2.12.52"
25724
25725         local testdir
25726         local stripe_count
25727
25728         generate_uneven_mdts 100
25729         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25730                 testdir=$DIR/$tdir-s$stripe_count
25731                 mkdir $testdir || error "mkdir $testdir failed"
25732                 mkdir $testdir/rr || error "mkdir rr failed"
25733                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25734                         error "mkdir qos failed"
25735                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25736                         $testdir/rr || error "setdirstripe rr failed"
25737                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25738                         error "setdirstripe failed"
25739                 test_qos_mkdir "mkdir" $stripe_count
25740         done
25741 }
25742 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25743
25744 test_413c() {
25745         (( $MDSCOUNT >= 2 )) ||
25746                 skip "We need at least 2 MDTs for this test"
25747
25748         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25749                 skip "Need server version at least 2.14.51"
25750
25751         local testdir
25752         local inherit
25753         local inherit_rr
25754
25755         testdir=$DIR/${tdir}-s1
25756         mkdir $testdir || error "mkdir $testdir failed"
25757         mkdir $testdir/rr || error "mkdir rr failed"
25758         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25759         # default max_inherit is -1, default max_inherit_rr is 0
25760         $LFS setdirstripe -D -c 1 $testdir/rr ||
25761                 error "setdirstripe rr failed"
25762         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25763                 error "setdirstripe qos failed"
25764         test_qos_mkdir "mkdir" 1
25765
25766         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25767         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25768         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25769         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25770         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25771
25772         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25773         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25774         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25775         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25776         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25777         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25778         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25779                 error "level2 shouldn't have default LMV" || true
25780 }
25781 run_test 413c "mkdir with default LMV max inherit rr"
25782
25783 test_413d() {
25784         (( MDSCOUNT >= 2 )) ||
25785                 skip "We need at least 2 MDTs for this test"
25786
25787         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25788                 skip "Need server version at least 2.14.51"
25789
25790         local lmv_qos_threshold_rr
25791
25792         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25793                 head -n1)
25794         stack_trap "$LCTL set_param \
25795                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25796
25797         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25798         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25799         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25800                 error "$tdir shouldn't have default LMV"
25801         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25802                 error "mkdir sub failed"
25803
25804         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25805
25806         (( count == 100 )) || error "$count subdirs on MDT0"
25807 }
25808 run_test 413d "inherit ROOT default LMV"
25809
25810 test_413e() {
25811         (( MDSCOUNT >= 2 )) ||
25812                 skip "We need at least 2 MDTs for this test"
25813         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25814                 skip "Need server version at least 2.14.55"
25815
25816         local testdir=$DIR/$tdir
25817         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25818         local max_inherit
25819         local sub_max_inherit
25820
25821         mkdir -p $testdir || error "failed to create $testdir"
25822
25823         # set default max-inherit to -1 if stripe count is 0 or 1
25824         $LFS setdirstripe -D -c 1 $testdir ||
25825                 error "failed to set default LMV"
25826         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25827         (( max_inherit == -1 )) ||
25828                 error "wrong max_inherit value $max_inherit"
25829
25830         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25831         $LFS setdirstripe -D -c -1 $testdir ||
25832                 error "failed to set default LMV"
25833         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25834         (( max_inherit > 0 )) ||
25835                 error "wrong max_inherit value $max_inherit"
25836
25837         # and the subdir will decrease the max_inherit by 1
25838         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25839         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25840         (( sub_max_inherit == max_inherit - 1)) ||
25841                 error "wrong max-inherit of subdir $sub_max_inherit"
25842
25843         # check specified --max-inherit and warning message
25844         stack_trap "rm -f $tmpfile"
25845         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25846                 error "failed to set default LMV"
25847         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25848         (( max_inherit == -1 )) ||
25849                 error "wrong max_inherit value $max_inherit"
25850
25851         # check the warning messages
25852         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25853                 error "failed to detect warning string"
25854         fi
25855 }
25856 run_test 413e "check default max-inherit value"
25857
25858 test_413f() {
25859         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25860
25861         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25862                 skip "Need server version at least 2.14.55"
25863
25864         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25865                 error "dump $DIR default LMV failed"
25866         stack_trap "setfattr --restore=$TMP/dmv.ea"
25867
25868         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25869                 error "set $DIR default LMV failed"
25870
25871         local testdir=$DIR/$tdir
25872
25873         local count
25874         local inherit
25875         local inherit_rr
25876
25877         for i in $(seq 3); do
25878                 mkdir $testdir || error "mkdir $testdir failed"
25879                 count=$($LFS getdirstripe -D -c $testdir)
25880                 (( count == 1 )) ||
25881                         error "$testdir default LMV count mismatch $count != 1"
25882                 inherit=$($LFS getdirstripe -D -X $testdir)
25883                 (( inherit == 3 - i )) ||
25884                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25885                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25886                 (( inherit_rr == 3 - i )) ||
25887                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25888                 testdir=$testdir/sub
25889         done
25890
25891         mkdir $testdir || error "mkdir $testdir failed"
25892         count=$($LFS getdirstripe -D -c $testdir)
25893         (( count == 0 )) ||
25894                 error "$testdir default LMV count not zero: $count"
25895 }
25896 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25897
25898 test_413z() {
25899         local pids=""
25900         local subdir
25901         local pid
25902
25903         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25904                 unlinkmany $subdir/f. 1000 &
25905                 pids="$pids $!"
25906         done
25907
25908         for pid in $pids; do
25909                 wait $pid
25910         done
25911 }
25912 run_test 413z "413 test cleanup"
25913
25914 test_414() {
25915 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25916         $LCTL set_param fail_loc=0x80000521
25917         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25918         rm -f $DIR/$tfile
25919 }
25920 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25921
25922 test_415() {
25923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25924         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25925                 skip "Need server version at least 2.11.52"
25926
25927         # LU-11102
25928         local total
25929         local setattr_pid
25930         local start_time
25931         local end_time
25932         local duration
25933
25934         total=500
25935         # this test may be slow on ZFS
25936         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25937
25938         # though this test is designed for striped directory, let's test normal
25939         # directory too since lock is always saved as CoS lock.
25940         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25941         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25942
25943         (
25944                 while true; do
25945                         touch $DIR/$tdir
25946                 done
25947         ) &
25948         setattr_pid=$!
25949
25950         start_time=$(date +%s)
25951         for i in $(seq $total); do
25952                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25953                         > /dev/null
25954         done
25955         end_time=$(date +%s)
25956         duration=$((end_time - start_time))
25957
25958         kill -9 $setattr_pid
25959
25960         echo "rename $total files took $duration sec"
25961         [ $duration -lt 100 ] || error "rename took $duration sec"
25962 }
25963 run_test 415 "lock revoke is not missing"
25964
25965 test_416() {
25966         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25967                 skip "Need server version at least 2.11.55"
25968
25969         # define OBD_FAIL_OSD_TXN_START    0x19a
25970         do_facet mds1 lctl set_param fail_loc=0x19a
25971
25972         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25973
25974         true
25975 }
25976 run_test 416 "transaction start failure won't cause system hung"
25977
25978 cleanup_417() {
25979         trap 0
25980         do_nodes $(comma_list $(mdts_nodes)) \
25981                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25982         do_nodes $(comma_list $(mdts_nodes)) \
25983                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25984         do_nodes $(comma_list $(mdts_nodes)) \
25985                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25986 }
25987
25988 test_417() {
25989         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25990         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25991                 skip "Need MDS version at least 2.11.56"
25992
25993         trap cleanup_417 RETURN EXIT
25994
25995         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25996         do_nodes $(comma_list $(mdts_nodes)) \
25997                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25998         $LFS migrate -m 0 $DIR/$tdir.1 &&
25999                 error "migrate dir $tdir.1 should fail"
26000
26001         do_nodes $(comma_list $(mdts_nodes)) \
26002                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26003         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26004                 error "create remote dir $tdir.2 should fail"
26005
26006         do_nodes $(comma_list $(mdts_nodes)) \
26007                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26008         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26009                 error "create striped dir $tdir.3 should fail"
26010         true
26011 }
26012 run_test 417 "disable remote dir, striped dir and dir migration"
26013
26014 # Checks that the outputs of df [-i] and lfs df [-i] match
26015 #
26016 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26017 check_lfs_df() {
26018         local dir=$2
26019         local inodes
26020         local df_out
26021         local lfs_df_out
26022         local count
26023         local passed=false
26024
26025         # blocks or inodes
26026         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26027
26028         for count in {1..100}; do
26029                 do_nodes "$CLIENTS" \
26030                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26031                 sync; sleep 0.2
26032
26033                 # read the lines of interest
26034                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26035                         error "df $inodes $dir | tail -n +2 failed"
26036                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26037                         error "lfs df $inodes $dir | grep summary: failed"
26038
26039                 # skip first substrings of each output as they are different
26040                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26041                 # compare the two outputs
26042                 passed=true
26043                 #  skip "available" on MDT until LU-13997 is fixed.
26044                 #for i in {1..5}; do
26045                 for i in 1 2 4 5; do
26046                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26047                 done
26048                 $passed && break
26049         done
26050
26051         if ! $passed; then
26052                 df -P $inodes $dir
26053                 echo
26054                 lfs df $inodes $dir
26055                 error "df and lfs df $1 output mismatch: "      \
26056                       "df ${inodes}: ${df_out[*]}, "            \
26057                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26058         fi
26059 }
26060
26061 test_418() {
26062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26063
26064         local dir=$DIR/$tdir
26065         local numfiles=$((RANDOM % 4096 + 2))
26066         local numblocks=$((RANDOM % 256 + 1))
26067
26068         wait_delete_completed
26069         test_mkdir $dir
26070
26071         # check block output
26072         check_lfs_df blocks $dir
26073         # check inode output
26074         check_lfs_df inodes $dir
26075
26076         # create a single file and retest
26077         echo "Creating a single file and testing"
26078         createmany -o $dir/$tfile- 1 &>/dev/null ||
26079                 error "creating 1 file in $dir failed"
26080         check_lfs_df blocks $dir
26081         check_lfs_df inodes $dir
26082
26083         # create a random number of files
26084         echo "Creating $((numfiles - 1)) files and testing"
26085         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26086                 error "creating $((numfiles - 1)) files in $dir failed"
26087
26088         # write a random number of blocks to the first test file
26089         echo "Writing $numblocks 4K blocks and testing"
26090         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26091                 count=$numblocks &>/dev/null ||
26092                 error "dd to $dir/${tfile}-0 failed"
26093
26094         # retest
26095         check_lfs_df blocks $dir
26096         check_lfs_df inodes $dir
26097
26098         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26099                 error "unlinking $numfiles files in $dir failed"
26100 }
26101 run_test 418 "df and lfs df outputs match"
26102
26103 test_419()
26104 {
26105         local dir=$DIR/$tdir
26106
26107         mkdir -p $dir
26108         touch $dir/file
26109
26110         cancel_lru_locks mdc
26111
26112         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26113         $LCTL set_param fail_loc=0x1410
26114         cat $dir/file
26115         $LCTL set_param fail_loc=0
26116         rm -rf $dir
26117 }
26118 run_test 419 "Verify open file by name doesn't crash kernel"
26119
26120 test_420()
26121 {
26122         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26123                 skip "Need MDS version at least 2.12.53"
26124
26125         local SAVE_UMASK=$(umask)
26126         local dir=$DIR/$tdir
26127         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26128
26129         mkdir -p $dir
26130         umask 0000
26131         mkdir -m03777 $dir/testdir
26132         ls -dn $dir/testdir
26133         # Need to remove trailing '.' when SELinux is enabled
26134         local dirperms=$(ls -dn $dir/testdir |
26135                          awk '{ sub(/\.$/, "", $1); print $1}')
26136         [ $dirperms == "drwxrwsrwt" ] ||
26137                 error "incorrect perms on $dir/testdir"
26138
26139         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26140                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26141         ls -n $dir/testdir/testfile
26142         local fileperms=$(ls -n $dir/testdir/testfile |
26143                           awk '{ sub(/\.$/, "", $1); print $1}')
26144         [ $fileperms == "-rwxr-xr-x" ] ||
26145                 error "incorrect perms on $dir/testdir/testfile"
26146
26147         umask $SAVE_UMASK
26148 }
26149 run_test 420 "clear SGID bit on non-directories for non-members"
26150
26151 test_421a() {
26152         local cnt
26153         local fid1
26154         local fid2
26155
26156         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26157                 skip "Need MDS version at least 2.12.54"
26158
26159         test_mkdir $DIR/$tdir
26160         createmany -o $DIR/$tdir/f 3
26161         cnt=$(ls -1 $DIR/$tdir | wc -l)
26162         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26163
26164         fid1=$(lfs path2fid $DIR/$tdir/f1)
26165         fid2=$(lfs path2fid $DIR/$tdir/f2)
26166         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26167
26168         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26169         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26170
26171         cnt=$(ls -1 $DIR/$tdir | wc -l)
26172         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26173
26174         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26175         createmany -o $DIR/$tdir/f 3
26176         cnt=$(ls -1 $DIR/$tdir | wc -l)
26177         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26178
26179         fid1=$(lfs path2fid $DIR/$tdir/f1)
26180         fid2=$(lfs path2fid $DIR/$tdir/f2)
26181         echo "remove using fsname $FSNAME"
26182         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26183
26184         cnt=$(ls -1 $DIR/$tdir | wc -l)
26185         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26186 }
26187 run_test 421a "simple rm by fid"
26188
26189 test_421b() {
26190         local cnt
26191         local FID1
26192         local FID2
26193
26194         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26195                 skip "Need MDS version at least 2.12.54"
26196
26197         test_mkdir $DIR/$tdir
26198         createmany -o $DIR/$tdir/f 3
26199         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26200         MULTIPID=$!
26201
26202         FID1=$(lfs path2fid $DIR/$tdir/f1)
26203         FID2=$(lfs path2fid $DIR/$tdir/f2)
26204         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26205
26206         kill -USR1 $MULTIPID
26207         wait
26208
26209         cnt=$(ls $DIR/$tdir | wc -l)
26210         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26211 }
26212 run_test 421b "rm by fid on open file"
26213
26214 test_421c() {
26215         local cnt
26216         local FIDS
26217
26218         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26219                 skip "Need MDS version at least 2.12.54"
26220
26221         test_mkdir $DIR/$tdir
26222         createmany -o $DIR/$tdir/f 3
26223         touch $DIR/$tdir/$tfile
26224         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26225         cnt=$(ls -1 $DIR/$tdir | wc -l)
26226         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26227
26228         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26229         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26230
26231         cnt=$(ls $DIR/$tdir | wc -l)
26232         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26233 }
26234 run_test 421c "rm by fid against hardlinked files"
26235
26236 test_421d() {
26237         local cnt
26238         local FIDS
26239
26240         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26241                 skip "Need MDS version at least 2.12.54"
26242
26243         test_mkdir $DIR/$tdir
26244         createmany -o $DIR/$tdir/f 4097
26245         cnt=$(ls -1 $DIR/$tdir | wc -l)
26246         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26247
26248         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26249         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26250
26251         cnt=$(ls $DIR/$tdir | wc -l)
26252         rm -rf $DIR/$tdir
26253         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26254 }
26255 run_test 421d "rmfid en masse"
26256
26257 test_421e() {
26258         local cnt
26259         local FID
26260
26261         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26262         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26263                 skip "Need MDS version at least 2.12.54"
26264
26265         mkdir -p $DIR/$tdir
26266         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26267         createmany -o $DIR/$tdir/striped_dir/f 512
26268         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26269         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26270
26271         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26272                 sed "s/[/][^:]*://g")
26273         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26274
26275         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26276         rm -rf $DIR/$tdir
26277         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26278 }
26279 run_test 421e "rmfid in DNE"
26280
26281 test_421f() {
26282         local cnt
26283         local FID
26284
26285         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26286                 skip "Need MDS version at least 2.12.54"
26287
26288         test_mkdir $DIR/$tdir
26289         touch $DIR/$tdir/f
26290         cnt=$(ls -1 $DIR/$tdir | wc -l)
26291         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26292
26293         FID=$(lfs path2fid $DIR/$tdir/f)
26294         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26295         # rmfid should fail
26296         cnt=$(ls -1 $DIR/$tdir | wc -l)
26297         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26298
26299         chmod a+rw $DIR/$tdir
26300         ls -la $DIR/$tdir
26301         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26302         # rmfid should fail
26303         cnt=$(ls -1 $DIR/$tdir | wc -l)
26304         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26305
26306         rm -f $DIR/$tdir/f
26307         $RUNAS touch $DIR/$tdir/f
26308         FID=$(lfs path2fid $DIR/$tdir/f)
26309         echo "rmfid as root"
26310         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26311         cnt=$(ls -1 $DIR/$tdir | wc -l)
26312         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26313
26314         rm -f $DIR/$tdir/f
26315         $RUNAS touch $DIR/$tdir/f
26316         cnt=$(ls -1 $DIR/$tdir | wc -l)
26317         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26318         FID=$(lfs path2fid $DIR/$tdir/f)
26319         # rmfid w/o user_fid2path mount option should fail
26320         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26321         cnt=$(ls -1 $DIR/$tdir | wc -l)
26322         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26323
26324         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26325         stack_trap "rmdir $tmpdir"
26326         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26327                 error "failed to mount client'"
26328         stack_trap "umount_client $tmpdir"
26329
26330         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26331         # rmfid should succeed
26332         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26333         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26334
26335         # rmfid shouldn't allow to remove files due to dir's permission
26336         chmod a+rwx $tmpdir/$tdir
26337         touch $tmpdir/$tdir/f
26338         ls -la $tmpdir/$tdir
26339         FID=$(lfs path2fid $tmpdir/$tdir/f)
26340         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26341         return 0
26342 }
26343 run_test 421f "rmfid checks permissions"
26344
26345 test_421g() {
26346         local cnt
26347         local FIDS
26348
26349         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26350         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26351                 skip "Need MDS version at least 2.12.54"
26352
26353         mkdir -p $DIR/$tdir
26354         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26355         createmany -o $DIR/$tdir/striped_dir/f 512
26356         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26357         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26358
26359         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26360                 sed "s/[/][^:]*://g")
26361
26362         rm -f $DIR/$tdir/striped_dir/f1*
26363         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26364         removed=$((512 - cnt))
26365
26366         # few files have been just removed, so we expect
26367         # rmfid to fail on their fids
26368         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26369         [ $removed != $errors ] && error "$errors != $removed"
26370
26371         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26372         rm -rf $DIR/$tdir
26373         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26374 }
26375 run_test 421g "rmfid to return errors properly"
26376
26377 test_422() {
26378         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26379         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26380         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26381         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26382         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26383
26384         local amc=$(at_max_get client)
26385         local amo=$(at_max_get mds1)
26386         local timeout=`lctl get_param -n timeout`
26387
26388         at_max_set 0 client
26389         at_max_set 0 mds1
26390
26391 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26392         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26393                         fail_val=$(((2*timeout + 10)*1000))
26394         touch $DIR/$tdir/d3/file &
26395         sleep 2
26396 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26397         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26398                         fail_val=$((2*timeout + 5))
26399         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26400         local pid=$!
26401         sleep 1
26402         kill -9 $pid
26403         sleep $((2 * timeout))
26404         echo kill $pid
26405         kill -9 $pid
26406         lctl mark touch
26407         touch $DIR/$tdir/d2/file3
26408         touch $DIR/$tdir/d2/file4
26409         touch $DIR/$tdir/d2/file5
26410
26411         wait
26412         at_max_set $amc client
26413         at_max_set $amo mds1
26414
26415         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26416         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26417                 error "Watchdog is always throttled"
26418 }
26419 run_test 422 "kill a process with RPC in progress"
26420
26421 stat_test() {
26422     df -h $MOUNT &
26423     df -h $MOUNT &
26424     df -h $MOUNT &
26425     df -h $MOUNT &
26426     df -h $MOUNT &
26427     df -h $MOUNT &
26428 }
26429
26430 test_423() {
26431     local _stats
26432     # ensure statfs cache is expired
26433     sleep 2;
26434
26435     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26436     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26437
26438     return 0
26439 }
26440 run_test 423 "statfs should return a right data"
26441
26442 test_424() {
26443 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26444         $LCTL set_param fail_loc=0x80000522
26445         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26446         rm -f $DIR/$tfile
26447 }
26448 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26449
26450 test_425() {
26451         test_mkdir -c -1 $DIR/$tdir
26452         $LFS setstripe -c -1 $DIR/$tdir
26453
26454         lru_resize_disable "" 100
26455         stack_trap "lru_resize_enable" EXIT
26456
26457         sleep 5
26458
26459         for i in $(seq $((MDSCOUNT * 125))); do
26460                 local t=$DIR/$tdir/$tfile_$i
26461
26462                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26463                         error_noexit "Create file $t"
26464         done
26465         stack_trap "rm -rf $DIR/$tdir" EXIT
26466
26467         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26468                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26469                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26470
26471                 [ $lock_count -le $lru_size ] ||
26472                         error "osc lock count $lock_count > lru size $lru_size"
26473         done
26474
26475         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26476                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26477                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26478
26479                 [ $lock_count -le $lru_size ] ||
26480                         error "mdc lock count $lock_count > lru size $lru_size"
26481         done
26482 }
26483 run_test 425 "lock count should not exceed lru size"
26484
26485 test_426() {
26486         splice-test -r $DIR/$tfile
26487         splice-test -rd $DIR/$tfile
26488         splice-test $DIR/$tfile
26489         splice-test -d $DIR/$tfile
26490 }
26491 run_test 426 "splice test on Lustre"
26492
26493 test_427() {
26494         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26495         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26496                 skip "Need MDS version at least 2.12.4"
26497         local log
26498
26499         mkdir $DIR/$tdir
26500         mkdir $DIR/$tdir/1
26501         mkdir $DIR/$tdir/2
26502         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26503         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26504
26505         $LFS getdirstripe $DIR/$tdir/1/dir
26506
26507         #first setfattr for creating updatelog
26508         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26509
26510 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26511         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26512         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26513         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26514
26515         sleep 2
26516         fail mds2
26517         wait_recovery_complete mds2 $((2*TIMEOUT))
26518
26519         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26520         echo $log | grep "get update log failed" &&
26521                 error "update log corruption is detected" || true
26522 }
26523 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26524
26525 test_428() {
26526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26527         local cache_limit=$CACHE_MAX
26528
26529         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26530         $LCTL set_param -n llite.*.max_cached_mb=64
26531
26532         mkdir $DIR/$tdir
26533         $LFS setstripe -c 1 $DIR/$tdir
26534         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26535         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26536         #test write
26537         for f in $(seq 4); do
26538                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26539         done
26540         wait
26541
26542         cancel_lru_locks osc
26543         # Test read
26544         for f in $(seq 4); do
26545                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26546         done
26547         wait
26548 }
26549 run_test 428 "large block size IO should not hang"
26550
26551 test_429() { # LU-7915 / LU-10948
26552         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26553         local testfile=$DIR/$tfile
26554         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26555         local new_flag=1
26556         local first_rpc
26557         local second_rpc
26558         local third_rpc
26559
26560         $LCTL get_param $ll_opencache_threshold_count ||
26561                 skip "client does not have opencache parameter"
26562
26563         set_opencache $new_flag
26564         stack_trap "restore_opencache"
26565         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26566                 error "enable opencache failed"
26567         touch $testfile
26568         # drop MDC DLM locks
26569         cancel_lru_locks mdc
26570         # clear MDC RPC stats counters
26571         $LCTL set_param $mdc_rpcstats=clear
26572
26573         # According to the current implementation, we need to run 3 times
26574         # open & close file to verify if opencache is enabled correctly.
26575         # 1st, RPCs are sent for lookup/open and open handle is released on
26576         #      close finally.
26577         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26578         #      so open handle won't be released thereafter.
26579         # 3rd, No RPC is sent out.
26580         $MULTIOP $testfile oc || error "multiop failed"
26581         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26582         echo "1st: $first_rpc RPCs in flight"
26583
26584         $MULTIOP $testfile oc || error "multiop failed"
26585         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26586         echo "2nd: $second_rpc RPCs in flight"
26587
26588         $MULTIOP $testfile oc || error "multiop failed"
26589         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26590         echo "3rd: $third_rpc RPCs in flight"
26591
26592         #verify no MDC RPC is sent
26593         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26594 }
26595 run_test 429 "verify if opencache flag on client side does work"
26596
26597 lseek_test_430() {
26598         local offset
26599         local file=$1
26600
26601         # data at [200K, 400K)
26602         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26603                 error "256K->512K dd fails"
26604         # data at [2M, 3M)
26605         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26606                 error "2M->3M dd fails"
26607         # data at [4M, 5M)
26608         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26609                 error "4M->5M dd fails"
26610         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26611         # start at first component hole #1
26612         printf "Seeking hole from 1000 ... "
26613         offset=$(lseek_test -l 1000 $file)
26614         echo $offset
26615         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26616         printf "Seeking data from 1000 ... "
26617         offset=$(lseek_test -d 1000 $file)
26618         echo $offset
26619         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26620
26621         # start at first component data block
26622         printf "Seeking hole from 300000 ... "
26623         offset=$(lseek_test -l 300000 $file)
26624         echo $offset
26625         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26626         printf "Seeking data from 300000 ... "
26627         offset=$(lseek_test -d 300000 $file)
26628         echo $offset
26629         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26630
26631         # start at the first component but beyond end of object size
26632         printf "Seeking hole from 1000000 ... "
26633         offset=$(lseek_test -l 1000000 $file)
26634         echo $offset
26635         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26636         printf "Seeking data from 1000000 ... "
26637         offset=$(lseek_test -d 1000000 $file)
26638         echo $offset
26639         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26640
26641         # start at second component stripe 2 (empty file)
26642         printf "Seeking hole from 1500000 ... "
26643         offset=$(lseek_test -l 1500000 $file)
26644         echo $offset
26645         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26646         printf "Seeking data from 1500000 ... "
26647         offset=$(lseek_test -d 1500000 $file)
26648         echo $offset
26649         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26650
26651         # start at second component stripe 1 (all data)
26652         printf "Seeking hole from 3000000 ... "
26653         offset=$(lseek_test -l 3000000 $file)
26654         echo $offset
26655         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26656         printf "Seeking data from 3000000 ... "
26657         offset=$(lseek_test -d 3000000 $file)
26658         echo $offset
26659         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26660
26661         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26662                 error "2nd dd fails"
26663         echo "Add data block at 640K...1280K"
26664
26665         # start at before new data block, in hole
26666         printf "Seeking hole from 600000 ... "
26667         offset=$(lseek_test -l 600000 $file)
26668         echo $offset
26669         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26670         printf "Seeking data from 600000 ... "
26671         offset=$(lseek_test -d 600000 $file)
26672         echo $offset
26673         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26674
26675         # start at the first component new data block
26676         printf "Seeking hole from 1000000 ... "
26677         offset=$(lseek_test -l 1000000 $file)
26678         echo $offset
26679         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26680         printf "Seeking data from 1000000 ... "
26681         offset=$(lseek_test -d 1000000 $file)
26682         echo $offset
26683         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26684
26685         # start at second component stripe 2, new data
26686         printf "Seeking hole from 1200000 ... "
26687         offset=$(lseek_test -l 1200000 $file)
26688         echo $offset
26689         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26690         printf "Seeking data from 1200000 ... "
26691         offset=$(lseek_test -d 1200000 $file)
26692         echo $offset
26693         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26694
26695         # start beyond file end
26696         printf "Using offset > filesize ... "
26697         lseek_test -l 4000000 $file && error "lseek should fail"
26698         printf "Using offset > filesize ... "
26699         lseek_test -d 4000000 $file && error "lseek should fail"
26700
26701         printf "Done\n\n"
26702 }
26703
26704 test_430a() {
26705         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26706                 skip "MDT does not support SEEK_HOLE"
26707
26708         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26709                 skip "OST does not support SEEK_HOLE"
26710
26711         local file=$DIR/$tdir/$tfile
26712
26713         mkdir -p $DIR/$tdir
26714
26715         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26716         # OST stripe #1 will have continuous data at [1M, 3M)
26717         # OST stripe #2 is empty
26718         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26719         lseek_test_430 $file
26720         rm $file
26721         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26722         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26723         lseek_test_430 $file
26724         rm $file
26725         $LFS setstripe -c2 -S 512K $file
26726         echo "Two stripes, stripe size 512K"
26727         lseek_test_430 $file
26728         rm $file
26729         # FLR with stale mirror
26730         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26731                        -N -c2 -S 1M $file
26732         echo "Mirrored file:"
26733         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26734         echo "Plain 2 stripes 1M"
26735         lseek_test_430 $file
26736         rm $file
26737 }
26738 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26739
26740 test_430b() {
26741         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26742                 skip "OST does not support SEEK_HOLE"
26743
26744         local offset
26745         local file=$DIR/$tdir/$tfile
26746
26747         mkdir -p $DIR/$tdir
26748         # Empty layout lseek should fail
26749         $MCREATE $file
26750         # seek from 0
26751         printf "Seeking hole from 0 ... "
26752         lseek_test -l 0 $file && error "lseek should fail"
26753         printf "Seeking data from 0 ... "
26754         lseek_test -d 0 $file && error "lseek should fail"
26755         rm $file
26756
26757         # 1M-hole file
26758         $LFS setstripe -E 1M -c2 -E eof $file
26759         $TRUNCATE $file 1048576
26760         printf "Seeking hole from 1000000 ... "
26761         offset=$(lseek_test -l 1000000 $file)
26762         echo $offset
26763         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26764         printf "Seeking data from 1000000 ... "
26765         lseek_test -d 1000000 $file && error "lseek should fail"
26766         rm $file
26767
26768         # full component followed by non-inited one
26769         $LFS setstripe -E 1M -c2 -E eof $file
26770         dd if=/dev/urandom of=$file bs=1M count=1
26771         printf "Seeking hole from 1000000 ... "
26772         offset=$(lseek_test -l 1000000 $file)
26773         echo $offset
26774         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26775         printf "Seeking hole from 1048576 ... "
26776         lseek_test -l 1048576 $file && error "lseek should fail"
26777         # init second component and truncate back
26778         echo "123" >> $file
26779         $TRUNCATE $file 1048576
26780         printf "Seeking hole from 1000000 ... "
26781         offset=$(lseek_test -l 1000000 $file)
26782         echo $offset
26783         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26784         printf "Seeking hole from 1048576 ... "
26785         lseek_test -l 1048576 $file && error "lseek should fail"
26786         # boundary checks for big values
26787         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26788         offset=$(lseek_test -d 0 $file.10g)
26789         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26790         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26791         offset=$(lseek_test -d 0 $file.100g)
26792         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26793         return 0
26794 }
26795 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26796
26797 test_430c() {
26798         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26799                 skip "OST does not support SEEK_HOLE"
26800
26801         local file=$DIR/$tdir/$tfile
26802         local start
26803
26804         mkdir -p $DIR/$tdir
26805         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26806
26807         # cp version 8.33+ prefers lseek over fiemap
26808         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26809                 start=$SECONDS
26810                 time cp $file /dev/null
26811                 (( SECONDS - start < 5 )) ||
26812                         error "cp: too long runtime $((SECONDS - start))"
26813
26814         fi
26815         # tar version 1.29+ supports SEEK_HOLE/DATA
26816         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26817                 start=$SECONDS
26818                 time tar cS $file - | cat > /dev/null
26819                 (( SECONDS - start < 5 )) ||
26820                         error "tar: too long runtime $((SECONDS - start))"
26821         fi
26822 }
26823 run_test 430c "lseek: external tools check"
26824
26825 test_431() { # LU-14187
26826         local file=$DIR/$tdir/$tfile
26827
26828         mkdir -p $DIR/$tdir
26829         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26830         dd if=/dev/urandom of=$file bs=4k count=1
26831         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26832         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26833         #define OBD_FAIL_OST_RESTART_IO 0x251
26834         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26835         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26836         cp $file $file.0
26837         cancel_lru_locks
26838         sync_all_data
26839         echo 3 > /proc/sys/vm/drop_caches
26840         diff  $file $file.0 || error "data diff"
26841 }
26842 run_test 431 "Restart transaction for IO"
26843
26844 cleanup_test_432() {
26845         do_facet mgs $LCTL nodemap_activate 0
26846         wait_nm_sync active
26847 }
26848
26849 test_432() {
26850         local tmpdir=$TMP/dir432
26851
26852         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26853                 skip "Need MDS version at least 2.14.52"
26854
26855         stack_trap cleanup_test_432 EXIT
26856         mkdir $DIR/$tdir
26857         mkdir $tmpdir
26858
26859         do_facet mgs $LCTL nodemap_activate 1
26860         wait_nm_sync active
26861         do_facet mgs $LCTL nodemap_modify --name default \
26862                 --property admin --value 1
26863         do_facet mgs $LCTL nodemap_modify --name default \
26864                 --property trusted --value 1
26865         cancel_lru_locks mdc
26866         wait_nm_sync default admin_nodemap
26867         wait_nm_sync default trusted_nodemap
26868
26869         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26870                grep -ci "Operation not permitted") -ne 0 ]; then
26871                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26872         fi
26873 }
26874 run_test 432 "mv dir from outside Lustre"
26875
26876 test_433() {
26877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26878
26879         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
26880                 skip "inode cache not supported"
26881
26882         $LCTL set_param llite.*.inode_cache=0
26883         stack_trap "$LCTL set_param llite.*.inode_cache=1"
26884
26885         local count=256
26886         local before
26887         local after
26888
26889         cancel_lru_locks mdc
26890         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26891         createmany -m $DIR/$tdir/f $count
26892         createmany -d $DIR/$tdir/d $count
26893         ls -l $DIR/$tdir > /dev/null
26894         stack_trap "rm -rf $DIR/$tdir"
26895
26896         before=$(num_objects)
26897         cancel_lru_locks mdc
26898         after=$(num_objects)
26899
26900         # sometimes even @before is less than 2 * count
26901         while (( before - after < count )); do
26902                 sleep 1
26903                 after=$(num_objects)
26904                 wait=$((wait + 1))
26905                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
26906                 if (( wait > 60 )); then
26907                         error "inode slab grew from $before to $after"
26908                 fi
26909         done
26910
26911         echo "lustre_inode_cache $before objs before lock cancel, $after after"
26912 }
26913 run_test 433 "ldlm lock cancel releases dentries and inodes"
26914
26915 prep_801() {
26916         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26917         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26918                 skip "Need server version at least 2.9.55"
26919
26920         start_full_debug_logging
26921 }
26922
26923 post_801() {
26924         stop_full_debug_logging
26925 }
26926
26927 barrier_stat() {
26928         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26929                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26930                            awk '/The barrier for/ { print $7 }')
26931                 echo $st
26932         else
26933                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26934                 echo \'$st\'
26935         fi
26936 }
26937
26938 barrier_expired() {
26939         local expired
26940
26941         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26942                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26943                           awk '/will be expired/ { print $7 }')
26944         else
26945                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26946         fi
26947
26948         echo $expired
26949 }
26950
26951 test_801a() {
26952         prep_801
26953
26954         echo "Start barrier_freeze at: $(date)"
26955         #define OBD_FAIL_BARRIER_DELAY          0x2202
26956         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26957         # Do not reduce barrier time - See LU-11873
26958         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26959
26960         sleep 2
26961         local b_status=$(barrier_stat)
26962         echo "Got barrier status at: $(date)"
26963         [ "$b_status" = "'freezing_p1'" ] ||
26964                 error "(1) unexpected barrier status $b_status"
26965
26966         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26967         wait
26968         b_status=$(barrier_stat)
26969         [ "$b_status" = "'frozen'" ] ||
26970                 error "(2) unexpected barrier status $b_status"
26971
26972         local expired=$(barrier_expired)
26973         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26974         sleep $((expired + 3))
26975
26976         b_status=$(barrier_stat)
26977         [ "$b_status" = "'expired'" ] ||
26978                 error "(3) unexpected barrier status $b_status"
26979
26980         # Do not reduce barrier time - See LU-11873
26981         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26982                 error "(4) fail to freeze barrier"
26983
26984         b_status=$(barrier_stat)
26985         [ "$b_status" = "'frozen'" ] ||
26986                 error "(5) unexpected barrier status $b_status"
26987
26988         echo "Start barrier_thaw at: $(date)"
26989         #define OBD_FAIL_BARRIER_DELAY          0x2202
26990         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26991         do_facet mgs $LCTL barrier_thaw $FSNAME &
26992
26993         sleep 2
26994         b_status=$(barrier_stat)
26995         echo "Got barrier status at: $(date)"
26996         [ "$b_status" = "'thawing'" ] ||
26997                 error "(6) unexpected barrier status $b_status"
26998
26999         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27000         wait
27001         b_status=$(barrier_stat)
27002         [ "$b_status" = "'thawed'" ] ||
27003                 error "(7) unexpected barrier status $b_status"
27004
27005         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27006         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27007         do_facet mgs $LCTL barrier_freeze $FSNAME
27008
27009         b_status=$(barrier_stat)
27010         [ "$b_status" = "'failed'" ] ||
27011                 error "(8) unexpected barrier status $b_status"
27012
27013         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27014         do_facet mgs $LCTL barrier_thaw $FSNAME
27015
27016         post_801
27017 }
27018 run_test 801a "write barrier user interfaces and stat machine"
27019
27020 test_801b() {
27021         prep_801
27022
27023         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27024         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27025         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27026         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27027         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27028
27029         cancel_lru_locks mdc
27030
27031         # 180 seconds should be long enough
27032         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27033
27034         local b_status=$(barrier_stat)
27035         [ "$b_status" = "'frozen'" ] ||
27036                 error "(6) unexpected barrier status $b_status"
27037
27038         mkdir $DIR/$tdir/d0/d10 &
27039         mkdir_pid=$!
27040
27041         touch $DIR/$tdir/d1/f13 &
27042         touch_pid=$!
27043
27044         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27045         ln_pid=$!
27046
27047         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27048         mv_pid=$!
27049
27050         rm -f $DIR/$tdir/d4/f12 &
27051         rm_pid=$!
27052
27053         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27054
27055         # To guarantee taht the 'stat' is not blocked
27056         b_status=$(barrier_stat)
27057         [ "$b_status" = "'frozen'" ] ||
27058                 error "(8) unexpected barrier status $b_status"
27059
27060         # let above commands to run at background
27061         sleep 5
27062
27063         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27064         ps -p $touch_pid || error "(10) touch should be blocked"
27065         ps -p $ln_pid || error "(11) link should be blocked"
27066         ps -p $mv_pid || error "(12) rename should be blocked"
27067         ps -p $rm_pid || error "(13) unlink should be blocked"
27068
27069         b_status=$(barrier_stat)
27070         [ "$b_status" = "'frozen'" ] ||
27071                 error "(14) unexpected barrier status $b_status"
27072
27073         do_facet mgs $LCTL barrier_thaw $FSNAME
27074         b_status=$(barrier_stat)
27075         [ "$b_status" = "'thawed'" ] ||
27076                 error "(15) unexpected barrier status $b_status"
27077
27078         wait $mkdir_pid || error "(16) mkdir should succeed"
27079         wait $touch_pid || error "(17) touch should succeed"
27080         wait $ln_pid || error "(18) link should succeed"
27081         wait $mv_pid || error "(19) rename should succeed"
27082         wait $rm_pid || error "(20) unlink should succeed"
27083
27084         post_801
27085 }
27086 run_test 801b "modification will be blocked by write barrier"
27087
27088 test_801c() {
27089         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27090
27091         prep_801
27092
27093         stop mds2 || error "(1) Fail to stop mds2"
27094
27095         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27096
27097         local b_status=$(barrier_stat)
27098         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27099                 do_facet mgs $LCTL barrier_thaw $FSNAME
27100                 error "(2) unexpected barrier status $b_status"
27101         }
27102
27103         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27104                 error "(3) Fail to rescan barrier bitmap"
27105
27106         # Do not reduce barrier time - See LU-11873
27107         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27108
27109         b_status=$(barrier_stat)
27110         [ "$b_status" = "'frozen'" ] ||
27111                 error "(4) unexpected barrier status $b_status"
27112
27113         do_facet mgs $LCTL barrier_thaw $FSNAME
27114         b_status=$(barrier_stat)
27115         [ "$b_status" = "'thawed'" ] ||
27116                 error "(5) unexpected barrier status $b_status"
27117
27118         local devname=$(mdsdevname 2)
27119
27120         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27121
27122         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27123                 error "(7) Fail to rescan barrier bitmap"
27124
27125         post_801
27126 }
27127 run_test 801c "rescan barrier bitmap"
27128
27129 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27130 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27131 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27132 saved_MOUNT_OPTS=$MOUNT_OPTS
27133
27134 cleanup_802a() {
27135         trap 0
27136
27137         stopall
27138         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27139         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27140         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27141         MOUNT_OPTS=$saved_MOUNT_OPTS
27142         setupall
27143 }
27144
27145 test_802a() {
27146         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27147         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27148         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27149                 skip "Need server version at least 2.9.55"
27150
27151         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27152
27153         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27154
27155         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27156                 error "(2) Fail to copy"
27157
27158         trap cleanup_802a EXIT
27159
27160         # sync by force before remount as readonly
27161         sync; sync_all_data; sleep 3; sync_all_data
27162
27163         stopall
27164
27165         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27166         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27167         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27168
27169         echo "Mount the server as read only"
27170         setupall server_only || error "(3) Fail to start servers"
27171
27172         echo "Mount client without ro should fail"
27173         mount_client $MOUNT &&
27174                 error "(4) Mount client without 'ro' should fail"
27175
27176         echo "Mount client with ro should succeed"
27177         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27178         mount_client $MOUNT ||
27179                 error "(5) Mount client with 'ro' should succeed"
27180
27181         echo "Modify should be refused"
27182         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27183
27184         echo "Read should be allowed"
27185         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27186                 error "(7) Read should succeed under ro mode"
27187
27188         cleanup_802a
27189 }
27190 run_test 802a "simulate readonly device"
27191
27192 test_802b() {
27193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27194         remote_mds_nodsh && skip "remote MDS with nodsh"
27195
27196         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27197                 skip "readonly option not available"
27198
27199         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27200
27201         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27202                 error "(2) Fail to copy"
27203
27204         # write back all cached data before setting MDT to readonly
27205         cancel_lru_locks
27206         sync_all_data
27207
27208         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27209         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27210
27211         echo "Modify should be refused"
27212         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27213
27214         echo "Read should be allowed"
27215         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27216                 error "(7) Read should succeed under ro mode"
27217
27218         # disable readonly
27219         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27220 }
27221 run_test 802b "be able to set MDTs to readonly"
27222
27223 test_803a() {
27224         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27225         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27226                 skip "MDS needs to be newer than 2.10.54"
27227
27228         mkdir_on_mdt0 $DIR/$tdir
27229         # Create some objects on all MDTs to trigger related logs objects
27230         for idx in $(seq $MDSCOUNT); do
27231                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27232                         $DIR/$tdir/dir${idx} ||
27233                         error "Fail to create $DIR/$tdir/dir${idx}"
27234         done
27235
27236         sync; sleep 3
27237         wait_delete_completed # ensure old test cleanups are finished
27238         echo "before create:"
27239         $LFS df -i $MOUNT
27240         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27241
27242         for i in {1..10}; do
27243                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27244                         error "Fail to create $DIR/$tdir/foo$i"
27245         done
27246
27247         sync; sleep 3
27248         echo "after create:"
27249         $LFS df -i $MOUNT
27250         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27251
27252         # allow for an llog to be cleaned up during the test
27253         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27254                 error "before ($before_used) + 10 > after ($after_used)"
27255
27256         for i in {1..10}; do
27257                 rm -rf $DIR/$tdir/foo$i ||
27258                         error "Fail to remove $DIR/$tdir/foo$i"
27259         done
27260
27261         sleep 3 # avoid MDT return cached statfs
27262         wait_delete_completed
27263         echo "after unlink:"
27264         $LFS df -i $MOUNT
27265         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27266
27267         # allow for an llog to be created during the test
27268         [ $after_used -le $((before_used + 1)) ] ||
27269                 error "after ($after_used) > before ($before_used) + 1"
27270 }
27271 run_test 803a "verify agent object for remote object"
27272
27273 test_803b() {
27274         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27275         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27276                 skip "MDS needs to be newer than 2.13.56"
27277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27278
27279         for i in $(seq 0 $((MDSCOUNT - 1))); do
27280                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27281         done
27282
27283         local before=0
27284         local after=0
27285
27286         local tmp
27287
27288         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27289         for i in $(seq 0 $((MDSCOUNT - 1))); do
27290                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27291                         awk '/getattr/ { print $2 }')
27292                 before=$((before + tmp))
27293         done
27294         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27295         for i in $(seq 0 $((MDSCOUNT - 1))); do
27296                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27297                         awk '/getattr/ { print $2 }')
27298                 after=$((after + tmp))
27299         done
27300
27301         [ $before -eq $after ] || error "getattr count $before != $after"
27302 }
27303 run_test 803b "remote object can getattr from cache"
27304
27305 test_804() {
27306         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27307         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27308                 skip "MDS needs to be newer than 2.10.54"
27309         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27310
27311         mkdir -p $DIR/$tdir
27312         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27313                 error "Fail to create $DIR/$tdir/dir0"
27314
27315         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27316         local dev=$(mdsdevname 2)
27317
27318         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27319                 grep ${fid} || error "NOT found agent entry for dir0"
27320
27321         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27322                 error "Fail to create $DIR/$tdir/dir1"
27323
27324         touch $DIR/$tdir/dir1/foo0 ||
27325                 error "Fail to create $DIR/$tdir/dir1/foo0"
27326         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27327         local rc=0
27328
27329         for idx in $(seq $MDSCOUNT); do
27330                 dev=$(mdsdevname $idx)
27331                 do_facet mds${idx} \
27332                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27333                         grep ${fid} && rc=$idx
27334         done
27335
27336         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27337                 error "Fail to rename foo0 to foo1"
27338         if [ $rc -eq 0 ]; then
27339                 for idx in $(seq $MDSCOUNT); do
27340                         dev=$(mdsdevname $idx)
27341                         do_facet mds${idx} \
27342                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27343                         grep ${fid} && rc=$idx
27344                 done
27345         fi
27346
27347         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27348                 error "Fail to rename foo1 to foo2"
27349         if [ $rc -eq 0 ]; then
27350                 for idx in $(seq $MDSCOUNT); do
27351                         dev=$(mdsdevname $idx)
27352                         do_facet mds${idx} \
27353                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27354                         grep ${fid} && rc=$idx
27355                 done
27356         fi
27357
27358         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27359
27360         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27361                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27362         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27363                 error "Fail to rename foo2 to foo0"
27364         unlink $DIR/$tdir/dir1/foo0 ||
27365                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27366         rm -rf $DIR/$tdir/dir0 ||
27367                 error "Fail to rm $DIR/$tdir/dir0"
27368
27369         for idx in $(seq $MDSCOUNT); do
27370                 rc=0
27371
27372                 stop mds${idx}
27373                 dev=$(mdsdevname $idx)
27374                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27375                         rc=$?
27376                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27377                         error "mount mds$idx failed"
27378                 df $MOUNT > /dev/null 2>&1
27379
27380                 # e2fsck should not return error
27381                 [ $rc -eq 0 ] ||
27382                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27383         done
27384 }
27385 run_test 804 "verify agent entry for remote entry"
27386
27387 cleanup_805() {
27388         do_facet $SINGLEMDS zfs set quota=$old $fsset
27389         unlinkmany $DIR/$tdir/f- 1000000
27390         trap 0
27391 }
27392
27393 test_805() {
27394         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27395         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27396         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27397                 skip "netfree not implemented before 0.7"
27398         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27399                 skip "Need MDS version at least 2.10.57"
27400
27401         local fsset
27402         local freekb
27403         local usedkb
27404         local old
27405         local quota
27406         local pref="osd-zfs.$FSNAME-MDT0000."
27407
27408         # limit available space on MDS dataset to meet nospace issue
27409         # quickly. then ZFS 0.7.2 can use reserved space if asked
27410         # properly (using netfree flag in osd_declare_destroy()
27411         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27412         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27413                 gawk '{print $3}')
27414         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27415         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27416         let "usedkb=usedkb-freekb"
27417         let "freekb=freekb/2"
27418         if let "freekb > 5000"; then
27419                 let "freekb=5000"
27420         fi
27421         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27422         trap cleanup_805 EXIT
27423         mkdir_on_mdt0 $DIR/$tdir
27424         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27425                 error "Can't set PFL layout"
27426         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27427         rm -rf $DIR/$tdir || error "not able to remove"
27428         do_facet $SINGLEMDS zfs set quota=$old $fsset
27429         trap 0
27430 }
27431 run_test 805 "ZFS can remove from full fs"
27432
27433 # Size-on-MDS test
27434 check_lsom_data()
27435 {
27436         local file=$1
27437         local expect=$(stat -c %s $file)
27438
27439         check_lsom_size $1 $expect
27440
27441         local blocks=$($LFS getsom -b $file)
27442         expect=$(stat -c %b $file)
27443         [[ $blocks == $expect ]] ||
27444                 error "$file expected blocks: $expect, got: $blocks"
27445 }
27446
27447 check_lsom_size()
27448 {
27449         local size
27450         local expect=$2
27451
27452         cancel_lru_locks mdc
27453
27454         size=$($LFS getsom -s $1)
27455         [[ $size == $expect ]] ||
27456                 error "$file expected size: $expect, got: $size"
27457 }
27458
27459 test_806() {
27460         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27461                 skip "Need MDS version at least 2.11.52"
27462
27463         local bs=1048576
27464
27465         touch $DIR/$tfile || error "touch $tfile failed"
27466
27467         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27468         save_lustre_params client "llite.*.xattr_cache" > $save
27469         lctl set_param llite.*.xattr_cache=0
27470         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27471
27472         # single-threaded write
27473         echo "Test SOM for single-threaded write"
27474         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27475                 error "write $tfile failed"
27476         check_lsom_size $DIR/$tfile $bs
27477
27478         local num=32
27479         local size=$(($num * $bs))
27480         local offset=0
27481         local i
27482
27483         echo "Test SOM for single client multi-threaded($num) write"
27484         $TRUNCATE $DIR/$tfile 0
27485         for ((i = 0; i < $num; i++)); do
27486                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27487                 local pids[$i]=$!
27488                 offset=$((offset + $bs))
27489         done
27490         for (( i=0; i < $num; i++ )); do
27491                 wait ${pids[$i]}
27492         done
27493         check_lsom_size $DIR/$tfile $size
27494
27495         $TRUNCATE $DIR/$tfile 0
27496         for ((i = 0; i < $num; i++)); do
27497                 offset=$((offset - $bs))
27498                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27499                 local pids[$i]=$!
27500         done
27501         for (( i=0; i < $num; i++ )); do
27502                 wait ${pids[$i]}
27503         done
27504         check_lsom_size $DIR/$tfile $size
27505
27506         # multi-client writes
27507         num=$(get_node_count ${CLIENTS//,/ })
27508         size=$(($num * $bs))
27509         offset=0
27510         i=0
27511
27512         echo "Test SOM for multi-client ($num) writes"
27513         $TRUNCATE $DIR/$tfile 0
27514         for client in ${CLIENTS//,/ }; do
27515                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27516                 local pids[$i]=$!
27517                 i=$((i + 1))
27518                 offset=$((offset + $bs))
27519         done
27520         for (( i=0; i < $num; i++ )); do
27521                 wait ${pids[$i]}
27522         done
27523         check_lsom_size $DIR/$tfile $offset
27524
27525         i=0
27526         $TRUNCATE $DIR/$tfile 0
27527         for client in ${CLIENTS//,/ }; do
27528                 offset=$((offset - $bs))
27529                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27530                 local pids[$i]=$!
27531                 i=$((i + 1))
27532         done
27533         for (( i=0; i < $num; i++ )); do
27534                 wait ${pids[$i]}
27535         done
27536         check_lsom_size $DIR/$tfile $size
27537
27538         # verify truncate
27539         echo "Test SOM for truncate"
27540         $TRUNCATE $DIR/$tfile 1048576
27541         check_lsom_size $DIR/$tfile 1048576
27542         $TRUNCATE $DIR/$tfile 1234
27543         check_lsom_size $DIR/$tfile 1234
27544
27545         # verify SOM blocks count
27546         echo "Verify SOM block count"
27547         $TRUNCATE $DIR/$tfile 0
27548         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27549                 error "failed to write file $tfile"
27550         check_lsom_data $DIR/$tfile
27551 }
27552 run_test 806 "Verify Lazy Size on MDS"
27553
27554 test_807() {
27555         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27556         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27557                 skip "Need MDS version at least 2.11.52"
27558
27559         # Registration step
27560         changelog_register || error "changelog_register failed"
27561         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27562         changelog_users $SINGLEMDS | grep -q $cl_user ||
27563                 error "User $cl_user not found in changelog_users"
27564
27565         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27566         save_lustre_params client "llite.*.xattr_cache" > $save
27567         lctl set_param llite.*.xattr_cache=0
27568         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27569
27570         rm -rf $DIR/$tdir || error "rm $tdir failed"
27571         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27572         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27573         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27574         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27575                 error "truncate $tdir/trunc failed"
27576
27577         local bs=1048576
27578         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27579                 error "write $tfile failed"
27580
27581         # multi-client wirtes
27582         local num=$(get_node_count ${CLIENTS//,/ })
27583         local offset=0
27584         local i=0
27585
27586         echo "Test SOM for multi-client ($num) writes"
27587         touch $DIR/$tfile || error "touch $tfile failed"
27588         $TRUNCATE $DIR/$tfile 0
27589         for client in ${CLIENTS//,/ }; do
27590                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27591                 local pids[$i]=$!
27592                 i=$((i + 1))
27593                 offset=$((offset + $bs))
27594         done
27595         for (( i=0; i < $num; i++ )); do
27596                 wait ${pids[$i]}
27597         done
27598
27599         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27600         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27601         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27602         check_lsom_data $DIR/$tdir/trunc
27603         check_lsom_data $DIR/$tdir/single_dd
27604         check_lsom_data $DIR/$tfile
27605
27606         rm -rf $DIR/$tdir
27607         # Deregistration step
27608         changelog_deregister || error "changelog_deregister failed"
27609 }
27610 run_test 807 "verify LSOM syncing tool"
27611
27612 check_som_nologged()
27613 {
27614         local lines=$($LFS changelog $FSNAME-MDT0000 |
27615                 grep 'x=trusted.som' | wc -l)
27616         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27617 }
27618
27619 test_808() {
27620         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27621                 skip "Need MDS version at least 2.11.55"
27622
27623         # Registration step
27624         changelog_register || error "changelog_register failed"
27625
27626         touch $DIR/$tfile || error "touch $tfile failed"
27627         check_som_nologged
27628
27629         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27630                 error "write $tfile failed"
27631         check_som_nologged
27632
27633         $TRUNCATE $DIR/$tfile 1234
27634         check_som_nologged
27635
27636         $TRUNCATE $DIR/$tfile 1048576
27637         check_som_nologged
27638
27639         # Deregistration step
27640         changelog_deregister || error "changelog_deregister failed"
27641 }
27642 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27643
27644 check_som_nodata()
27645 {
27646         $LFS getsom $1
27647         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27648 }
27649
27650 test_809() {
27651         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27652                 skip "Need MDS version at least 2.11.56"
27653
27654         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27655                 error "failed to create DoM-only file $DIR/$tfile"
27656         touch $DIR/$tfile || error "touch $tfile failed"
27657         check_som_nodata $DIR/$tfile
27658
27659         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27660                 error "write $tfile failed"
27661         check_som_nodata $DIR/$tfile
27662
27663         $TRUNCATE $DIR/$tfile 1234
27664         check_som_nodata $DIR/$tfile
27665
27666         $TRUNCATE $DIR/$tfile 4097
27667         check_som_nodata $DIR/$file
27668 }
27669 run_test 809 "Verify no SOM xattr store for DoM-only files"
27670
27671 test_810() {
27672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27673         $GSS && skip_env "could not run with gss"
27674         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27675                 skip "OST < 2.12.58 doesn't align checksum"
27676
27677         set_checksums 1
27678         stack_trap "set_checksums $ORIG_CSUM" EXIT
27679         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27680
27681         local csum
27682         local before
27683         local after
27684         for csum in $CKSUM_TYPES; do
27685                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27686                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27687                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27688                         eval set -- $i
27689                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27690                         before=$(md5sum $DIR/$tfile)
27691                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27692                         after=$(md5sum $DIR/$tfile)
27693                         [ "$before" == "$after" ] ||
27694                                 error "$csum: $before != $after bs=$1 seek=$2"
27695                 done
27696         done
27697 }
27698 run_test 810 "partial page writes on ZFS (LU-11663)"
27699
27700 test_812a() {
27701         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27702                 skip "OST < 2.12.51 doesn't support this fail_loc"
27703
27704         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27705         # ensure ost1 is connected
27706         stat $DIR/$tfile >/dev/null || error "can't stat"
27707         wait_osc_import_state client ost1 FULL
27708         # no locks, no reqs to let the connection idle
27709         cancel_lru_locks osc
27710
27711         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27712 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27713         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27714         wait_osc_import_state client ost1 CONNECTING
27715         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27716
27717         stat $DIR/$tfile >/dev/null || error "can't stat file"
27718 }
27719 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27720
27721 test_812b() { # LU-12378
27722         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27723                 skip "OST < 2.12.51 doesn't support this fail_loc"
27724
27725         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27726         # ensure ost1 is connected
27727         stat $DIR/$tfile >/dev/null || error "can't stat"
27728         wait_osc_import_state client ost1 FULL
27729         # no locks, no reqs to let the connection idle
27730         cancel_lru_locks osc
27731
27732         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27733 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27734         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27735         wait_osc_import_state client ost1 CONNECTING
27736         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27737
27738         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27739         wait_osc_import_state client ost1 IDLE
27740 }
27741 run_test 812b "do not drop no resend request for idle connect"
27742
27743 test_812c() {
27744         local old
27745
27746         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27747
27748         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27749         $LFS getstripe $DIR/$tfile
27750         $LCTL set_param osc.*.idle_timeout=10
27751         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27752         # ensure ost1 is connected
27753         stat $DIR/$tfile >/dev/null || error "can't stat"
27754         wait_osc_import_state client ost1 FULL
27755         # no locks, no reqs to let the connection idle
27756         cancel_lru_locks osc
27757
27758 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27759         $LCTL set_param fail_loc=0x80000533
27760         sleep 15
27761         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27762 }
27763 run_test 812c "idle import vs lock enqueue race"
27764
27765 test_813() {
27766         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27767         [ -z "$file_heat_sav" ] && skip "no file heat support"
27768
27769         local readsample
27770         local writesample
27771         local readbyte
27772         local writebyte
27773         local readsample1
27774         local writesample1
27775         local readbyte1
27776         local writebyte1
27777
27778         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27779         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27780
27781         $LCTL set_param -n llite.*.file_heat=1
27782         echo "Turn on file heat"
27783         echo "Period second: $period_second, Decay percentage: $decay_pct"
27784
27785         echo "QQQQ" > $DIR/$tfile
27786         echo "QQQQ" > $DIR/$tfile
27787         echo "QQQQ" > $DIR/$tfile
27788         cat $DIR/$tfile > /dev/null
27789         cat $DIR/$tfile > /dev/null
27790         cat $DIR/$tfile > /dev/null
27791         cat $DIR/$tfile > /dev/null
27792
27793         local out=$($LFS heat_get $DIR/$tfile)
27794
27795         $LFS heat_get $DIR/$tfile
27796         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27797         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27798         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27799         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27800
27801         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27802         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27803         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27804         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27805
27806         sleep $((period_second + 3))
27807         echo "Sleep $((period_second + 3)) seconds..."
27808         # The recursion formula to calculate the heat of the file f is as
27809         # follow:
27810         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27811         # Where Hi is the heat value in the period between time points i*I and
27812         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27813         # to the weight of Ci.
27814         out=$($LFS heat_get $DIR/$tfile)
27815         $LFS heat_get $DIR/$tfile
27816         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27817         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27818         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27819         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27820
27821         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27822                 error "read sample ($readsample) is wrong"
27823         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27824                 error "write sample ($writesample) is wrong"
27825         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27826                 error "read bytes ($readbyte) is wrong"
27827         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27828                 error "write bytes ($writebyte) is wrong"
27829
27830         echo "QQQQ" > $DIR/$tfile
27831         echo "QQQQ" > $DIR/$tfile
27832         echo "QQQQ" > $DIR/$tfile
27833         cat $DIR/$tfile > /dev/null
27834         cat $DIR/$tfile > /dev/null
27835         cat $DIR/$tfile > /dev/null
27836         cat $DIR/$tfile > /dev/null
27837
27838         sleep $((period_second + 3))
27839         echo "Sleep $((period_second + 3)) seconds..."
27840
27841         out=$($LFS heat_get $DIR/$tfile)
27842         $LFS heat_get $DIR/$tfile
27843         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27844         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27845         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27846         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27847
27848         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27849                 4 * $decay_pct) / 100") -eq 1 ] ||
27850                 error "read sample ($readsample1) is wrong"
27851         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27852                 3 * $decay_pct) / 100") -eq 1 ] ||
27853                 error "write sample ($writesample1) is wrong"
27854         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27855                 20 * $decay_pct) / 100") -eq 1 ] ||
27856                 error "read bytes ($readbyte1) is wrong"
27857         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27858                 15 * $decay_pct) / 100") -eq 1 ] ||
27859                 error "write bytes ($writebyte1) is wrong"
27860
27861         echo "Turn off file heat for the file $DIR/$tfile"
27862         $LFS heat_set -o $DIR/$tfile
27863
27864         echo "QQQQ" > $DIR/$tfile
27865         echo "QQQQ" > $DIR/$tfile
27866         echo "QQQQ" > $DIR/$tfile
27867         cat $DIR/$tfile > /dev/null
27868         cat $DIR/$tfile > /dev/null
27869         cat $DIR/$tfile > /dev/null
27870         cat $DIR/$tfile > /dev/null
27871
27872         out=$($LFS heat_get $DIR/$tfile)
27873         $LFS heat_get $DIR/$tfile
27874         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27875         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27876         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27877         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27878
27879         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27880         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27881         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27882         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27883
27884         echo "Trun on file heat for the file $DIR/$tfile"
27885         $LFS heat_set -O $DIR/$tfile
27886
27887         echo "QQQQ" > $DIR/$tfile
27888         echo "QQQQ" > $DIR/$tfile
27889         echo "QQQQ" > $DIR/$tfile
27890         cat $DIR/$tfile > /dev/null
27891         cat $DIR/$tfile > /dev/null
27892         cat $DIR/$tfile > /dev/null
27893         cat $DIR/$tfile > /dev/null
27894
27895         out=$($LFS heat_get $DIR/$tfile)
27896         $LFS heat_get $DIR/$tfile
27897         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27898         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27899         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27900         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27901
27902         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27903         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27904         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27905         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27906
27907         $LFS heat_set -c $DIR/$tfile
27908         $LCTL set_param -n llite.*.file_heat=0
27909         echo "Turn off file heat support for the Lustre filesystem"
27910
27911         echo "QQQQ" > $DIR/$tfile
27912         echo "QQQQ" > $DIR/$tfile
27913         echo "QQQQ" > $DIR/$tfile
27914         cat $DIR/$tfile > /dev/null
27915         cat $DIR/$tfile > /dev/null
27916         cat $DIR/$tfile > /dev/null
27917         cat $DIR/$tfile > /dev/null
27918
27919         out=$($LFS heat_get $DIR/$tfile)
27920         $LFS heat_get $DIR/$tfile
27921         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27922         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27923         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27924         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27925
27926         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27927         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27928         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27929         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27930
27931         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27932         rm -f $DIR/$tfile
27933 }
27934 run_test 813 "File heat verfication"
27935
27936 test_814()
27937 {
27938         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27939         echo -n y >> $DIR/$tfile
27940         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27941         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27942 }
27943 run_test 814 "sparse cp works as expected (LU-12361)"
27944
27945 test_815()
27946 {
27947         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27948         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27949 }
27950 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27951
27952 test_816() {
27953         local ost1_imp=$(get_osc_import_name client ost1)
27954         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27955                          cut -d'.' -f2)
27956
27957         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27958         # ensure ost1 is connected
27959
27960         stat $DIR/$tfile >/dev/null || error "can't stat"
27961         wait_osc_import_state client ost1 FULL
27962         # no locks, no reqs to let the connection idle
27963         cancel_lru_locks osc
27964         lru_resize_disable osc
27965         local before
27966         local now
27967         before=$($LCTL get_param -n \
27968                  ldlm.namespaces.$imp_name.lru_size)
27969
27970         wait_osc_import_state client ost1 IDLE
27971         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27972         now=$($LCTL get_param -n \
27973               ldlm.namespaces.$imp_name.lru_size)
27974         [ $before == $now ] || error "lru_size changed $before != $now"
27975 }
27976 run_test 816 "do not reset lru_resize on idle reconnect"
27977
27978 cleanup_817() {
27979         umount $tmpdir
27980         exportfs -u localhost:$DIR/nfsexp
27981         rm -rf $DIR/nfsexp
27982 }
27983
27984 test_817() {
27985         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27986
27987         mkdir -p $DIR/nfsexp
27988         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27989                 error "failed to export nfs"
27990
27991         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27992         stack_trap cleanup_817 EXIT
27993
27994         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27995                 error "failed to mount nfs to $tmpdir"
27996
27997         cp /bin/true $tmpdir
27998         $DIR/nfsexp/true || error "failed to execute 'true' command"
27999 }
28000 run_test 817 "nfsd won't cache write lock for exec file"
28001
28002 test_818() {
28003         test_mkdir -i0 -c1 $DIR/$tdir
28004         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28005         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28006         stop $SINGLEMDS
28007
28008         # restore osp-syn threads
28009         stack_trap "fail $SINGLEMDS"
28010
28011         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28012         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28013         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28014                 error "start $SINGLEMDS failed"
28015         rm -rf $DIR/$tdir
28016
28017         local testid=$(echo $TESTNAME | tr '_' ' ')
28018
28019         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28020                 grep "run LFSCK" || error "run LFSCK is not suggested"
28021 }
28022 run_test 818 "unlink with failed llog"
28023
28024 test_819a() {
28025         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28026         cancel_lru_locks osc
28027         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28028         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28029         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28030         rm -f $TDIR/$tfile
28031 }
28032 run_test 819a "too big niobuf in read"
28033
28034 test_819b() {
28035         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28036         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28038         cancel_lru_locks osc
28039         sleep 1
28040         rm -f $TDIR/$tfile
28041 }
28042 run_test 819b "too big niobuf in write"
28043
28044
28045 function test_820_start_ost() {
28046         sleep 5
28047
28048         for num in $(seq $OSTCOUNT); do
28049                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28050         done
28051 }
28052
28053 test_820() {
28054         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28055
28056         mkdir $DIR/$tdir
28057         umount_client $MOUNT || error "umount failed"
28058         for num in $(seq $OSTCOUNT); do
28059                 stop ost$num
28060         done
28061
28062         # mount client with no active OSTs
28063         # so that the client can't initialize max LOV EA size
28064         # from OSC notifications
28065         mount_client $MOUNT || error "mount failed"
28066         # delay OST starting to keep this 0 max EA size for a while
28067         test_820_start_ost &
28068
28069         # create a directory on MDS2
28070         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28071                 error "Failed to create directory"
28072         # open intent should update default EA size
28073         # see mdc_update_max_ea_from_body()
28074         # notice this is the very first RPC to MDS2
28075         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28076         ret=$?
28077         echo $out
28078         # With SSK, this situation can lead to -EPERM being returned.
28079         # In that case, simply retry.
28080         if [ $ret -ne 0 ] && $SHARED_KEY; then
28081                 if echo "$out" | grep -q "not permitted"; then
28082                         cp /etc/services $DIR/$tdir/mds2
28083                         ret=$?
28084                 fi
28085         fi
28086         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28087 }
28088 run_test 820 "update max EA from open intent"
28089
28090 test_822() {
28091         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28092
28093         save_lustre_params mds1 \
28094                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28095         do_facet $SINGLEMDS "$LCTL set_param -n \
28096                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28097         do_facet $SINGLEMDS "$LCTL set_param -n \
28098                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28099
28100         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28101         local maxage=$(do_facet mds1 $LCTL get_param -n \
28102                        osp.$FSNAME-OST0000*MDT0000.maxage)
28103         sleep $((maxage + 1))
28104
28105         #define OBD_FAIL_NET_ERROR_RPC          0x532
28106         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28107
28108         stack_trap "restore_lustre_params < $p; rm $p"
28109
28110         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28111                       osp.$FSNAME-OST0000*MDT0000.create_count")
28112         for i in $(seq 1 $count); do
28113                 touch $DIR/$tfile.${i} || error "touch failed"
28114         done
28115 }
28116 run_test 822 "test precreate failure"
28117
28118 test_823() {
28119         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28120         local OST_MAX_PRECREATE=20000
28121
28122         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28123                 skip "Need MDS version at least 2.14.56"
28124
28125         save_lustre_params mds1 \
28126                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28127         do_facet $SINGLEMDS "$LCTL set_param -n \
28128                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28129         do_facet $SINGLEMDS "$LCTL set_param -n \
28130                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28131
28132         stack_trap "restore_lustre_params < $p; rm $p"
28133
28134         do_facet $SINGLEMDS "$LCTL set_param -n \
28135                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28136
28137         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28138                       osp.$FSNAME-OST0000*MDT0000.create_count")
28139         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28140                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28141         local expect_count=$(((($max/2)/256) * 256))
28142
28143         log "setting create_count to 100200:"
28144         log " -result- count: $count with max: $max, expecting: $expect_count"
28145
28146         [[ $count -eq expect_count ]] ||
28147                 error "Create count not set to max precreate."
28148 }
28149 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28150
28151 test_831() {
28152         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28153                 skip "Need MDS version 2.14.56"
28154
28155         local sync_changes=$(do_facet $SINGLEMDS \
28156                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28157
28158         [ "$sync_changes" -gt 100 ] &&
28159                 skip "Sync changes $sync_changes > 100 already"
28160
28161         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28162
28163         $LFS mkdir -i 0 $DIR/$tdir
28164         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28165
28166         save_lustre_params mds1 \
28167                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28168         save_lustre_params mds1 \
28169                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28170
28171         do_facet mds1 "$LCTL set_param -n \
28172                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28173                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28174         stack_trap "restore_lustre_params < $p" EXIT
28175
28176         createmany -o $DIR/$tdir/f- 1000
28177         unlinkmany $DIR/$tdir/f- 1000 &
28178         local UNLINK_PID=$!
28179
28180         while sleep 1; do
28181                 sync_changes=$(do_facet mds1 \
28182                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28183                 # the check in the code is racy, fail the test
28184                 # if the value above the limit by 10.
28185                 [ $sync_changes -gt 110 ] && {
28186                         kill -2 $UNLINK_PID
28187                         wait
28188                         error "osp changes throttling failed, $sync_changes>110"
28189                 }
28190                 kill -0 $UNLINK_PID 2> /dev/null || break
28191         done
28192         wait
28193 }
28194 run_test 831 "throttling unlink/setattr queuing on OSP"
28195
28196 #
28197 # tests that do cleanup/setup should be run at the end
28198 #
28199
28200 test_900() {
28201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28202         local ls
28203
28204         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28205         $LCTL set_param fail_loc=0x903
28206
28207         cancel_lru_locks MGC
28208
28209         FAIL_ON_ERROR=true cleanup
28210         FAIL_ON_ERROR=true setup
28211 }
28212 run_test 900 "umount should not race with any mgc requeue thread"
28213
28214 # LUS-6253/LU-11185
28215 test_901() {
28216         local old
28217         local count
28218         local oldc
28219         local newc
28220         local olds
28221         local news
28222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28223
28224         # some get_param have a bug to handle dot in param name
28225         cancel_lru_locks MGC
28226         old=$(mount -t lustre | wc -l)
28227         # 1 config+sptlrpc
28228         # 2 params
28229         # 3 nodemap
28230         # 4 IR
28231         old=$((old * 4))
28232         oldc=0
28233         count=0
28234         while [ $old -ne $oldc ]; do
28235                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28236                 sleep 1
28237                 ((count++))
28238                 if [ $count -ge $TIMEOUT ]; then
28239                         error "too large timeout"
28240                 fi
28241         done
28242         umount_client $MOUNT || error "umount failed"
28243         mount_client $MOUNT || error "mount failed"
28244         cancel_lru_locks MGC
28245         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28246
28247         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28248
28249         return 0
28250 }
28251 run_test 901 "don't leak a mgc lock on client umount"
28252
28253 # LU-13377
28254 test_902() {
28255         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28256                 skip "client does not have LU-13377 fix"
28257         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28258         $LCTL set_param fail_loc=0x1415
28259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28260         cancel_lru_locks osc
28261         rm -f $DIR/$tfile
28262 }
28263 run_test 902 "test short write doesn't hang lustre"
28264
28265 # LU-14711
28266 test_903() {
28267         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28268         echo "blah" > $DIR/${tfile}-2
28269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28270         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28271         $LCTL set_param fail_loc=0x417 fail_val=20
28272
28273         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28274         sleep 1 # To start the destroy
28275         wait_destroy_complete 150 || error "Destroy taking too long"
28276         cat $DIR/$tfile > /dev/null || error "Evicted"
28277 }
28278 run_test 903 "Test long page discard does not cause evictions"
28279
28280 test_904() {
28281         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28282         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28283                 grep -q project || skip "skip project quota not supported"
28284
28285         local testfile="$DIR/$tdir/$tfile"
28286         local xattr="trusted.projid"
28287         local projid
28288         local mdts=$(comma_list $(mdts_nodes))
28289         local saved=$(do_facet mds1 $LCTL get_param -n \
28290                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28291
28292         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28293         stack_trap "do_nodes $mdts $LCTL set_param \
28294                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28295
28296         mkdir -p $DIR/$tdir
28297         touch $testfile
28298         #hide projid xattr on server
28299         $LFS project -p 1 $testfile ||
28300                 error "set $testfile project id failed"
28301         getfattr -m - $testfile | grep $xattr &&
28302                 error "do not show trusted.projid when disabled on server"
28303         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28304         #should be hidden when projid is 0
28305         $LFS project -p 0 $testfile ||
28306                 error "set $testfile project id failed"
28307         getfattr -m - $testfile | grep $xattr &&
28308                 error "do not show trusted.projid with project ID 0"
28309
28310         #still can getxattr explicitly
28311         projid=$(getfattr -n $xattr $testfile |
28312                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28313         [ $projid == "0" ] ||
28314                 error "projid expected 0 not $projid"
28315
28316         #set the projid via setxattr
28317         setfattr -n $xattr -v "1000" $testfile ||
28318                 error "setattr failed with $?"
28319         projid=($($LFS project $testfile))
28320         [ ${projid[0]} == "1000" ] ||
28321                 error "projid expected 1000 not $projid"
28322
28323         #check the new projid via getxattr
28324         $LFS project -p 1001 $testfile ||
28325                 error "set $testfile project id failed"
28326         getfattr -m - $testfile | grep $xattr ||
28327                 error "should show trusted.projid when project ID != 0"
28328         projid=$(getfattr -n $xattr $testfile |
28329                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28330         [ $projid == "1001" ] ||
28331                 error "projid expected 1001 not $projid"
28332
28333         #try to set invalid projid
28334         setfattr -n $xattr -v "4294967295" $testfile &&
28335                 error "set invalid projid should fail"
28336
28337         #remove the xattr means setting projid to 0
28338         setfattr -x $xattr $testfile ||
28339                 error "setfattr failed with $?"
28340         projid=($($LFS project $testfile))
28341         [ ${projid[0]} == "0" ] ||
28342                 error "projid expected 0 not $projid"
28343
28344         #should be hidden when parent has inherit flag and same projid
28345         $LFS project -srp 1002 $DIR/$tdir ||
28346                 error "set $tdir project id failed"
28347         getfattr -m - $testfile | grep $xattr &&
28348                 error "do not show trusted.projid with inherit flag"
28349
28350         #still can getxattr explicitly
28351         projid=$(getfattr -n $xattr $testfile |
28352                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28353         [ $projid == "1002" ] ||
28354                 error "projid expected 1002 not $projid"
28355 }
28356 run_test 904 "virtual project ID xattr"
28357
28358 complete $SECONDS
28359 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28360 check_and_cleanup_lustre
28361 if [ "$I_MOUNTED" != "yes" ]; then
28362         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28363 fi
28364 exit_status